mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
293 lines
9.5 KiB
TypeScript
293 lines
9.5 KiB
TypeScript
import { getApp } from "../../olympusapp";
|
|
import { GAME_MASTER } from "../../constants/constants";
|
|
import { UnitBlueprint } from "../../interfaces";
|
|
import { UnitDatabaseLoadedEvent } from "../../events";
|
|
|
|
export class UnitDatabase {
|
|
blueprints: { [key: string]: UnitBlueprint } = {};
|
|
|
|
constructor() {}
|
|
|
|
load(url: string, category?: string) {
|
|
if (url !== "") {
|
|
var xhr = new XMLHttpRequest();
|
|
xhr.open("GET", url, true);
|
|
xhr.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0");
|
|
xhr.responseType = "json";
|
|
xhr.onload = () => {
|
|
var status = xhr.status;
|
|
if (status === 200) {
|
|
const newBlueprints = xhr.response as { [key: string]: UnitBlueprint };
|
|
for (let unit in newBlueprints) {
|
|
if (!newBlueprints[unit].category) {
|
|
if (category) newBlueprints[unit].category = category
|
|
else console.warn(`No category provided for ${unit}`)
|
|
}
|
|
}
|
|
this.blueprints = { ...this.blueprints, ...newBlueprints };
|
|
UnitDatabaseLoadedEvent.dispatch();
|
|
} else {
|
|
console.error(`Error retrieving database from ${url}`);
|
|
}
|
|
};
|
|
xhr.send();
|
|
}
|
|
}
|
|
|
|
/* Gets a specific blueprint by name */
|
|
getByName(name: string) {
|
|
if (name in this.blueprints) return this.blueprints[name];
|
|
return null;
|
|
}
|
|
|
|
/* Gets a specific blueprint by label */
|
|
getByLabel(label: string) {
|
|
for (let unit in this.blueprints) {
|
|
if (this.blueprints[unit].label === label) return this.blueprints[unit];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getBlueprints(includeDisabled: boolean = false) {
|
|
if (!getApp()) return [];
|
|
|
|
if (
|
|
getApp().getMissionManager().getCommandModeOptions().commandMode == GAME_MASTER ||
|
|
!getApp().getMissionManager().getCommandModeOptions().restrictSpawns
|
|
) {
|
|
var filteredBlueprints: { [key: string]: UnitBlueprint } = {};
|
|
for (let unit in this.blueprints) {
|
|
const blueprint = this.blueprints[unit];
|
|
if (blueprint.enabled || includeDisabled) filteredBlueprints[unit] = blueprint;
|
|
}
|
|
return Object.values(filteredBlueprints);
|
|
} else {
|
|
var filteredBlueprints: { [key: string]: UnitBlueprint } = {};
|
|
for (let unit in this.blueprints) {
|
|
const blueprint = this.blueprints[unit];
|
|
if (
|
|
(blueprint.enabled || includeDisabled) &&
|
|
this.getSpawnPointsByName(blueprint.name) <= getApp().getMissionManager().getAvailableSpawnPoints() &&
|
|
getApp().getMissionManager().getCommandModeOptions().eras.includes(blueprint.era) &&
|
|
(!getApp().getMissionManager().getCommandModeOptions().restrictToCoalition ||
|
|
blueprint.coalition === getApp().getMissionManager().getCommandedCoalition() ||
|
|
blueprint.coalition === undefined)
|
|
) {
|
|
filteredBlueprints[unit] = blueprint;
|
|
}
|
|
}
|
|
return Object.values(filteredBlueprints);
|
|
}
|
|
}
|
|
|
|
/* Returns a list of all possible roles in a database */
|
|
getRoles(unitFilter?: (unit: UnitBlueprint) => boolean) {
|
|
var roles: string[] = [];
|
|
var filteredBlueprints = this.getBlueprints();
|
|
for (let unit of filteredBlueprints) {
|
|
if (typeof unitFilter === "function" && !unitFilter(unit)) continue;
|
|
var loadouts = unit.loadouts;
|
|
if (loadouts) {
|
|
for (let loadout of loadouts) {
|
|
for (let role of loadout.roles) {
|
|
if (role !== "" && !roles.includes(role)) roles.push(role);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return roles;
|
|
}
|
|
|
|
/* Returns a list of all possible types in a database */
|
|
getTypes(unitFilter?: (unit: UnitBlueprint) => boolean) {
|
|
var filteredBlueprints = this.getBlueprints();
|
|
var types: string[] = [];
|
|
for (let unit of filteredBlueprints) {
|
|
if (typeof unitFilter === "function" && !unitFilter(unit)) continue;
|
|
var type = unit.type;
|
|
if (type && type !== "" && !types.includes(type)) types.push(type);
|
|
}
|
|
return types;
|
|
}
|
|
|
|
/* Returns a list of all possible eras in a database */
|
|
getEras(unitFilter?: (unit: UnitBlueprint) => boolean) {
|
|
var filteredBlueprints = this.getBlueprints();
|
|
var eras: string[] = [];
|
|
for (let unit of filteredBlueprints) {
|
|
if (typeof unitFilter === "function" && !unitFilter(unit)) continue;
|
|
var era = unit.era;
|
|
if (era && era !== "" && !eras.includes(era)) eras.push(era);
|
|
}
|
|
return eras;
|
|
}
|
|
|
|
/* Get all blueprints by range */
|
|
getByRange(range: string, unitFilter?: (unit: UnitBlueprint) => boolean) {
|
|
var filteredBlueprints = this.getBlueprints();
|
|
var unitswithrange: UnitBlueprint[] = [];
|
|
var minRange = 0;
|
|
var maxRange = 0;
|
|
|
|
if (range === "Short range") {
|
|
minRange = 0;
|
|
maxRange = 10000;
|
|
} else if (range === "Medium range") {
|
|
minRange = 10000;
|
|
maxRange = 100000;
|
|
} else {
|
|
minRange = 100000;
|
|
maxRange = 999999;
|
|
}
|
|
|
|
for (let unit of filteredBlueprints) {
|
|
if (typeof unitFilter === "function" && !unitFilter(unit)) continue;
|
|
var engagementRange = unit.engagementRange;
|
|
if (engagementRange !== undefined) {
|
|
if (engagementRange >= minRange && engagementRange < maxRange) {
|
|
unitswithrange.push(unit);
|
|
}
|
|
}
|
|
}
|
|
return unitswithrange;
|
|
}
|
|
|
|
/* Get all blueprints by type */
|
|
getByType(type: string, unitFilter?: (unit: UnitBlueprint) => boolean) {
|
|
var filteredBlueprints = this.getBlueprints();
|
|
var units: UnitBlueprint[] = [];
|
|
for (let unit of filteredBlueprints) {
|
|
if (typeof unitFilter === "function" && !unitFilter(unit)) continue;
|
|
if (unit.type === type) {
|
|
units.push(unit);
|
|
}
|
|
}
|
|
return units;
|
|
}
|
|
|
|
/* Get all blueprints by role */
|
|
getByRole(role: string, unitFilter?: (unit: UnitBlueprint) => boolean) {
|
|
var filteredBlueprints = this.getBlueprints();
|
|
var units: UnitBlueprint[] = [];
|
|
for (let unit of filteredBlueprints) {
|
|
if (typeof unitFilter === "function" && !unitFilter(unit)) continue;
|
|
var loadouts = unit.loadouts;
|
|
if (loadouts) {
|
|
for (let loadout of loadouts) {
|
|
if (loadout.roles.includes(role) || loadout.roles.includes(role.toLowerCase())) {
|
|
units.push(unit);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return units;
|
|
}
|
|
|
|
/* Get the names of all the loadouts for a specific unit and for a specific role */
|
|
getLoadoutNamesByRole(name: string, role: string) {
|
|
var filteredBlueprints = this.getBlueprints();
|
|
var loadoutsByRole: string[] = [];
|
|
var loadouts = filteredBlueprints[name].loadouts;
|
|
if (loadouts) {
|
|
for (let loadout of loadouts) {
|
|
if (loadout.roles.includes(role) || loadout.roles.includes("")) {
|
|
loadoutsByRole.push(loadout.name);
|
|
}
|
|
}
|
|
}
|
|
return loadoutsByRole;
|
|
}
|
|
|
|
/* Get the livery names for a specific unit */
|
|
getLiveryNamesByName(name: string) {
|
|
var liveries = this.blueprints[name].liveries;
|
|
if (liveries !== undefined) return Object.values(liveries);
|
|
else return [];
|
|
}
|
|
|
|
/* Get the loadout content from the unit name and loadout name */
|
|
getLoadoutByName(name: string, loadoutName: string) {
|
|
var loadouts = this.blueprints[name].loadouts;
|
|
if (loadouts) {
|
|
for (let loadout of loadouts) {
|
|
if (loadout.name === loadoutName) return loadout;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
getSpawnPointsByName(name: string) {
|
|
return this.getByLabel(name)?.cost ?? 10;
|
|
}
|
|
|
|
getUnkownUnit(name: string): UnitBlueprint {
|
|
return {
|
|
name: name,
|
|
category: "aircraft",
|
|
enabled: true,
|
|
coalition: "neutral",
|
|
era: "N/A",
|
|
label: name,
|
|
shortLabel: "",
|
|
};
|
|
}
|
|
|
|
|
|
getRandomUnit(
|
|
options: {
|
|
type?: string;
|
|
role?: string;
|
|
ranges?: string[];
|
|
eras?: string[];
|
|
coalition?: string;
|
|
}
|
|
) {
|
|
/* Start from all the unit blueprints in the database */
|
|
var unitBlueprints = this.getBlueprints();
|
|
|
|
/* If a specific type or role is provided, use only the blueprints of that type or role */
|
|
if (options.type && options.role) {
|
|
console.error("Can't create random unit if both type and role are provided. Either create by type or by role.");
|
|
return null;
|
|
}
|
|
|
|
if (options.type) {
|
|
unitBlueprints = this.getByType(options.type);
|
|
} else if (options.role) {
|
|
unitBlueprints = this.getByType(options.role);
|
|
}
|
|
|
|
/* Keep only the units that have a range included in the requested values */
|
|
if (options.ranges) {
|
|
unitBlueprints = unitBlueprints.filter((unitBlueprint: UnitBlueprint) => {
|
|
var rangeType = "";
|
|
var range = unitBlueprint.acquisitionRange;
|
|
if (range !== undefined) {
|
|
if (range >= 0 && range < 10000) rangeType = "Short range";
|
|
else if (range >= 10000 && range < 100000) rangeType = "Medium range";
|
|
else if (range >= 100000 && range < 999999) rangeType = "Long range";
|
|
}
|
|
return options.ranges?.includes(rangeType);
|
|
});
|
|
}
|
|
|
|
/* Keep only the units that have an era included in the requested values */
|
|
if (options.eras) {
|
|
unitBlueprints = unitBlueprints.filter((unitBlueprint: UnitBlueprint) => {
|
|
return unitBlueprint.era ? options.eras?.includes(unitBlueprint.era) : true;
|
|
});
|
|
}
|
|
|
|
/* Keep only the units that have the correct coalition, if selected */
|
|
if (options.coalition) {
|
|
unitBlueprints = unitBlueprints.filter((unitBlueprint: UnitBlueprint) => {
|
|
return unitBlueprint.coalition && unitBlueprint.coalition !== "" ? options.coalition === unitBlueprint.coalition : true;
|
|
});
|
|
}
|
|
|
|
var index = Math.floor(Math.random() * unitBlueprints.length);
|
|
return unitBlueprints[index];
|
|
}
|
|
}
|