From b08a3835dc71b9001d1c385654f5a093bfb7cc8c Mon Sep 17 00:00:00 2001 From: Pax1601 Date: Thu, 5 Oct 2023 11:02:02 +0200 Subject: [PATCH] Some database changes, started to add threat rings --- client/plugins/databasemanager/index.js | 990 ++++++++++++++++-- client/plugins/databasemanager/src/utils.ts | 4 +- client/plugins/databasemanager/style.css | 2 +- .../databases/units/aircraftdatabase.json | 2 +- .../databases/units/groundunitdatabase.json | 70 +- client/src/constants/constants.ts | 7 +- client/src/map/map.ts | 65 +- client/src/other/utils.ts | 6 + client/src/unit/unit.ts | 32 +- scripts/python/addRanges.py | 63 ++ scripts/python/temp.py | 15 - src/core/src/groundunit.cpp | 2 + 12 files changed, 1066 insertions(+), 192 deletions(-) create mode 100644 scripts/python/addRanges.py delete mode 100644 scripts/python/temp.py diff --git a/client/plugins/databasemanager/index.js b/client/plugins/databasemanager/index.js index b780b875..859ff36d 100644 --- a/client/plugins/databasemanager/index.js +++ b/client/plugins/databasemanager/index.js @@ -1,22 +1,5 @@ (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i { + var _a; + if (this.visible) + (_a = __classPrivateFieldGet(this, _AirUnitEditor_loadoutEditor, "f")) === null || _a === void 0 ? void 0 : _a.show(); + }); + } + /** Sets a unit blueprint as the currently active one + * + * @param blueprint The blueprint to edit + */ + setBlueprint(blueprint) { + var _a, _b, _c, _d, _e, _f; + this.blueprint = blueprint; + if (this.blueprint !== null) { + this.contentDiv2.replaceChildren(); + var title = document.createElement("label"); + title.innerText = "Unit properties"; + this.contentDiv2.appendChild(title); + (0, utils_1.addStringInput)(this.contentDiv2, "Name", blueprint.name, "text", (value) => { blueprint.name = value; }, true); + (0, utils_1.addStringInput)(this.contentDiv2, "Label", blueprint.label, "text", (value) => { blueprint.label = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Short label", blueprint.shortLabel, "text", (value) => { blueprint.shortLabel = value; }); + (0, utils_1.addDropdownInput)(this.contentDiv2, "Coalition", blueprint.coalition, ["", "blue", "red"]); + (0, utils_1.addDropdownInput)(this.contentDiv2, "Era", blueprint.era, ["WW2", "Early Cold War", "Mid Cold War", "Late Cold War", "Modern"]); + (0, utils_1.addStringInput)(this.contentDiv2, "Filename", (_a = blueprint.filename) !== null && _a !== void 0 ? _a : "", "text", (value) => { blueprint.filename = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Cost", (_b = String(blueprint.cost)) !== null && _b !== void 0 ? _b : "", "number", (value) => { blueprint.cost = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Rufels from", (_c = String(blueprint.refuelsFrom)) !== null && _c !== void 0 ? _c : "", "text", (value) => { blueprint.refuelsFrom = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Refueling type", (_d = String(blueprint.refuelingType)) !== null && _d !== void 0 ? _d : "", "text", (value) => { blueprint.refuelingType = value; }); + /* Add a scrollable list of loadouts that the user can edit */ + var title = document.createElement("label"); + title.innerText = "Loadouts"; + this.contentDiv2.appendChild(title); + (0, utils_1.addLoadoutsScroll)(this.contentDiv2, (_e = blueprint.loadouts) !== null && _e !== void 0 ? _e : [], (loadout) => { + var _a, _b; + (_a = __classPrivateFieldGet(this, _AirUnitEditor_loadoutEditor, "f")) === null || _a === void 0 ? void 0 : _a.setLoadout(loadout); + (_b = __classPrivateFieldGet(this, _AirUnitEditor_loadoutEditor, "f")) === null || _b === void 0 ? void 0 : _b.show(); + }); + (0, utils_1.addNewElementInput)(this.contentDiv2, (ev, input) => { this.addLoadout(input.value); }); + (_f = __classPrivateFieldGet(this, _AirUnitEditor_loadoutEditor, "f")) === null || _f === void 0 ? void 0 : _f.hide(); + } + } + /** Add a new empty blueprint + * + * @param key Blueprint key + */ + addBlueprint(key) { + if (this.database != null) { + this.database.blueprints[key] = { + name: key, + coalition: "", + label: "", + shortLabel: "", + era: "", + loadouts: [] + }; + this.show(); + this.setBlueprint(this.database.blueprints[key]); + } + } + /** Add a new empty loadout to the currently active blueprint + * + * @param loadoutName The name of the new loadout + */ + addLoadout(loadoutName) { + var _a; + if (loadoutName && this.blueprint !== null) { + (_a = this.blueprint.loadouts) === null || _a === void 0 ? void 0 : _a.push({ + name: loadoutName, + code: "", + fuel: 1, + items: [], + roles: [] + }); + this.setBlueprint(this.blueprint); + } + } + /** Hide the editor + * + */ + hide() { + var _a; + super.hide(); + (_a = __classPrivateFieldGet(this, _AirUnitEditor_loadoutEditor, "f")) === null || _a === void 0 ? void 0 : _a.hide(); + } +} +exports.AirUnitEditor = AirUnitEditor; +_AirUnitEditor_loadoutEditor = new WeakMap(); + +},{"./loadouteditor":5,"./uniteditor":7,"./utils":8}],2:[function(require,module,exports){ +"use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _DatabaseManagerPlugin_instances, _DatabaseManagerPlugin_app, _DatabaseManagerPlugin_element, _DatabaseManagerPlugin_mainContentContainer, _DatabaseManagerPlugin_contentDiv1, _DatabaseManagerPlugin_contentDiv2, _DatabaseManagerPlugin_contentDiv3, _DatabaseManagerPlugin_button1, _DatabaseManagerPlugin_button2, _DatabaseManagerPlugin_button3, _DatabaseManagerPlugin_button4, _DatabaseManagerPlugin_button5, _DatabaseManagerPlugin_button6, _DatabaseManagerPlugin_button7, _DatabaseManagerPlugin_button8, _DatabaseManagerPlugin_button9, _DatabaseManagerPlugin_aircraftEditor, _DatabaseManagerPlugin_helicopterEditor, _DatabaseManagerPlugin_groundUnitEditor, _DatabaseManagerPlugin_navyUnitEditor, _DatabaseManagerPlugin_hideAll, _DatabaseManagerPlugin_loadDatabases, _DatabaseManagerPlugin_saveDatabases, _DatabaseManagerPlugin_resetToDefaultDatabases, _DatabaseManagerPlugin_restoreToPreviousDatabases, _DatabaseManagerPlugin_uploadDatabase, _DatabaseManagerPlugin_resetToDefaultDatabase, _DatabaseManagerPlugin_restoreToPreviousDatabase; Object.defineProperty(exports, "__esModule", { value: true }); exports.DatabaseManagerPlugin = void 0; const airuniteditor_1 = require("./airuniteditor"); +const grounduniteditor_1 = require("./grounduniteditor"); +const navyuniteditor_1 = require("./navyuniteditor"); +/** Database Manager + * + * This database provides a user interface to allow easier and convenient unit databases manipulation. It allows to edit all the fields of the units databases, save them + * on the server, and restore the defaults. + * + * TODO: + * Add ability to manage liveries + * + */ class DatabaseManagerPlugin { constructor() { + _DatabaseManagerPlugin_instances.add(this); _DatabaseManagerPlugin_app.set(this, null); _DatabaseManagerPlugin_element.set(this, void 0); - _DatabaseManagerPlugin_scrollDiv.set(this, void 0); - _DatabaseManagerPlugin_contentDiv.set(this, void 0); + _DatabaseManagerPlugin_mainContentContainer.set(this, void 0); + _DatabaseManagerPlugin_contentDiv1.set(this, void 0); + _DatabaseManagerPlugin_contentDiv2.set(this, void 0); + _DatabaseManagerPlugin_contentDiv3.set(this, void 0); + /* Upper tab buttons */ + _DatabaseManagerPlugin_button1.set(this, void 0); + _DatabaseManagerPlugin_button2.set(this, void 0); + _DatabaseManagerPlugin_button3.set(this, void 0); + _DatabaseManagerPlugin_button4.set(this, void 0); + /* Lower operation buttons */ + _DatabaseManagerPlugin_button5.set(this, void 0); + _DatabaseManagerPlugin_button6.set(this, void 0); + _DatabaseManagerPlugin_button7.set(this, void 0); + _DatabaseManagerPlugin_button8.set(this, void 0); + _DatabaseManagerPlugin_button9.set(this, void 0); + /* Database editors */ _DatabaseManagerPlugin_aircraftEditor.set(this, void 0); + _DatabaseManagerPlugin_helicopterEditor.set(this, void 0); + _DatabaseManagerPlugin_groundUnitEditor.set(this, void 0); + _DatabaseManagerPlugin_navyUnitEditor.set(this, void 0); + /* Create main HTML element */ __classPrivateFieldSet(this, _DatabaseManagerPlugin_element, document.createElement("div"), "f"); __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").id = "database-manager-panel"; __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").oncontextmenu = () => { return false; }; __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").classList.add("ol-dialog"); document.body.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f")); - __classPrivateFieldSet(this, _DatabaseManagerPlugin_scrollDiv, document.createElement("div"), "f"); - __classPrivateFieldGet(this, _DatabaseManagerPlugin_scrollDiv, "f").classList.add("dm-scroll-container"); - __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_scrollDiv, "f")); - __classPrivateFieldSet(this, _DatabaseManagerPlugin_contentDiv, document.createElement("div"), "f"); - __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv, "f").classList.add("dm-content-container"); - __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv, "f")); - __classPrivateFieldSet(this, _DatabaseManagerPlugin_aircraftEditor, new airuniteditor_1.AirUnitEditor(__classPrivateFieldGet(this, _DatabaseManagerPlugin_scrollDiv, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv, "f")), "f"); + /* Start hidden */ + this.toggle(false); + /* Create the top tab buttons container and buttons */ + let topButtonContainer = document.createElement("div"); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button1, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").classList.add("tab-button"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").textContent = "Aircraft database"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_hideAll).call(this); __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").show(); __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").classList.add("selected"); }; + topButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button2, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button2, "f").classList.add("tab-button"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button2, "f").textContent = "Helicopter database"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button2, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_hideAll).call(this); __classPrivateFieldGet(this, _DatabaseManagerPlugin_helicopterEditor, "f").show(); __classPrivateFieldGet(this, _DatabaseManagerPlugin_button2, "f").classList.add("selected"); }; + topButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button2, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button3, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button3, "f").classList.add("tab-button"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button3, "f").textContent = "Ground Unit database"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button3, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_hideAll).call(this); __classPrivateFieldGet(this, _DatabaseManagerPlugin_groundUnitEditor, "f").show(); __classPrivateFieldGet(this, _DatabaseManagerPlugin_button3, "f").classList.add("selected"); }; + topButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button3, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button4, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button4, "f").classList.add("tab-button"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button4, "f").textContent = "Navy Unit database"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button4, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_hideAll).call(this); __classPrivateFieldGet(this, _DatabaseManagerPlugin_navyUnitEditor, "f").show(); __classPrivateFieldGet(this, _DatabaseManagerPlugin_button4, "f").classList.add("selected"); }; + topButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button4, "f")); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").appendChild(topButtonContainer); + /* Create the container for the database editor elements and the elements themselves */ + __classPrivateFieldSet(this, _DatabaseManagerPlugin_mainContentContainer, document.createElement("div"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_mainContentContainer, "f").classList.add("dm-container"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_mainContentContainer, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_contentDiv1, document.createElement("div"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv1, "f").classList.add("dm-content-container"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_mainContentContainer, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv1, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_contentDiv2, document.createElement("div"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv2, "f").classList.add("dm-content-container"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_mainContentContainer, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv2, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_contentDiv3, document.createElement("div"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv3, "f").classList.add("dm-content-container"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_mainContentContainer, "f").appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv3, "f")); + /* Create the database editors, which use the three divs created before */ + __classPrivateFieldSet(this, _DatabaseManagerPlugin_aircraftEditor, new airuniteditor_1.AirUnitEditor(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv1, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv2, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv3, "f")), "f"); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_helicopterEditor, new airuniteditor_1.AirUnitEditor(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv1, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv2, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv3, "f")), "f"); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_groundUnitEditor, new grounduniteditor_1.GroundUnitEditor(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv1, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv2, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv3, "f")), "f"); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_navyUnitEditor, new navyuniteditor_1.NavyUnitEditor(__classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv1, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv2, "f"), __classPrivateFieldGet(this, _DatabaseManagerPlugin_contentDiv3, "f")), "f"); + /* Create the bottom buttons container. These buttons allow to save, restore, reset, and discard the changes */ + let bottomButtonContainer = document.createElement("div"); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button5, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button5, "f").textContent = "Save"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button5, "f").title = "Save the changes on the server"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button5, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_saveDatabases).call(this); }; + bottomButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button5, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button6, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button6, "f").textContent = "Discard"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button6, "f").title = "Discard all changes and reload the database from the server"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button6, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_loadDatabases).call(this); }; + bottomButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button6, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button7, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button7, "f").textContent = "Reset defaults"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button7, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_resetToDefaultDatabases).call(this); }; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button7, "f").title = "Reset the databases to the default values"; + bottomButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button7, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button8, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button8, "f").textContent = "Restore previous"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button8, "f").onclick = () => { __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_restoreToPreviousDatabases).call(this); }; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button8, "f").title = "Restore the previously saved databases. Use this if you saved a database by mistake."; + bottomButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button8, "f")); + __classPrivateFieldSet(this, _DatabaseManagerPlugin_button9, document.createElement("button"), "f"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button9, "f").textContent = "Close"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button9, "f").title = "Close the Database Manager"; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button9, "f").onclick = () => { this.toggle(false); }; + bottomButtonContainer.appendChild(__classPrivateFieldGet(this, _DatabaseManagerPlugin_button9, "f")); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f").appendChild(bottomButtonContainer); } + /** + * + * @returns The name of the plugin + */ getName() { return "Database Control Plugin"; } + /** Initialize the plugin + * + * @param app The OlympusApp singleton + * @returns True if successfull + */ initialize(app) { var _a; __classPrivateFieldSet(this, _DatabaseManagerPlugin_app, app, "f"); - var aircraftDatabase = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getAircraftDatabase(); - if (aircraftDatabase != null) { - __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").setDatabase(aircraftDatabase); - __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").show(); - } + /* Load the databases and initialize the editors */ + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_loadDatabases).call(this); + /* Add a button to the main Olympus App to allow the users to open the dialog */ + var mainButtonDiv = document.createElement("div"); + var mainButton = document.createElement("button"); + mainButton.textContent = "Database manager"; + mainButtonDiv.appendChild(mainButton); + var toolbar = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getToolbarsManager().get("primaryToolbar"); + var elements = toolbar.getMainDropdown().getOptionElements(); + var arr = Array.prototype.slice.call(elements); + arr.splice(arr.length - 1, 0, mainButtonDiv); + toolbar.getMainDropdown().setOptionsElements(arr); + mainButton.onclick = () => { + var _a; + toolbar.getMainDropdown().close(); + if (((_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getMissionManager().getCommandModeOptions().commandMode) === "Game master") + this.toggle(); + }; return true; } + /** + * + * @returns The main container element + */ getElement() { return __classPrivateFieldGet(this, _DatabaseManagerPlugin_element, "f"); } + /** Toggles the visibility of the dialog + * + * @param bool Force a specific visibility state + */ toggle(bool) { - this.getElement().classList.toggle("hide", bool); + if (bool) + this.getElement().classList.toggle("hide", !bool); + else + this.getElement().classList.toggle("hide"); } } exports.DatabaseManagerPlugin = DatabaseManagerPlugin; -_DatabaseManagerPlugin_app = new WeakMap(), _DatabaseManagerPlugin_element = new WeakMap(), _DatabaseManagerPlugin_scrollDiv = new WeakMap(), _DatabaseManagerPlugin_contentDiv = new WeakMap(), _DatabaseManagerPlugin_aircraftEditor = new WeakMap(); -},{"./airuniteditor":1}],3:[function(require,module,exports){ +_DatabaseManagerPlugin_app = new WeakMap(), _DatabaseManagerPlugin_element = new WeakMap(), _DatabaseManagerPlugin_mainContentContainer = new WeakMap(), _DatabaseManagerPlugin_contentDiv1 = new WeakMap(), _DatabaseManagerPlugin_contentDiv2 = new WeakMap(), _DatabaseManagerPlugin_contentDiv3 = new WeakMap(), _DatabaseManagerPlugin_button1 = new WeakMap(), _DatabaseManagerPlugin_button2 = new WeakMap(), _DatabaseManagerPlugin_button3 = new WeakMap(), _DatabaseManagerPlugin_button4 = new WeakMap(), _DatabaseManagerPlugin_button5 = new WeakMap(), _DatabaseManagerPlugin_button6 = new WeakMap(), _DatabaseManagerPlugin_button7 = new WeakMap(), _DatabaseManagerPlugin_button8 = new WeakMap(), _DatabaseManagerPlugin_button9 = new WeakMap(), _DatabaseManagerPlugin_aircraftEditor = new WeakMap(), _DatabaseManagerPlugin_helicopterEditor = new WeakMap(), _DatabaseManagerPlugin_groundUnitEditor = new WeakMap(), _DatabaseManagerPlugin_navyUnitEditor = new WeakMap(), _DatabaseManagerPlugin_instances = new WeakSet(), _DatabaseManagerPlugin_hideAll = function _DatabaseManagerPlugin_hideAll() { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").hide(); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_helicopterEditor, "f").hide(); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_groundUnitEditor, "f").hide(); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_navyUnitEditor, "f").hide(); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").classList.remove("selected"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button2, "f").classList.remove("selected"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button3, "f").classList.remove("selected"); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button4, "f").classList.remove("selected"); +}, _DatabaseManagerPlugin_loadDatabases = function _DatabaseManagerPlugin_loadDatabases() { + var _a, _b, _c, _d; + var aircraftDatabase = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getAircraftDatabase(); + if (aircraftDatabase != null) + __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").setDatabase(aircraftDatabase); + var helicopterDatabase = (_b = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _b === void 0 ? void 0 : _b.getHelicopterDatabase(); + if (helicopterDatabase != null) + __classPrivateFieldGet(this, _DatabaseManagerPlugin_helicopterEditor, "f").setDatabase(helicopterDatabase); + var groundUnitDatabase = (_c = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _c === void 0 ? void 0 : _c.getGroundUnitDatabase(); + if (groundUnitDatabase != null) + __classPrivateFieldGet(this, _DatabaseManagerPlugin_groundUnitEditor, "f").setDatabase(groundUnitDatabase); + var navyUnitDatabase = (_d = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _d === void 0 ? void 0 : _d.getNavyUnitDatabase(); + if (navyUnitDatabase != null) + __classPrivateFieldGet(this, _DatabaseManagerPlugin_navyUnitEditor, "f").setDatabase(navyUnitDatabase); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_hideAll).call(this); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").show(); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").classList.add("selected"); +}, _DatabaseManagerPlugin_saveDatabases = function _DatabaseManagerPlugin_saveDatabases() { + var aircraftDatabase = __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").getDatabase(); + if (aircraftDatabase) { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_uploadDatabase).call(this, aircraftDatabase, "aircraftdatabase", "Aircraft database", () => { + var helicopterDatabase = __classPrivateFieldGet(this, _DatabaseManagerPlugin_helicopterEditor, "f").getDatabase(); + if (helicopterDatabase) { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_uploadDatabase).call(this, helicopterDatabase, "helicopterDatabase", "Helicopter database", () => { + var groundUnitDatabase = __classPrivateFieldGet(this, _DatabaseManagerPlugin_groundUnitEditor, "f").getDatabase(); + if (groundUnitDatabase) { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_uploadDatabase).call(this, groundUnitDatabase, "groundUnitDatabase", "Ground Unit database", () => { + var navyUnitDatabase = __classPrivateFieldGet(this, _DatabaseManagerPlugin_navyUnitEditor, "f").getDatabase(); + if (navyUnitDatabase) { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_uploadDatabase).call(this, navyUnitDatabase, "navyUnitDatabase", "Navy Unit database", () => { + var _a, _b, _c, _d, _e; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getAircraftDatabase().load(() => { }); + (_b = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _b === void 0 ? void 0 : _b.getHelicopterDatabase().load(() => { }); + (_c = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _c === void 0 ? void 0 : _c.getGroundUnitDatabase().load(() => { }); + (_d = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _d === void 0 ? void 0 : _d.getNavyUnitDatabase().load(() => { }); + (_e = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _e === void 0 ? void 0 : _e.getServerManager().reloadDatabases(() => { + var _a, _b; + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText("Olympus core databases reloaded"); + }); + }); + } + }); + } + }); + } + }); + } +}, _DatabaseManagerPlugin_resetToDefaultDatabases = function _DatabaseManagerPlugin_resetToDefaultDatabases() { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_resetToDefaultDatabase).call(this, "aircraftdatabase", "Aircraft database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getAircraftDatabase().load(() => { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_resetToDefaultDatabase).call(this, "helicopterdatabase", "Helicopter database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getHelicopterDatabase().load(() => { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_resetToDefaultDatabase).call(this, "groundunitdatabase", "Ground Unit database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getGroundUnitDatabase().load(() => { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_resetToDefaultDatabase).call(this, "navyunitdatabase", "Navy Unit database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getNavyUnitDatabase().load(() => { + var _a; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_loadDatabases).call(this); + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getServerManager().reloadDatabases(() => { + var _a, _b; + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText("Olympus core databases reloaded"); + }); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_hideAll).call(this); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").show(); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").classList.add("selected"); + }); + }); + }); + }); + }); + }); + }); + }); +}, _DatabaseManagerPlugin_restoreToPreviousDatabases = function _DatabaseManagerPlugin_restoreToPreviousDatabases() { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_restoreToPreviousDatabase).call(this, "aircraftdatabase", "Aircraft database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getAircraftDatabase().load(() => { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_restoreToPreviousDatabase).call(this, "helicopterdatabase", "Helicopter database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getHelicopterDatabase().load(() => { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_restoreToPreviousDatabase).call(this, "groundunitdatabase", "Ground Unit database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getGroundUnitDatabase().load(() => { + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_restoreToPreviousDatabase).call(this, "navyunitdatabase", "Navy Unit database", () => { + var _a; + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getNavyUnitDatabase().load(() => { + var _a; + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_loadDatabases).call(this); + (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getServerManager().reloadDatabases(() => { + var _a, _b; + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText("Olympus core databases reloaded"); + }); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_instances, "m", _DatabaseManagerPlugin_hideAll).call(this); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_aircraftEditor, "f").show(); + __classPrivateFieldGet(this, _DatabaseManagerPlugin_button1, "f").classList.add("selected"); + }); + }); + }); + }); + }); + }); + }); + }); +}, _DatabaseManagerPlugin_uploadDatabase = function _DatabaseManagerPlugin_uploadDatabase(database, name, label, callback) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open("PUT", "/api/databases/save/units/" + name); + xmlHttp.setRequestHeader("Content-Type", "application/json"); + xmlHttp.onload = (res) => { + var _a, _b, _c, _d; + if (xmlHttp.status == 200) { + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText(label + " saved successfully"); + callback(); + } + else { + (_d = (_c = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _c === void 0 ? void 0 : _c.getPopupsManager().get("infoPopup")) === null || _d === void 0 ? void 0 : _d.setText("An error has occurred while saving the " + label); + } + }; + xmlHttp.onerror = (res) => { + var _a, _b; + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText("An error has occurred while saving the " + label); + }; + xmlHttp.send(JSON.stringify(database)); +}, _DatabaseManagerPlugin_resetToDefaultDatabase = function _DatabaseManagerPlugin_resetToDefaultDatabase(name, label, callback) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open("PUT", "/api/databases/reset/units/" + name); + xmlHttp.setRequestHeader("Content-Type", "application/json"); + xmlHttp.onload = (res) => { + var _a, _b, _c, _d; + if (xmlHttp.status == 200) { + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText(label + " reset successfully"); + callback(); + } + else { + (_d = (_c = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _c === void 0 ? void 0 : _c.getPopupsManager().get("infoPopup")) === null || _d === void 0 ? void 0 : _d.setText("An error has occurred while resetting the " + label); + } + }; + xmlHttp.onerror = (res) => { + var _a, _b; + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText("An error has occurred while resetting the " + label); + }; + xmlHttp.send(""); +}, _DatabaseManagerPlugin_restoreToPreviousDatabase = function _DatabaseManagerPlugin_restoreToPreviousDatabase(name, label, callback) { + var xmlHttp = new XMLHttpRequest(); + xmlHttp.open("PUT", "/api/databases/restore/units/" + name); + xmlHttp.setRequestHeader("Content-Type", "application/json"); + xmlHttp.onload = (res) => { + var _a, _b, _c, _d; + if (xmlHttp.status == 200) { + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText(label + " restored successfully"); + callback(); + } + else { + (_d = (_c = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _c === void 0 ? void 0 : _c.getPopupsManager().get("infoPopup")) === null || _d === void 0 ? void 0 : _d.setText("An error has occurred while restoring the " + label); + } + }; + xmlHttp.onerror = (res) => { + var _a, _b; + (_b = (_a = __classPrivateFieldGet(this, _DatabaseManagerPlugin_app, "f")) === null || _a === void 0 ? void 0 : _a.getPopupsManager().get("infoPopup")) === null || _b === void 0 ? void 0 : _b.setText("An error has occurred while restoring the " + label); + }; + xmlHttp.send(""); +}; + +},{"./airuniteditor":1,"./grounduniteditor":3,"./navyuniteditor":6}],3:[function(require,module,exports){ +"use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _GroundUnitEditor_blueprint; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.GroundUnitEditor = void 0; +const uniteditor_1 = require("./uniteditor"); +const utils_1 = require("./utils"); +/** Database editor for ground units + * + */ +class GroundUnitEditor extends uniteditor_1.UnitEditor { + constructor(contentDiv1, contentDiv2, contentDiv3) { + super(contentDiv1, contentDiv2, contentDiv3); + _GroundUnitEditor_blueprint.set(this, null); + } + /** Sets a unit blueprint as the currently active one + * + * @param blueprint The blueprint to edit + */ + setBlueprint(blueprint) { + var _a, _b, _c, _d, _e, _f, _g, _h; + __classPrivateFieldSet(this, _GroundUnitEditor_blueprint, blueprint, "f"); + if (__classPrivateFieldGet(this, _GroundUnitEditor_blueprint, "f") !== null) { + this.contentDiv2.replaceChildren(); + var title = document.createElement("label"); + title.innerText = "Unit properties"; + this.contentDiv2.appendChild(title); + (0, utils_1.addStringInput)(this.contentDiv2, "Name", blueprint.name, "text", (value) => { blueprint.name = value; }, true); + (0, utils_1.addStringInput)(this.contentDiv2, "Label", blueprint.label, "text", (value) => { blueprint.label = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Short label", blueprint.shortLabel, "text", (value) => { blueprint.shortLabel = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Type", (_a = blueprint.type) !== null && _a !== void 0 ? _a : "", "text", (value) => { blueprint.type = value; }); + (0, utils_1.addDropdownInput)(this.contentDiv2, "Coalition", blueprint.coalition, ["", "blue", "red"]); + (0, utils_1.addDropdownInput)(this.contentDiv2, "Era", blueprint.era, ["WW2", "Early Cold War", "Mid Cold War", "Late Cold War", "Modern"]); + //addStringInput(this.contentDiv2, "Filename", blueprint.filename?? "", "text", (value: string) => {blueprint.filename = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Cost", (_b = String(blueprint.cost)) !== null && _b !== void 0 ? _b : "", "number", (value) => { blueprint.cost = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Acquisition range [NM]", (_c = String(blueprint.acquisitionRange)) !== null && _c !== void 0 ? _c : "", "number", (value) => { blueprint.acquisitionRange = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Engagement range [NM]", (_d = String(blueprint.engagementRange)) !== null && _d !== void 0 ? _d : "", "number", (value) => { blueprint.engagementRange = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Barrel height [m]", (_e = String(blueprint.barrelHeight)) !== null && _e !== void 0 ? _e : "", "number", (value) => { blueprint.barrelHeight = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Muzzle velocity [m/s]", (_f = String(blueprint.muzzleVelocity)) !== null && _f !== void 0 ? _f : "", "number", (value) => { blueprint.muzzleVelocity = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Aim time [s]", (_g = String(blueprint.aimTime)) !== null && _g !== void 0 ? _g : "", "number", (value) => { blueprint.aimTime = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Burst quantity", (_h = String(blueprint.shotsToFire)) !== null && _h !== void 0 ? _h : "", "number", (value) => { blueprint.shotsToFire = Math.round(parseFloat(value)); }); + } + } + /** Add a new empty blueprint + * + * @param key Blueprint key + */ + addBlueprint(key) { + if (this.database != null) { + this.database.blueprints[key] = { + name: key, + coalition: "", + label: "", + shortLabel: "", + era: "" + }; + this.show(); + this.setBlueprint(this.database.blueprints[key]); + } + } +} +exports.GroundUnitEditor = GroundUnitEditor; +_GroundUnitEditor_blueprint = new WeakMap(); + +},{"./uniteditor":7,"./utils":8}],4:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const databasemanagerplugin_1 = require("./databasemanagerplugin"); globalThis.getOlympusPlugin = () => { return new databasemanagerplugin_1.DatabaseManagerPlugin(); }; -},{"./databasemanagerplugin":2}],4:[function(require,module,exports){ + +},{"./databasemanagerplugin":2}],5:[function(require,module,exports){ +"use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _LoadoutEditor_contentDiv, _LoadoutEditor_loadout, _LoadoutEditor_visible; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.LoadoutEditor = void 0; +const utils_1 = require("./utils"); +/** The LoadoutEditor allows the user to edit a loadout + * + */ +class LoadoutEditor { + constructor(contentDiv) { + _LoadoutEditor_contentDiv.set(this, void 0); + _LoadoutEditor_loadout.set(this, null); + _LoadoutEditor_visible.set(this, false); + __classPrivateFieldSet(this, _LoadoutEditor_contentDiv, contentDiv, "f"); + __classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f").addEventListener("refresh", () => { + if (__classPrivateFieldGet(this, _LoadoutEditor_visible, "f")) + this.show(); + }); + } + /** Set the loadout to edit + * + * @param loadout The loadout to edit + */ + setLoadout(loadout) { + __classPrivateFieldSet(this, _LoadoutEditor_loadout, loadout, "f"); + } + /** Show the editor + * + */ + show() { + __classPrivateFieldSet(this, _LoadoutEditor_visible, true, "f"); + __classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f").replaceChildren(); + var title = document.createElement("label"); + title.innerText = "Loadout properties"; + __classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f").appendChild(title); + if (__classPrivateFieldGet(this, _LoadoutEditor_loadout, "f")) { + var laodout = __classPrivateFieldGet(this, _LoadoutEditor_loadout, "f"); + (0, utils_1.addStringInput)(__classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f"), "Name", laodout.name, "text", (value) => { laodout.name = value; __classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f").dispatchEvent(new Event("refresh")); }); + (0, utils_1.addStringInput)(__classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f"), "Code", laodout.code, "text", (value) => { laodout.code = value; }); + (0, utils_1.addLoadoutItemsEditor)(__classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f"), __classPrivateFieldGet(this, _LoadoutEditor_loadout, "f")); + } + } + /** Hide the editor + * + */ + hide() { + __classPrivateFieldSet(this, _LoadoutEditor_visible, false, "f"); + __classPrivateFieldGet(this, _LoadoutEditor_contentDiv, "f").replaceChildren(); + } +} +exports.LoadoutEditor = LoadoutEditor; +_LoadoutEditor_contentDiv = new WeakMap(), _LoadoutEditor_loadout = new WeakMap(), _LoadoutEditor_visible = new WeakMap(); + +},{"./utils":8}],6:[function(require,module,exports){ +"use strict"; +var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; +}; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var _NavyUnitEditor_blueprint; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NavyUnitEditor = void 0; +const uniteditor_1 = require("./uniteditor"); +const utils_1 = require("./utils"); +/** Database editor for navy units + * + */ +class NavyUnitEditor extends uniteditor_1.UnitEditor { + constructor(contentDiv1, contentDiv2, contentDiv3) { + super(contentDiv1, contentDiv2, contentDiv3); + _NavyUnitEditor_blueprint.set(this, null); + } + /** Sets a unit blueprint as the currently active one + * + * @param blueprint The blueprint to edit + */ + setBlueprint(blueprint) { + var _a, _b, _c, _d; + __classPrivateFieldSet(this, _NavyUnitEditor_blueprint, blueprint, "f"); + if (__classPrivateFieldGet(this, _NavyUnitEditor_blueprint, "f") !== null) { + this.contentDiv2.replaceChildren(); + var title = document.createElement("label"); + title.innerText = "Unit properties"; + this.contentDiv2.appendChild(title); + (0, utils_1.addStringInput)(this.contentDiv2, "Name", blueprint.name, "text", (value) => { blueprint.name = value; }, true); + (0, utils_1.addStringInput)(this.contentDiv2, "Label", blueprint.label, "text", (value) => { blueprint.label = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Short label", blueprint.shortLabel, "text", (value) => { blueprint.shortLabel = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Type", (_a = blueprint.type) !== null && _a !== void 0 ? _a : "", "text", (value) => { blueprint.type = value; }); + (0, utils_1.addDropdownInput)(this.contentDiv2, "Coalition", blueprint.coalition, ["", "blue", "red"]); + (0, utils_1.addDropdownInput)(this.contentDiv2, "Era", blueprint.era, ["WW2", "Early Cold War", "Mid Cold War", "Late Cold War", "Modern"]); + //addStringInput(this.contentDiv2, "Filename", blueprint.filename?? "", "text", (value: string) => {blueprint.filename = value; }); + (0, utils_1.addStringInput)(this.contentDiv2, "Cost", (_b = String(blueprint.cost)) !== null && _b !== void 0 ? _b : "", "number", (value) => { blueprint.cost = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Barrel height [m]", (_c = String(blueprint.barrelHeight)) !== null && _c !== void 0 ? _c : "", "number", (value) => { blueprint.barrelHeight = parseFloat(value); }); + (0, utils_1.addStringInput)(this.contentDiv2, "Muzzle velocity [m/s]", (_d = String(blueprint.muzzleVelocity)) !== null && _d !== void 0 ? _d : "", "number", (value) => { blueprint.muzzleVelocity = parseFloat(value); }); + } + } + /** Add a new empty blueprint + * + * @param key Blueprint key + */ + addBlueprint(key) { + if (this.database != null) { + this.database.blueprints[key] = { + name: key, + coalition: "", + label: "", + shortLabel: "", + era: "" + }; + this.show(); + this.setBlueprint(this.database.blueprints[key]); + } + } +} +exports.NavyUnitEditor = NavyUnitEditor; +_NavyUnitEditor_blueprint = new WeakMap(); + +},{"./uniteditor":7,"./utils":8}],7:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.UnitEditor = void 0; +const utils_1 = require("./utils"); +/** Base abstract class of Unit database editors + * + */ class UnitEditor { - constructor(scrollDiv, contentDiv) { + constructor(contentDiv1, contentDiv2, contentDiv3) { + this.blueprint = null; this.database = null; - this.scrollDiv = scrollDiv; - this.contentDiv = contentDiv; - } - setDatabase(database) { - this.database = database; - } - show() { - if (this.database !== null) { - var blueprints = this.database.getBlueprints(); - for (let key in blueprints) { - var div = document.createElement("div"); - this.scrollDiv.appendChild(div); - div.textContent = key; - div.onclick = () => this.setContent(blueprints[key]); + this.visible = false; + this.contentDiv1 = contentDiv1; + this.contentDiv2 = contentDiv2; + this.contentDiv3 = contentDiv3; + /* Refresh the list of units if it changes */ + this.contentDiv1.addEventListener("refresh", () => { + if (this.visible) + this.show(); + }); + /* If the unit properties or loadout are edited, reload the editor */ + this.contentDiv2.addEventListener("refresh", () => { + if (this.visible) { + if (this.blueprint !== null) + this.setBlueprint(this.blueprint); } + }); + this.contentDiv3.addEventListener("refresh", () => { + if (this.visible) { + if (this.blueprint !== null) + this.setBlueprint(this.blueprint); + } + }); + } + /** + * + * @param database The database that the editor will operate on + */ + setDatabase(database) { + this.database = JSON.parse(JSON.stringify(database)); + } + /** Show the editor + * + */ + show() { + this.visible = true; + this.contentDiv1.replaceChildren(); + this.contentDiv2.replaceChildren(); + this.contentDiv3.replaceChildren(); + /* Create the list of units. Each unit is clickable to activate the editor on it */ + if (this.database != null) { + var title = document.createElement("label"); + title.innerText = "Units list"; + this.contentDiv1.appendChild(title); + (0, utils_1.addBlueprintsScroll)(this.contentDiv1, this.database, (key) => { + if (this.database != null) + this.setBlueprint(this.database.blueprints[key]); + }); + (0, utils_1.addNewElementInput)(this.contentDiv1, (ev, input) => { + if (input.value != "") + this.addBlueprint((input).value); + }); } } - addStringInput(key, value) { - var dt = document.createElement("dt"); - var dd = document.createElement("dd"); - dt.innerText = key; - var input = document.createElement("input"); - input.value = value; - input.textContent = value; - dd.appendChild(input); - this.contentDiv.appendChild(dt); - this.contentDiv.appendChild(dd); + /** Hid the editor + * + */ + hide() { + this.visible = false; + this.contentDiv1.replaceChildren(); + this.contentDiv2.replaceChildren(); + this.contentDiv3.replaceChildren(); } - addDropdownInput(key, value, options) { - var dt = document.createElement("dt"); - var dd = document.createElement("dd"); - dt.innerText = key; - var input = document.createElement("input"); - input.value = value; - input.textContent = value; - dd.appendChild(input); - this.contentDiv.appendChild(dt); - this.contentDiv.appendChild(dd); + /** + * + * @returns The edited database + */ + getDatabase() { + return this.database; } } exports.UnitEditor = UnitEditor; -},{}]},{},[3]) -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvYWlydW5pdGVkaXRvci50cyIsInNyYy9kYXRhYmFzZW1hbmFnZXJwbHVnaW4udHMiLCJzcmMvaW5kZXgudHMiLCJzcmMvdW5pdGVkaXRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztBQ0NBLDZDQUEwQztBQUUxQyxNQUFhLGFBQWMsU0FBUSx1QkFBVTtJQUN6QyxZQUFZLFNBQXNCLEVBQUUsVUFBdUI7UUFDdkQsS0FBSyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsVUFBVSxDQUFDLFNBQXdCO1FBQy9CLElBQUksQ0FBQyxVQUFVLENBQUMsZUFBZSxFQUFFLENBQUM7UUFFbEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxTQUFTLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDN0QsQ0FBQztDQUNKO0FBWkQsc0NBWUM7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDZEQsbURBQWdEO0FBR2hELE1BQWEscUJBQXFCO0lBUzlCO1FBUkEscUNBQTBCLElBQUksRUFBQztRQUUvQixpREFBc0I7UUFDdEIsbURBQXdCO1FBQ3hCLG9EQUF5QjtRQUV6Qix3REFBK0I7UUFHM0IsdUJBQUEsSUFBSSxrQ0FBWSxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxNQUFBLENBQUM7UUFDOUMsdUJBQUEsSUFBSSxzQ0FBUyxDQUFDLEVBQUUsR0FBRyx3QkFBd0IsQ0FBQztRQUM1Qyx1QkFBQSxJQUFJLHNDQUFTLENBQUMsYUFBYSxHQUFHLEdBQUcsRUFBRSxHQUFHLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ3JELHVCQUFBLElBQUksc0NBQVMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ3pDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLHVCQUFBLElBQUksc0NBQVMsQ0FBQyxDQUFDO1FBRXpDLHVCQUFBLElBQUksb0NBQWMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsTUFBQSxDQUFDO1FBQ2hELHVCQUFBLElBQUksd0NBQVcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDLENBQUM7UUFDckQsdUJBQUEsSUFBSSxzQ0FBUyxDQUFDLFdBQVcsQ0FBQyx1QkFBQSxJQUFJLHdDQUFXLENBQUMsQ0FBQztRQUUzQyx1QkFBQSxJQUFJLHFDQUFlLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLE1BQUEsQ0FBQztRQUNqRCx1QkFBQSxJQUFJLHlDQUFZLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1FBQ3ZELHVCQUFBLElBQUksc0NBQVMsQ0FBQyxXQUFXLENBQUMsdUJBQUEsSUFBSSx5Q0FBWSxDQUFDLENBQUM7UUFFNUMsdUJBQUEsSUFBSSx5Q0FBbUIsSUFBSSw2QkFBYSxDQUFDLHVCQUFBLElBQUksd0NBQVcsRUFBRSx1QkFBQSxJQUFJLHlDQUFZLENBQUMsTUFBQSxDQUFDO0lBQ2hGLENBQUM7SUFFRCxPQUFPO1FBQ0gsT0FBTyx5QkFBeUIsQ0FBQTtJQUNwQyxDQUFDO0lBRUQsVUFBVSxDQUFDLEdBQVE7O1FBQ2YsdUJBQUEsSUFBSSw4QkFBUSxHQUFHLE1BQUEsQ0FBQztRQUVoQixJQUFJLGdCQUFnQixHQUFHLE1BQUEsdUJBQUEsSUFBSSxrQ0FBSywwQ0FBRSxtQkFBbUIsRUFBRSxDQUFDO1FBQ3hELElBQUksZ0JBQWdCLElBQUksSUFBSSxFQUFFO1lBQzFCLHVCQUFBLElBQUksNkNBQWdCLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDbkQsdUJBQUEsSUFBSSw2Q0FBZ0IsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUMvQjtRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxVQUFVO1FBQ04sT0FBTyx1QkFBQSxJQUFJLHNDQUFTLENBQUM7SUFDekIsQ0FBQztJQUVELE1BQU0sQ0FBQyxJQUFjO1FBQ2pCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNyRCxDQUFDO0NBQ0o7QUFsREQsc0RBa0RDOzs7OztBQ3RERCxtRUFBZ0U7QUFFaEUsVUFBVSxDQUFDLGdCQUFnQixHQUFHLEdBQUcsRUFBRTtJQUMvQixPQUFPLElBQUksNkNBQXFCLEVBQUUsQ0FBQztBQUN2QyxDQUFDLENBQUE7Ozs7O0FDREQsTUFBc0IsVUFBVTtJQUs1QixZQUFZLFNBQXNCLEVBQUUsVUFBdUI7UUFKM0QsYUFBUSxHQUF3QixJQUFJLENBQUM7UUFLakMsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7SUFDakMsQ0FBQztJQUVELFdBQVcsQ0FBQyxRQUFhO1FBQ3JCLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO0lBQzdCLENBQUM7SUFFRCxJQUFJO1FBQ0EsSUFBSSxJQUFJLENBQUMsUUFBUSxLQUFLLElBQUksRUFBRTtZQUN4QixJQUFJLFVBQVUsR0FBbUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUUvRSxLQUFLLElBQUksR0FBRyxJQUFJLFVBQVUsRUFBRTtnQkFDeEIsSUFBSSxHQUFHLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2hDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDO2dCQUN0QixHQUFHLENBQUMsT0FBTyxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7YUFDeEQ7U0FDSjtJQUNMLENBQUM7SUFFRCxjQUFjLENBQUMsR0FBVyxFQUFFLEtBQWE7UUFDckMsSUFBSSxFQUFFLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLEVBQUUsQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDO1FBQ25CLElBQUksS0FBSyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUMsS0FBSyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDcEIsS0FBSyxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUM7UUFDMUIsRUFBRSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QixJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsR0FBVyxFQUFFLEtBQWEsRUFBRSxPQUFpQjtRQUMxRCxJQUFJLEVBQUUsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLElBQUksRUFBRSxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsRUFBRSxDQUFDLFNBQVMsR0FBRyxHQUFHLENBQUM7UUFDbkIsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM1QyxLQUFLLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNwQixLQUFLLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztRQUMxQixFQUFFLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7Q0FJSjtBQXJERCxnQ0FxREMiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbigpe2Z1bmN0aW9uIHIoZSxuLHQpe2Z1bmN0aW9uIG8oaSxmKXtpZighbltpXSl7aWYoIWVbaV0pe3ZhciBjPVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmU7aWYoIWYmJmMpcmV0dXJuIGMoaSwhMCk7aWYodSlyZXR1cm4gdShpLCEwKTt2YXIgYT1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2krXCInXCIpO3Rocm93IGEuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixhfXZhciBwPW5baV09e2V4cG9ydHM6e319O2VbaV1bMF0uY2FsbChwLmV4cG9ydHMsZnVuY3Rpb24ocil7dmFyIG49ZVtpXVsxXVtyXTtyZXR1cm4gbyhufHxyKX0scCxwLmV4cG9ydHMscixlLG4sdCl9cmV0dXJuIG5baV0uZXhwb3J0c31mb3IodmFyIHU9XCJmdW5jdGlvblwiPT10eXBlb2YgcmVxdWlyZSYmcmVxdWlyZSxpPTA7aTx0Lmxlbmd0aDtpKyspbyh0W2ldKTtyZXR1cm4gb31yZXR1cm4gcn0pKCkiLCJpbXBvcnQgeyBVbml0Qmx1ZXByaW50IH0gZnJvbSBcImludGVyZmFjZXNcIjtcclxuaW1wb3J0IHsgVW5pdEVkaXRvciB9IGZyb20gXCIuL3VuaXRlZGl0b3JcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBBaXJVbml0RWRpdG9yIGV4dGVuZHMgVW5pdEVkaXRvciB7XHJcbiAgICBjb25zdHJ1Y3RvcihzY3JvbGxEaXY6IEhUTUxFbGVtZW50LCBjb250ZW50RGl2OiBIVE1MRWxlbWVudCkge1xyXG4gICAgICAgIHN1cGVyKHNjcm9sbERpdiwgY29udGVudERpdik7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Q29udGVudChibHVlcHJpbnQ6IFVuaXRCbHVlcHJpbnQpIHtcclxuICAgICAgICB0aGlzLmNvbnRlbnREaXYucmVwbGFjZUNoaWxkcmVuKCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5hZGRTdHJpbmdJbnB1dChcIk5hbWVcIiwgYmx1ZXByaW50Lm5hbWUpO1xyXG4gICAgICAgIHRoaXMuYWRkU3RyaW5nSW5wdXQoXCJMYWJlbFwiLCBibHVlcHJpbnQubGFiZWwpO1xyXG4gICAgICAgIHRoaXMuYWRkU3RyaW5nSW5wdXQoXCJTaG9ydCBsYWJlbFwiLCBibHVlcHJpbnQuc2hvcnRMYWJlbCk7XHJcbiAgICB9XHJcbn1cclxuIiwiaW1wb3J0IHsgT2x5bXB1c1BsdWdpbiB9IGZyb20gXCJpbnRlcmZhY2VzXCI7XHJcbmltcG9ydCB7IEFpclVuaXRFZGl0b3IgfSBmcm9tIFwiLi9haXJ1bml0ZWRpdG9yXCI7XHJcbmltcG9ydCB7IE9seW1wdXNBcHAgfSBmcm9tIFwib2x5bXB1c2FwcFwiO1xyXG5cclxuZXhwb3J0IGNsYXNzIERhdGFiYXNlTWFuYWdlclBsdWdpbiBpbXBsZW1lbnRzIE9seW1wdXNQbHVnaW4ge1xyXG4gICAgI2FwcDogT2x5bXB1c0FwcCB8IG51bGwgPSBudWxsO1xyXG5cclxuICAgICNlbGVtZW50OiBIVE1MRWxlbWVudDtcclxuICAgICNzY3JvbGxEaXY6IEhUTUxFbGVtZW50O1xyXG4gICAgI2NvbnRlbnREaXY6IEhUTUxFbGVtZW50O1xyXG5cclxuICAgICNhaXJjcmFmdEVkaXRvcjogQWlyVW5pdEVkaXRvcjtcclxuICAgICAgICBcclxuICAgIGNvbnN0cnVjdG9yKCkge1xyXG4gICAgICAgIHRoaXMuI2VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgIHRoaXMuI2VsZW1lbnQuaWQgPSBcImRhdGFiYXNlLWNvbnRyb2wtcGFuZWxcIjtcclxuICAgICAgICB0aGlzLiNlbGVtZW50Lm9uY29udGV4dG1lbnUgPSAoKSA9PiB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgICAgIHRoaXMuI2VsZW1lbnQuY2xhc3NMaXN0LmFkZChcIm9sLWRpYWxvZ1wiKTtcclxuICAgICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKHRoaXMuI2VsZW1lbnQpO1xyXG5cclxuICAgICAgICB0aGlzLiNzY3JvbGxEaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgIHRoaXMuI3Njcm9sbERpdi5jbGFzc0xpc3QuYWRkKFwiZGMtc2Nyb2xsLWNvbnRhaW5lclwiKTtcclxuICAgICAgICB0aGlzLiNlbGVtZW50LmFwcGVuZENoaWxkKHRoaXMuI3Njcm9sbERpdik7XHJcblxyXG4gICAgICAgIHRoaXMuI2NvbnRlbnREaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xyXG4gICAgICAgIHRoaXMuI2NvbnRlbnREaXYuY2xhc3NMaXN0LmFkZChcImRjLWNvbnRlbnQtY29udGFpbmVyXCIpO1xyXG4gICAgICAgIHRoaXMuI2VsZW1lbnQuYXBwZW5kQ2hpbGQodGhpcy4jY29udGVudERpdik7XHJcblxyXG4gICAgICAgIHRoaXMuI2FpcmNyYWZ0RWRpdG9yID0gbmV3IEFpclVuaXRFZGl0b3IodGhpcy4jc2Nyb2xsRGl2LCB0aGlzLiNjb250ZW50RGl2KTtcclxuICAgIH1cclxuXHJcbiAgICBnZXROYW1lKCkge1xyXG4gICAgICAgIHJldHVybiBcIkRhdGFiYXNlIENvbnRyb2wgUGx1Z2luXCJcclxuICAgIH1cclxuXHJcbiAgICBpbml0aWFsaXplKGFwcDogYW55KSB7XHJcbiAgICAgICAgdGhpcy4jYXBwID0gYXBwO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHZhciBhaXJjcmFmdERhdGFiYXNlID0gdGhpcy4jYXBwPy5nZXRBaXJjcmFmdERhdGFiYXNlKCk7XHJcbiAgICAgICAgaWYgKGFpcmNyYWZ0RGF0YWJhc2UgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aGlzLiNhaXJjcmFmdEVkaXRvci5zZXREYXRhYmFzZShhaXJjcmFmdERhdGFiYXNlKTtcclxuICAgICAgICAgICAgdGhpcy4jYWlyY3JhZnRFZGl0b3Iuc2hvdygpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0RWxlbWVudCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy4jZWxlbWVudDtcclxuICAgIH1cclxuXHJcbiAgICB0b2dnbGUoYm9vbD86IGJvb2xlYW4pIHtcclxuICAgICAgICB0aGlzLmdldEVsZW1lbnQoKS5jbGFzc0xpc3QudG9nZ2xlKFwiaGlkZVwiLCBib29sKTtcclxuICAgIH1cclxufSIsImltcG9ydCB7IERhdGFiYXNlTWFuYWdlclBsdWdpbiB9IGZyb20gXCIuL2RhdGFiYXNlbWFuYWdlcnBsdWdpblwiO1xyXG5cclxuZ2xvYmFsVGhpcy5nZXRPbHltcHVzUGx1Z2luID0gKCkgPT4ge1xyXG4gICAgcmV0dXJuIG5ldyBEYXRhYmFzZU1hbmFnZXJQbHVnaW4oKTtcclxufSIsImltcG9ydCB7IFVuaXRCbHVlcHJpbnQgfSBmcm9tIFwiaW50ZXJmYWNlc1wiO1xyXG5pbXBvcnQgeyBVbml0RGF0YWJhc2UgfSBmcm9tIFwidW5pdC9kYXRhYmFzZXMvdW5pdGRhdGFiYXNlXCI7XHJcblxyXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgVW5pdEVkaXRvciB7XHJcbiAgICBkYXRhYmFzZTogVW5pdERhdGFiYXNlIHwgbnVsbCA9IG51bGw7XHJcbiAgICBzY3JvbGxEaXY6IEhUTUxFbGVtZW50O1xyXG4gICAgY29udGVudERpdjogSFRNTEVsZW1lbnQ7XHJcblxyXG4gICAgY29uc3RydWN0b3Ioc2Nyb2xsRGl2OiBIVE1MRWxlbWVudCwgY29udGVudERpdjogSFRNTEVsZW1lbnQpIHtcclxuICAgICAgICB0aGlzLnNjcm9sbERpdiA9IHNjcm9sbERpdjtcclxuICAgICAgICB0aGlzLmNvbnRlbnREaXYgPSBjb250ZW50RGl2O1xyXG4gICAgfVxyXG5cclxuICAgIHNldERhdGFiYXNlKGRhdGFiYXNlOiBhbnkpIHtcclxuICAgICAgICB0aGlzLmRhdGFiYXNlID0gZGF0YWJhc2U7XHJcbiAgICB9XHJcblxyXG4gICAgc2hvdygpIHtcclxuICAgICAgICBpZiAodGhpcy5kYXRhYmFzZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICB2YXIgYmx1ZXByaW50czoge1trZXk6IHN0cmluZ106IFVuaXRCbHVlcHJpbnR9ID0gdGhpcy5kYXRhYmFzZS5nZXRCbHVlcHJpbnRzKCk7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gYmx1ZXByaW50cykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbERpdi5hcHBlbmRDaGlsZChkaXYpO1xyXG4gICAgICAgICAgICAgICAgZGl2LnRleHRDb250ZW50ID0ga2V5O1xyXG4gICAgICAgICAgICAgICAgZGl2Lm9uY2xpY2sgPSAoKSA9PiB0aGlzLnNldENvbnRlbnQoYmx1ZXByaW50c1trZXldKTtcclxuICAgICAgICAgICAgfSAgICAgIFxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhZGRTdHJpbmdJbnB1dChrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZykge1xyXG4gICAgICAgIHZhciBkdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkdFwiKTtcclxuICAgICAgICB2YXIgZGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGRcIik7XHJcbiAgICAgICAgZHQuaW5uZXJUZXh0ID0ga2V5O1xyXG4gICAgICAgIHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcclxuICAgICAgICBpbnB1dC52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgIGlucHV0LnRleHRDb250ZW50ID0gdmFsdWU7XHJcbiAgICAgICAgZGQuYXBwZW5kQ2hpbGQoaW5wdXQpO1xyXG4gICAgICAgIHRoaXMuY29udGVudERpdi5hcHBlbmRDaGlsZChkdCk7XHJcbiAgICAgICAgdGhpcy5jb250ZW50RGl2LmFwcGVuZENoaWxkKGRkKTtcclxuICAgIH1cclxuXHJcbiAgICBhZGREcm9wZG93bklucHV0KGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBvcHRpb25zOiBzdHJpbmdbXSkge1xyXG4gICAgICAgIHZhciBkdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkdFwiKTtcclxuICAgICAgICB2YXIgZGQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGRcIik7XHJcbiAgICAgICAgZHQuaW5uZXJUZXh0ID0ga2V5O1xyXG4gICAgICAgIHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcclxuICAgICAgICBpbnB1dC52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgIGlucHV0LnRleHRDb250ZW50ID0gdmFsdWU7XHJcbiAgICAgICAgZGQuYXBwZW5kQ2hpbGQoaW5wdXQpO1xyXG4gICAgICAgIHRoaXMuY29udGVudERpdi5hcHBlbmRDaGlsZChkdCk7XHJcbiAgICAgICAgdGhpcy5jb250ZW50RGl2LmFwcGVuZENoaWxkKGRkKTtcclxuICAgIH1cclxuXHJcbiAgICBhYnN0cmFjdCBzZXRDb250ZW50KGJsdWVwcmludDogVW5pdEJsdWVwcmludCk6IHZvaWQ7XHJcbiAgICBcclxufSJdfQ== + +},{"./utils":8}],8:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.addLoadoutsScroll = exports.addBlueprintsScroll = exports.addNewElementInput = exports.addLoadoutItemsEditor = exports.addDropdownInput = exports.addStringInput = void 0; +/** This file contains a set of utility functions that are reused in the various editors and allows to declutter the classes + * + */ +/** Add a string input in the form of String: [ value ] + * + * @param div The HTMLElement that will contain the input + * @param key The key of the input, which will be used as label + * @param value The initial value of the input + * @param type The type of the input, e.g. "Text" or "Number" as per html standard + * @param callback Callback called when the user enters a new value + * @param disabled If true, the input will be disabled and read only + */ +function addStringInput(div, key, value, type, callback, disabled) { + var row = document.createElement("div"); + var dt = document.createElement("dt"); + var dd = document.createElement("dd"); + dt.innerText = key; + var input = document.createElement("input"); + input.value = value; + input.textContent = value; + input.type = type !== null && type !== void 0 ? type : "text"; + input.disabled = disabled !== null && disabled !== void 0 ? disabled : false; + input.onchange = () => callback(input.value); + dd.appendChild(input); + row.appendChild(dt); + row.appendChild(dd); + row.classList.add("input-row"); + div.appendChild(row); +} +exports.addStringInput = addStringInput; +/** Add a dropdown (select) input + * + * @param div The HTMLElement that will contain the input + * @param key The key of the input, which will be used as label + * @param value The initial value of the input + * @param options The dropdown options + */ +function addDropdownInput(div, key, value, options) { + var row = document.createElement("div"); + var dt = document.createElement("dt"); + var dd = document.createElement("dd"); + dt.innerText = key; + var select = document.createElement("select"); + options.forEach((option) => { + var el = document.createElement("option"); + el.value = option; + el.innerText = option; + select.appendChild(el); + }); + select.value = value; + dd.appendChild(select); + row.appendChild(dt); + row.appendChild(dd); + row.classList.add("input-row"); + div.appendChild(row); +} +exports.addDropdownInput = addDropdownInput; +/** Create a loadout items editor. This editor allows to add or remove loadout items, as well as changing their name and quantity + * + * @param div The HTMLElement that will contain the editor + * @param loadout The loadout to edit + */ +function addLoadoutItemsEditor(div, loadout) { + var itemsEl = document.createElement("div"); + itemsEl.classList.add("dm-scroll-container", "dm-items-container"); + /* Create a row for each loadout item to allow and change the name and quantity of the item itself */ + loadout.items.forEach((item, index) => { + var rowDiv = document.createElement("div"); + var nameLabel = document.createElement("label"); + nameLabel.innerText = "Name"; + rowDiv.appendChild(nameLabel); + var nameInput = document.createElement("input"); + rowDiv.appendChild(nameInput); + nameInput.textContent = item.name; + nameInput.value = item.name; + nameInput.onchange = () => { loadout.items[index].name = nameInput.value; }; + var quantityLabel = document.createElement("label"); + quantityLabel.innerText = "Quantity"; + rowDiv.appendChild(quantityLabel); + var quantityInput = document.createElement("input"); + rowDiv.appendChild(quantityInput); + quantityInput.textContent = String(item.quantity); + quantityInput.value = String(item.quantity); + quantityInput.type = "number"; + quantityInput.step = "1"; + quantityInput.onchange = () => { loadout.items[index].quantity = parseInt(quantityInput.value); }; + /* This button allows to remove the item */ + var button = document.createElement("button"); + button.innerText = "X"; + button.onclick = () => { + loadout.items.splice(index, 1); + div.dispatchEvent(new Event("refresh")); + }; + rowDiv.appendChild(button); + itemsEl.appendChild(rowDiv); + }); + div.appendChild(itemsEl); + /* Button to add a new item to the loadout */ + var inputDiv = document.createElement("div"); + inputDiv.classList.add("dm-new-item-input"); + var button = document.createElement("button"); + button.innerText = "Add"; + inputDiv.appendChild(button); + div.appendChild(inputDiv); + button.addEventListener("click", (ev) => { + loadout === null || loadout === void 0 ? void 0 : loadout.items.push({ + name: "", + quantity: 1 + }); + div.dispatchEvent(new Event("refresh")); + }); +} +exports.addLoadoutItemsEditor = addLoadoutItemsEditor; +/** Add a input and button to create a new element in a list. It uses a generic callback to actually add the element. + * + * @param div The HTMLElement that will contain the input and button + * @param callback Callback called when the user clicks on "Add" + */ +function addNewElementInput(div, callback) { + var inputDiv = document.createElement("div"); + inputDiv.classList.add("dm-new-element-input"); + var input = document.createElement("input"); + inputDiv.appendChild(input); + var button = document.createElement("button"); + button.innerText = "Add"; + button.addEventListener("click", (ev) => callback(ev, input)); + inputDiv.appendChild(button); + div.appendChild(inputDiv); +} +exports.addNewElementInput = addNewElementInput; +/** Add a scrollable list of blueprints + * + * @param div The HTMLElement that will contain the list + * @param database The database that will be used to fill the list of blueprints + * @param callback Callback called when the user clicks on one of the elements + */ +function addBlueprintsScroll(div, database, callback) { + var scrollDiv = document.createElement("div"); + scrollDiv.classList.add("dm-scroll-container"); + if (database !== null) { + var blueprints = database.blueprints; + for (let key in Object.keys(blueprints).sort()) { + var rowDiv = document.createElement("div"); + scrollDiv.appendChild(rowDiv); + var text = document.createElement("label"); + text.textContent = key; + text.onclick = () => callback(key); + rowDiv.appendChild(text); + /* This button allows to remove an element from the list. It requires a refresh. */ + var button = document.createElement("button"); + button.innerText = "X"; + button.onclick = () => { + delete blueprints[key]; + div.dispatchEvent(new Event("refresh")); + }; + rowDiv.appendChild(button); + } + } + div.appendChild(scrollDiv); +} +exports.addBlueprintsScroll = addBlueprintsScroll; +/** Add a scrollable list of loadouts + * + * @param div The HTMLElement that will contain the list + * @param loadouts The loadouts that will be used to fill the list + * @param callback Callback called when the user clicks on one of the elements + */ +function addLoadoutsScroll(div, loadouts, callback) { + var loadoutsEl = document.createElement("div"); + loadoutsEl.classList.add("dm-scroll-container", "dm-loadout-container"); + loadouts.forEach((loadout, index) => { + var rowDiv = document.createElement("div"); + loadoutsEl.appendChild(rowDiv); + var text = document.createElement("label"); + text.textContent = loadout.name; + text.onclick = () => { callback(loadout); }; + rowDiv.appendChild(text); + /* The "Empty loadout" can not be removed */ + if (loadout.name !== "Empty loadout") { + /* This button allows to remove an element from the list. It requires a refresh. */ + var button = document.createElement("button"); + button.innerText = "X"; + button.onclick = () => { + loadouts.splice(index, 1); + div.dispatchEvent(new Event("refresh")); + }; + rowDiv.appendChild(button); + } + }); + div.appendChild(loadoutsEl); +} +exports.addLoadoutsScroll = addLoadoutsScroll; + +},{}]},{},[4]); diff --git a/client/plugins/databasemanager/src/utils.ts b/client/plugins/databasemanager/src/utils.ts index 47035467..7a70edf2 100644 --- a/client/plugins/databasemanager/src/utils.ts +++ b/client/plugins/databasemanager/src/utils.ts @@ -68,6 +68,7 @@ export function addLoadoutItemsEditor(div: HTMLElement, loadout: LoadoutBlueprin itemsEl.classList.add("dm-scroll-container", "dm-items-container"); /* Create a row for each loadout item to allow and change the name and quantity of the item itself */ + loadout.items.sort((a: LoadoutItemBlueprint, b: LoadoutItemBlueprint) => a.name.localeCompare(b.name, undefined, {sensitivity: 'base'})); loadout.items.forEach((item: LoadoutItemBlueprint, index: number) => { var rowDiv = document.createElement("div"); @@ -154,7 +155,7 @@ export function addBlueprintsScroll(div: HTMLElement, database: {blueprints: {[k if (database !== null) { var blueprints: {[key: string]: UnitBlueprint} = database.blueprints; - for (let key in blueprints) { + for (let key of Object.keys(blueprints).sort((a, b) => a.localeCompare(b, undefined, {sensitivity: 'base'}))) { var rowDiv = document.createElement("div"); scrollDiv.appendChild(rowDiv); @@ -186,6 +187,7 @@ export function addLoadoutsScroll(div: HTMLElement, loadouts: LoadoutBlueprint[] var loadoutsEl = document.createElement("div"); loadoutsEl.classList.add("dm-scroll-container", "dm-loadout-container") + loadouts.sort((a: LoadoutBlueprint, b: LoadoutBlueprint) => a.name.localeCompare(b.name, undefined, {sensitivity: 'base'})); loadouts.forEach((loadout: LoadoutBlueprint, index: number) => { var rowDiv = document.createElement("div"); loadoutsEl.appendChild(rowDiv); diff --git a/client/plugins/databasemanager/style.css b/client/plugins/databasemanager/style.css index 3c1a6b24..47a50446 100644 --- a/client/plugins/databasemanager/style.css +++ b/client/plugins/databasemanager/style.css @@ -71,7 +71,7 @@ } .dm-content-container:nth-of-type(1) { - width: 200px; + width: 300px; } .dm-content-container:nth-of-type(2) { diff --git a/client/public/databases/units/aircraftdatabase.json b/client/public/databases/units/aircraftdatabase.json index 6258e44f..f9d20a95 100644 --- a/client/public/databases/units/aircraftdatabase.json +++ b/client/public/databases/units/aircraftdatabase.json @@ -3,7 +3,7 @@ "name": "A-10C_2", "coalition": "blue", "era": "Late Cold War", - "label": "A-10C Warthog test", + "label": "A-10C Warthog", "shortLabel": "10", "loadouts": [ { diff --git a/client/public/databases/units/groundunitdatabase.json b/client/public/databases/units/groundunitdatabase.json index c83e7534..5263040d 100644 --- a/client/public/databases/units/groundunitdatabase.json +++ b/client/public/databases/units/groundunitdatabase.json @@ -6230,7 +6230,7 @@ "era": "", "label": "SPAAA LC with ZU-23", "shortLabel": "SPAAA LC with ZU-23", - "type": "AirDefence", + "type": "AAA", "enabled": true, "liveries": {} }, @@ -6510,7 +6510,7 @@ "era": "", "label": "AAA Bofors 40mm", "shortLabel": "AAA Bofors 40mm", - "type": "AirDefence", + "type": "AAA", "enabled": true, "liveries": {} }, @@ -6620,9 +6620,11 @@ "era": "", "label": "AAA 8,8cm Flak 18", "shortLabel": "AAA 8,8cm Flak 18", - "type": "AirDefence", + "type": "AAA", "enabled": true, - "liveries": {} + "liveries": {}, + "aimTime": 20, + "shotsToFire": 1 }, "Pz_IV_H": { "name": "Pz_IV_H", @@ -6904,46 +6906,6 @@ "enabled": true, "liveries": {} }, - "flak30": { - "name": "flak30", - "coalition": "", - "era": "", - "label": "AAA Flak 38 20mm", - "shortLabel": "AAA Flak 38 20mm", - "type": "AirDefence", - "enabled": true, - "liveries": {} - }, - "flak36": { - "name": "flak36", - "coalition": "", - "era": "", - "label": "AAA 8,8cm Flak 36", - "shortLabel": "AAA 8,8cm Flak 36", - "type": "AirDefence", - "enabled": true, - "liveries": {} - }, - "flak37": { - "name": "flak37", - "coalition": "", - "era": "", - "label": "AAA 8,8cm Flak 37", - "shortLabel": "AAA 8,8cm Flak 37", - "type": "AirDefence", - "enabled": true, - "liveries": {} - }, - "flak38": { - "name": "flak38", - "coalition": "", - "era": "", - "label": "AAA Flak-Vierling 38 Quad 20mm", - "shortLabel": "AAA Flak-Vierling 38 Quad 20mm", - "type": "AirDefence", - "enabled": true, - "liveries": {} - }, "KDO_Mod40": { "name": "KDO_Mod40", "coalition": "", @@ -6960,7 +6922,7 @@ "era": "", "label": "SL Flakscheinwerfer 37", "shortLabel": "SL Flakscheinwerfer 37", - "type": "AirDefence", + "type": "AAA", "enabled": true, "liveries": {} }, @@ -6970,7 +6932,7 @@ "era": "", "label": "Maschinensatz 33 Gen", "shortLabel": "Maschinensatz 33 Gen", - "type": "AirDefence", + "type": "AAA", "enabled": true, "liveries": {} }, @@ -7024,16 +6986,6 @@ "enabled": true, "liveries": {} }, - "flak41": { - "name": "flak41", - "coalition": "", - "era": "", - "label": "AAA 8,8cm Flak 41", - "shortLabel": "AAA 8,8cm Flak 41", - "type": "AirDefence", - "enabled": true, - "liveries": {} - }, "v1_launcher": { "name": "v1_launcher", "coalition": "", @@ -7160,7 +7112,7 @@ "era": "", "label": "AAA QF 3.7\"", "shortLabel": "AAA QF 3.7\"", - "type": "AirDefence", + "type": "AAA", "enabled": true, "liveries": {} }, @@ -7270,7 +7222,7 @@ "era": "", "label": "AAA M45 Quadmount HB 12.7mm", "shortLabel": "AAA M45 Quadmount HB 12.7mm", - "type": "AirDefence", + "type": "AAA", "enabled": true, "liveries": {} }, @@ -7280,7 +7232,7 @@ "era": "", "label": "AAA M1 37mm", "shortLabel": "AAA M1 37mm", - "type": "AirDefence", + "type": "AAA", "enabled": true, "liveries": {} }, diff --git a/client/src/constants/constants.ts b/client/src/constants/constants.ts index e952cd0b..4d3006cc 100644 --- a/client/src/constants/constants.ts +++ b/client/src/constants/constants.ts @@ -151,11 +151,12 @@ export const visibilityControlsTooltips: string[] = ["Toggle human players visib export const IADSTypes = ["AAA", "MANPADS", "SAM Site", "Radar"]; export const IADSDensities: {[key: string]: number}= {"AAA": 0.8, "MANPADS": 0.3, "SAM Site": 0.1, "Radar": 0.05}; -export const SHOW_CONTACT_LINES = "Show unit contact lines"; export const HIDE_GROUP_MEMBERS = "Hide group members when zoomed out"; export const SHOW_UNIT_LABELS = "Show unit labels"; -export const SHOW_UNIT_PATHS = "Show unit paths"; -export const SHOW_UNIT_TARGETS = "Show unit targets"; +export const SHOW_UNIT_CONTACTS = "Show selected units contact lines"; +export const SHOW_UNITS_RINGS = "Show selected units threat range rings"; +export const SHOW_UNIT_PATHS = "Show selected unit paths"; +export const SHOW_UNIT_TARGETS = "Show selected unit targets"; export enum DataIndexes { startOfData = 0, diff --git a/client/src/map/map.ts b/client/src/map/map.ts index c20d95b1..fa1367a8 100644 --- a/client/src/map/map.ts +++ b/client/src/map/map.ts @@ -12,7 +12,7 @@ import { DestinationPreviewMarker } from "./markers/destinationpreviewmarker"; import { TemporaryUnitMarker } from "./markers/temporaryunitmarker"; import { ClickableMiniMap } from "./clickableminimap"; import { SVGInjector } from '@tanem/svg-injector' -import { mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_CONTACT_LINES, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants"; +import { mapLayers, mapBounds, minimapBoundaries, IDLE, COALITIONAREA_DRAW_POLYGON, visibilityControls, visibilityControlsTooltips, MOVE_UNIT, SHOW_UNIT_CONTACTS, HIDE_GROUP_MEMBERS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, visibilityControlsTypes, SHOW_UNIT_LABELS } from "../constants/constants"; import { TargetMarker } from "./markers/targetmarker"; import { CoalitionArea } from "./coalitionarea/coalitionarea"; import { CoalitionAreaContextMenu } from "../contextmenus/coalitionareacontextmenu"; @@ -209,7 +209,7 @@ export class Map extends L.Map { document.querySelector("#unit-visibility-control")?.append(...this.#optionButtons["visibility"]); /* Create the checkboxes to select the advanced visibility options */ - this.addVisibilityOption(SHOW_CONTACT_LINES, false); + this.addVisibilityOption(SHOW_UNIT_CONTACTS, false); this.addVisibilityOption(HIDE_GROUP_MEMBERS, true); this.addVisibilityOption(SHOW_UNIT_PATHS, true); this.addVisibilityOption(SHOW_UNIT_TARGETS, true); @@ -528,39 +528,38 @@ export class Map extends L.Map { } this.hideMapContextMenu(); - if (!this.#shiftKey) { - if (this.#state === IDLE) { - if (this.#state == IDLE) { - this.showMapContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); - var clickedCoalitionArea = null; + if (this.#state === IDLE) { + if (this.#state == IDLE) { + this.showMapContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng); + var clickedCoalitionArea = null; - /* Coalition areas are ordered in the #coalitionAreas array according to their zindex. Select the upper one */ - for (let coalitionArea of this.#coalitionAreas) { - if (coalitionArea.getBounds().contains(e.latlng)) { - if (coalitionArea.getSelected()) - clickedCoalitionArea = coalitionArea; - else - this.getMapContextMenu().setCoalitionArea(coalitionArea); - } + /* Coalition areas are ordered in the #coalitionAreas array according to their zindex. Select the upper one */ + for (let coalitionArea of this.#coalitionAreas) { + if (coalitionArea.getBounds().contains(e.latlng)) { + if (coalitionArea.getSelected()) + clickedCoalitionArea = coalitionArea; + else + this.getMapContextMenu().setCoalitionArea(coalitionArea); } - if (clickedCoalitionArea) - this.showCoalitionAreaContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng, clickedCoalitionArea); } - } - else if (this.#state === MOVE_UNIT) { - if (!e.originalEvent.ctrlKey) { - getApp().getUnitsManager().selectedUnitsClearDestinations(); - } - getApp().getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation) - - this.#destinationGroupRotation = 0; - this.#destinationRotationCenter = null; - this.#computeDestinationRotation = false; - } - else { - this.setState(IDLE); + if (clickedCoalitionArea) + this.showCoalitionAreaContextMenu(e.originalEvent.x, e.originalEvent.y, e.latlng, clickedCoalitionArea); } } + else if (this.#state === MOVE_UNIT) { + if (!e.originalEvent.ctrlKey) { + getApp().getUnitsManager().selectedUnitsClearDestinations(); + } + getApp().getUnitsManager().selectedUnitsAddDestination(this.#computeDestinationRotation && this.#destinationRotationCenter != null ? this.#destinationRotationCenter : e.latlng, this.#shiftKey, this.#destinationGroupRotation) + + this.#destinationGroupRotation = 0; + this.#destinationRotationCenter = null; + this.#computeDestinationRotation = false; + } + else { + this.setState(IDLE); + } + } #onSelectionStart(e: any) { @@ -593,12 +592,12 @@ export class Map extends L.Map { } this.#longPressTimer = window.setTimeout(() => { - if (e.originalEvent.button != 2 || e.originalEvent.ctrlKey || e.originalEvent.shiftKey) - return; - this.hideMapContextMenu(); this.#longPressHandled = true; + if (e.originalEvent.button != 2 || e.originalEvent.ctrlKey || e.originalEvent.shiftKey) + return; + var options: { [key: string]: { text: string, tooltip: string } } = {}; const selectedUnits = getApp().getUnitsManager().getSelectedUnits(); const selectedUnitTypes = getApp().getUnitsManager().getSelectedUnitsCategories(); diff --git a/client/src/other/utils.ts b/client/src/other/utils.ts index 655c5374..6bb3041d 100644 --- a/client/src/other/utils.ts +++ b/client/src/other/utils.ts @@ -204,10 +204,16 @@ export function mToNm(m: number) { return m * 0.000539957; } +export function nmToM(nm: number) { + return nm / 0.000539957; +} + + export function nmToFt(nm: number) { return nm * 6076.12; } + export function polyContains(latlng: LatLng, polygon: Polygon) { var poly = polygon.toGeoJSON(); return turf.inside(turf.point([latlng.lng, latlng.lat]), poly); diff --git a/client/src/unit/unit.ts b/client/src/unit/unit.ts index 6cfb1897..93b8dfe5 100644 --- a/client/src/unit/unit.ts +++ b/client/src/unit/unit.ts @@ -1,11 +1,11 @@ -import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point } from 'leaflet'; +import { Marker, LatLng, Polyline, Icon, DivIcon, CircleMarker, Map, Point, Circle } from 'leaflet'; import { getApp } from '..'; -import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad, ftToM, getGroundElevation, coalitionToEnum } from '../other/utils'; +import { enumToCoalition, enumToEmissioNCountermeasure, getMarkerCategoryByName, enumToROE, enumToReactionToThreat, enumToState, getUnitDatabaseByCategory, mToFt, msToKnots, rad2deg, bearing, deg2rad, ftToM, getGroundElevation, coalitionToEnum, nmToFt, nmToM } from '../other/utils'; 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_CONTACT_LINES, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants'; +import { DLINK, DataIndexes, GAME_MASTER, HIDE_GROUP_MEMBERS, IDLE, IRST, MOVE_UNIT, OPTIC, RADAR, ROEs, RWR, SHOW_UNIT_CONTACTS, SHOW_UNITS_RINGS, SHOW_UNIT_PATHS, SHOW_UNIT_TARGETS, VISUAL, emissionsCountermeasures, reactionsToThreat, states } from '../constants/constants'; import { DataExtractor } from '../server/dataextractor'; import { groundUnitDatabase } from './databases/groundunitdatabase'; import { navyUnitDatabase } from './databases/navyunitdatabase'; @@ -86,7 +86,8 @@ export class Unit extends CustomMarker { #waitingForDoubleClick: boolean = false; #pathMarkers: Marker[] = []; #pathPolyline: Polyline; - #contactsPolylines: Polyline[]; + #contactsPolylines: Polyline[] = []; + #rangeRingCircles: Circle[] = []; #miniMapMarker: CircleMarker | null = null; #targetPositionMarker: TargetMarker; #targetPositionPolyline: Polyline; @@ -148,7 +149,6 @@ export class Unit extends CustomMarker { this.#pathPolyline = new Polyline([], { color: '#2d3e50', weight: 3, opacity: 0.5, smoothFactor: 1 }); this.#pathPolyline.addTo(getApp().getMap()); - this.#contactsPolylines = []; this.#targetPositionMarker = new TargetMarker(new LatLng(0, 0)); this.#targetPositionPolyline = new Polyline([], { color: '#FF0000', weight: 3, opacity: 0.5, smoothFactor: 1 }); @@ -251,6 +251,7 @@ export class Unit extends CustomMarker { drawLines() { this.#drawPath(); this.#drawContacts(); + this.#drawRanges(); this.#drawTarget(); } @@ -1093,7 +1094,7 @@ export class Unit extends CustomMarker { #drawContacts() { this.#clearContacts(); - if (getApp().getMap().getVisibilityOptions()[SHOW_CONTACT_LINES]) { + if (getApp().getMap().getVisibilityOptions()[SHOW_UNIT_CONTACTS]) { for (let index in this.#contacts) { var contactData = this.#contacts[index]; var contact: Unit | Weapon | null; @@ -1133,12 +1134,31 @@ export class Unit extends CustomMarker { } } + #drawRanges() { + this.#clearRanges(); + if (getApp().getMap().getVisibilityOptions()[SHOW_UNITS_RINGS]) { + var engagementRange = this.getDatabase()?.getByName(this.getName())?.engagementRange; + var acquisitionRange = this.getDatabase()?.getByName(this.getName())?.acquisitionRange + if (engagementRange) { + var rangeCircle = new Circle(this.getPosition(), { radius: nmToM(engagementRange), color: "#FF0000", weight: 3, opacity: 1 }); + rangeCircle.addTo(getApp().getMap()); + this.#rangeRingCircles.push(rangeCircle) + } + } + } + #clearContacts() { for (let index in this.#contactsPolylines) { getApp().getMap().removeLayer(this.#contactsPolylines[index]) } } + #clearRanges() { + for (let index in this.#rangeRingCircles) { + getApp().getMap().removeLayer(this.#rangeRingCircles[index]) + } + } + #drawTarget() { if (this.#targetPosition.lat != 0 && this.#targetPosition.lng != 0 && getApp().getMap().getVisibilityOptions()[SHOW_UNIT_PATHS]) { this.#drawTargetPosition(this.#targetPosition); diff --git a/scripts/python/addRanges.py b/scripts/python/addRanges.py new file mode 100644 index 00000000..b63a1699 --- /dev/null +++ b/scripts/python/addRanges.py @@ -0,0 +1,63 @@ +import sys +import json +import inspect +import difflib +from slpp import slpp as lua + +SEARCH_FOLDER = "D:\\Eagle Dynamics\\DCS World OpenBeta" + +sys.path.append("..\..\..\dcs-master\dcs-master") + +from dcs.weapons_data import Weapons +from dcs.planes import * +from dcs.helicopters import * + +# The database file on which to operate is the first standard argument of the call +if len(sys.argv) > 1: + if (sys.argv[1] == "aircraft"): + filename = '..\\..\\client\\public\\databases\\units\\aircraftdatabase.json' + elif (sys.argv[1] == "helicopter"): + filename = '..\\..\\client\\public\\databases\\units\\helicopterdatabase.json' + elif (sys.argv[1] == "groundunit"): + filename = '..\\..\\client\\public\\databases\\units\\groundunitdatabase.json' + elif (sys.argv[1] == "navyunit"): + filename = '..\\..\\client\\public\\databases\\units\\navyunitdatabase.json' + + # Loads the database + with open(filename) as f: + database = json.load(f) + for unit_name in database: + database[unit_name]["enabled"] = True + + # Loop on all the units in the database + for unit_name in database: + try: + # Get the pydcs Python class for the unit + if (sys.argv[1] == "aircraft"): + unitmap = plane_map + elif (sys.argv[1] == "helicopter"): + unitmap = helicopter_map + elif (sys.argv[1] == "groundunit"): + unitmap = vehicle_map + elif (sys.argv[1] == "navyunit"): + unitmap = ship_map + lowercase_keys = [key.lower() for key in unitmap.keys()] + res = difflib.get_close_matches(unit_name.lower(), lowercase_keys) + if len(res) > 0: + found_name = list(unitmap.keys())[lowercase_keys.index(res[0])] + cls = unitmap[found_name] + else: + print(f"Warning, could not find {unit_name} in classes list. Skipping...") + continue + + except Exception as e: + print(f"Could not find data for aircraft of type {unit_name}: {e}, skipping...") + + # Dump everything in the database + with open(filename, "w") as f: + json.dump(database, f, indent=2) + + # Done! + print("Done!") + + \ No newline at end of file diff --git a/scripts/python/temp.py b/scripts/python/temp.py deleted file mode 100644 index c7303c11..00000000 --- a/scripts/python/temp.py +++ /dev/null @@ -1,15 +0,0 @@ -import json -import difflib - -countries = ['USA', 'GRG', 'GER', 'DZA', 'FRA', 'CAN', 'AUS', 'UKR', 'ITA', 'GRC', 'SPN', 'RUS', 'NETH', 'DEN', 'TUR', 'UK', 'BEL', 'ISR', 'NOR', 'JPN', 'ARE', 'QAT', 'IND', 'SAU', 'EGY', 'KOR', 'HND', 'CHL', 'BLUE', 'AUSAF', 'RED', 'VNM', 'SVK', 'SDN', 'GDR', 'JOR', 'PER', 'CHN', 'IDN', 'PHL', 'BOL', 'MAR', 'YEM', 'KWT', 'SUI', 'GHA', 'CYP', 'BHR', 'YUG', 'CZE', 'KAZ', 'AUT', 'HUN', 'MYS', 'ROU', 'THA', 'LBN', 'FIN', 'PRT', 'OMN', 'MEX', 'IRQ', 'BRA', 'SWE', 'NZG', 'CUB', 'INS', 'RSO', 'RSA', 'HRV', 'ABH', 'ARG', 'LBY', 'PRK', 'VEN', 'TUN', 'IRN', 'ETH', 'BLR', 'SUN', 'BGR', 'PAK', 'NGA', 'POL', 'SVN', 'SYR', 'SRB', 'UN', 'RSI', 'SPA', 'ECU', '', 'USAF', 'hide', 'EGP', 'LIB'] - -with open('C:\\Users\\dpass\\Documents\\DCSOlympus\\client\\public\\images\\nations\\codes.json', "r") as f: - codes = json.load(f) - - for country in countries: - keys = difflib.get_close_matches(country, codes.keys(), cutoff=.35) - if len(keys) > 0: - codes[keys[0]]["liveryCodes"].append(country) - -with open('C:\\Users\\dpass\\Documents\\DCSOlympus\\client\\public\\images\\nations\\codes.json', "w") as f: - json.dump(codes, f) \ No newline at end of file diff --git a/src/core/src/groundunit.cpp b/src/core/src/groundunit.cpp index a84a69c3..4220129a 100644 --- a/src/core/src/groundunit.cpp +++ b/src/core/src/groundunit.cpp @@ -74,9 +74,11 @@ void GroundUnit::setState(unsigned char newState) break; } case State::SCENIC_AAA: { + setTargetPosition(Coords(NULL)); break; } case State::MISS_ON_PURPOSE: { + setTargetPosition(Coords(NULL)); break; } default: