UNPKG

@fboes/aerofly-custom-missions

Version:

Builder for Aerofly FS4 Custom Missions Files

238 lines (212 loc) 7.48 kB
import { AeroflyVector3Float, AeroflyMatrix3Float, Convert } from "../node/Convert.js"; import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js"; export type AeroflySettingsFlightConfiguration = | "Keep" | "ColdAndDark" | "BeforeStart" // TODO | "Parking" | "OnGround" | "Takeoff" | "Cruise" | "ShortFinal" | "Final"; export class AeroflySettingsFlight { gear: number = 1; /** * Throttle is supposed to be set to * - 0 on "ColdAndDark", "BeforeStart", "Parking", "OnGround" and "Takeoff" configuration * - 0.4 on "ShortFinal" and "Final" configuration * - 0.6 on "Cruise" configuration */ throttle: number = 0; /** * Flaps is supposed to be set to 1 on "ShortFinal" and "Final" configurations */ flaps: number = 0; configuration: AeroflySettingsFlightConfiguration = "Parking"; onGround: boolean = true; /** * Airport is supposed to be set on any configurations but "Cruise" and "Keep" */ airport: string; /** * Runway is supposed to be set on "Takeoff", "ShortFinal" and "Final" configurations */ runway: string; constructor( public longitude: number, public latitude: number, public altitude_meter: number, public heading_degree: number, public speed_kts: number = 0, { gear = 1, throttle = 0, flaps = 0, configuration = "OnGround", onGround = true, airport = "", runway = "", }: Partial<AeroflySettingsFlight> = {}, ) { this.configuration = configuration; this.setConfiguration(configuration); if (gear !== undefined) { this.gear = gear; } if (throttle !== undefined) { this.throttle = throttle; } if (flaps !== undefined) { this.flaps = flaps; } if (onGround !== undefined) { this.onGround = onGround; } this.airport = airport; this.runway = runway; } static createInFeet( longitude: number, latitude: number, altitude_ft: number, heading_degree: number, speed_kts: number = 0, additionalAttributes: Partial<AeroflySettingsFlight> = {}, ): AeroflySettingsFlight { return new AeroflySettingsFlight( longitude, latitude, Convert.convertFeetToMeter(altitude_ft), heading_degree, speed_kts, additionalAttributes, ); } static createInCartesian( position: AeroflyVector3Float, velocity: AeroflyVector3Float, orientation: AeroflyMatrix3Float, additionalAttributes: Partial<AeroflySettingsFlight> = {}, ): AeroflySettingsFlight { const flight = new AeroflySettingsFlight(0, 0, 0, 0, 0, additionalAttributes); flight.position = position; flight.velocity = velocity; flight.orientation = orientation; return flight; } /** * @param {AeroflySettingsFlightConfiguration} configuration which will set other parameters like `gear`, `flaps` and `throttle` consistently */ setConfiguration(configuration: AeroflySettingsFlightConfiguration) { this.configuration = configuration; if (configuration === "Keep") { return; } this.onGround = configuration === "ColdAndDark" || configuration === "BeforeStart" || configuration === "Parking" || configuration === "OnGround" || configuration === "Takeoff"; this.gear = configuration === "Cruise" ? 0 : 1; this.flaps = configuration === "Final" || configuration === "ShortFinal" ? 1 : 0; switch (configuration) { case "ShortFinal": case "Final": this.throttle = 0.4; break; case "Cruise": this.throttle = 0.6; break; default: this.throttle = 0; this.speed_kts = 0; break; } } /** * @returns {AeroflyVector3Float} position vector to use in Aerofly FS4's `main.mcf` */ get position(): AeroflyVector3Float { return Convert.convertLonLatToVector(this.longitude, this.latitude, this.altitude_meter); } set position(position: AeroflyVector3Float) { const { longitude, latitude, altitude_meter } = Convert.convertVectorToLonLat(position); this.longitude = longitude; this.latitude = latitude; this.altitude_meter = altitude_meter; } /** * @returns {AeroflyVector3Float} velocity vector to use in Aerofly FS4's `main.mcf` */ get velocity(): AeroflyVector3Float { const speed = this.speed_ms; const heading_rad = this.heading_degree * (Math.PI / 180); return [Math.cos(heading_rad) * speed, Math.sin(heading_rad) * speed, 0]; } set velocity(velocity: AeroflyVector3Float) { // TODO: implement setting velocity vector and updating speed accordingly this.speed_ms = 0; } get orientation(): AeroflyMatrix3Float { return Convert.convertDegreeToMatrix(this.heading_degree); } set orientation(orientation: AeroflyMatrix3Float) { this.heading_degree = Convert.convertMatrixToDegree(orientation); } /** * @returns {number} altitude in feet AGL */ get altitude_ft(): number { return Convert.convertMeterToFeet(this.altitude_meter); } set altitude_ft(altitude_ft: number) { this.altitude_meter = Convert.convertFeetToMeter(altitude_ft); } /** * @returns {number} speed in meters per seconds */ get speed_ms(): number { return this.speed_kts * 0.514444; } set speed_ms(speed_ms: number) { this.speed_kts = speed_ms / 0.514444; } getElement(): AeroflyConfigurationNode { return new AeroflyConfigurationNode("tmsettings_flight", "flight_setting") .appendChild( "vector3_float64", "position", this.position, `Lon ${this.longitude.toFixed(6)}, Lat ${this.latitude.toFixed(6)}, ${Math.ceil(this.altitude_ft)} ft`, ) .appendChild("vector3_float64", "velocity", this.velocity, `${Math.round(this.speed_kts)} kts`) .appendChild( "matrix3_float64", "orientation", this.orientation, `${Math.round(this.heading_degree)}° heading`, ) .appendChild("float64", "gear", this.gear) .appendChild("float64", "throttle", this.throttle) .appendChild("float64", "flaps", this.flaps) .appendChild("flight_configuration", "configuration", this.configuration) .appendChild("bool", "on_ground", this.onGround) .appendChild("string8u", "airport", this.airport) .appendChild("string8u", "runway", this.runway); } toJSON() { return { ...this, altitude_meter: undefined, altitude_ft: this.altitude_ft, }; } /** * @returns {string} to use in Aerofly FS4's `main.mcf` */ toString(): string { return this.getElement().toString(); } }