@fboes/aerofly-custom-missions 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +1 -4
- package/dist/dto/AeroflyLocalizedText.js +24 -0
- package/dist/dto/AeroflyMission.js +83 -0
- package/dist/dto/AeroflyMission.test.js +4 -3
- package/dist/dto/AeroflyMissionCheckpoint.js +52 -0
- package/dist/dto/AeroflyMissionConditions.js +25 -4
- package/dist/dto/AeroflyMissionConditionsCloud.js +8 -0
- package/dist/dto/AeroflyMissionTargetPlane.js +20 -0
- package/dist/dto/AeroflyMissionsList.js +4 -0
- package/dist/dto-flight/AeroflyFlight.js +51 -1
- package/dist/dto-flight/AeroflyFlight.test.js +8 -3
- package/dist/dto-flight/AeroflyNavRouteAirports.js +5 -0
- package/dist/dto-flight/AeroflyNavRouteBase.js +20 -0
- package/dist/dto-flight/AeroflyNavRouteRunway.js +13 -0
- package/dist/dto-flight/AeroflyNavRouteTransition.js +17 -0
- package/dist/dto-flight/AeroflyNavRouteWaypoint.js +16 -0
- package/dist/dto-flight/AeroflyNavigationConfig.js +19 -3
- package/dist/dto-flight/AeroflySettingsAircraft.js +16 -0
- package/dist/dto-flight/AeroflySettingsCloud.js +8 -0
- package/dist/dto-flight/AeroflySettingsFlight.js +27 -14
- package/dist/dto-flight/AeroflySettingsFuelLoad.js +18 -0
- package/dist/dto-flight/AeroflySettingsWind.js +16 -0
- package/dist/dto-flight/AeroflyTimeUtc.js +5 -0
- package/dist/node/AeroflyConfigurationNode.js +7 -6
- package/docs/custom_missions_user.json +65 -65
- package/docs/flight.json +9 -7
- package/package.json +5 -5
- package/src/dto/AeroflyMission.test.ts +7 -3
- package/src/dto-flight/AeroflyFlight.test.ts +9 -3
- package/src/dto-flight/AeroflyFlight.ts +16 -0
- package/src/dto-flight/AeroflyNavRouteAirports.ts +1 -1
- package/src/dto-flight/AeroflyNavRouteBase.ts +1 -1
- package/src/dto-flight/AeroflyNavRouteRunway.ts +2 -2
- package/src/dto-flight/AeroflyNavRouteTransition.ts +2 -2
- package/src/dto-flight/AeroflyNavRouteWaypoint.ts +1 -1
- package/src/dto-flight/AeroflyNavigationConfig.ts +19 -3
- package/src/dto-flight/AeroflySettingsFlight.ts +1 -1
- package/src/node/Convert.test.ts +1 -1
- package/tsconfig.json +4 -3
- package/types/dto-flight/AeroflyFlight.d.ts +18 -1
- package/types/dto-flight/AeroflyFlight.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteAirports.d.ts +1 -1
- package/types/dto-flight/AeroflyNavRouteAirports.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteBase.d.ts +1 -1
- package/types/dto-flight/AeroflyNavRouteBase.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteRunway.d.ts +2 -2
- package/types/dto-flight/AeroflyNavRouteRunway.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteTransition.d.ts +2 -2
- package/types/dto-flight/AeroflyNavRouteTransition.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteWaypoint.d.ts +1 -1
- package/types/dto-flight/AeroflyNavRouteWaypoint.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavigationConfig.d.ts +12 -2
- package/types/dto-flight/AeroflyNavigationConfig.d.ts.map +1 -1
- package/types/dto-flight/AeroflySettingsFlight.d.ts +1 -1
- package/types/dto-flight/AeroflySettingsFlight.d.ts.map +1 -1
- package/docs/flight-generator-prompt.md +0 -91
- package/docs/flight-mcf.md +0 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
This changelog documents all notable changes to the Aerofly Custom Missions project. Each version entry includes a list of changes, with the most recent version at the top.
|
|
4
4
|
|
|
5
|
+
## [1.12.0] - 2026-07-08
|
|
6
|
+
|
|
7
|
+
- Added unofficial `_cruiseSpeed` property to `AeroflyNavigationConfig`
|
|
8
|
+
|
|
9
|
+
## [1.11.0] - 2026-06-18
|
|
10
|
+
|
|
11
|
+
- Added unofficial `_missionTitle` and `_missionBriefing` property to `AeroflyFlight`
|
|
12
|
+
|
|
5
13
|
## [1.10.0] - 2026-05-28
|
|
6
14
|
|
|
7
15
|
- Changed turbulence formula
|
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
[Aerofly Flight Simulator 4](https://www.aerofly.com/) has a custom missions file `custom_missions_user.tmc` with a very unique format. To help you build this custom missions file, this JavaScript / TypeScript library offers Data Objects to create this file programmatically.
|
|
6
6
|
|
|
7
|
-
This simulator also defines flight plans and settings in the `main.mcf`, which is automatically loaded on simulator startup. This library contains a proposal for a `flight.mcf`, which is a stripped-down version of the `main.mcf` which only contains all information necessary for flight set-up.
|
|
7
|
+
This simulator also defines flight plans and settings in the `main.mcf`, which is automatically loaded on simulator startup. This library contains a proposal for a `flight.mcf`, which is a stripped-down version of the `main.mcf` which only contains all information necessary for flight set-up.
|
|
8
8
|
|
|
9
9
|
This library is intended to work in modern browsers as well as [Node.js](https://nodejs.org/en).
|
|
10
10
|
|
|
@@ -54,9 +54,6 @@ import {
|
|
|
54
54
|
|
|
55
55
|
You might want to enable TypeScript type checking by adding `// @ts-check` as your first line in your scripts.
|
|
56
56
|
|
|
57
|
-
> [!NOTE]
|
|
58
|
-
> This library also contains classes for building the yet unsupported `flight.mcf`. Please refer to the code on how to use this. See [the documentation for `flight.mcf`](./docs/flight-mcf.md).
|
|
59
|
-
|
|
60
57
|
### Basic idea
|
|
61
58
|
|
|
62
59
|
All objects are basic structures needed for the missions list. The constructors tell you which properties are required, and will start with sensible defaults for all other properties.
|
|
@@ -4,6 +4,30 @@ import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
|
4
4
|
* A translation for the mission title and description.
|
|
5
5
|
*/
|
|
6
6
|
export class AeroflyLocalizedText {
|
|
7
|
+
/**
|
|
8
|
+
* @property {string} language ISO 639-1 like
|
|
9
|
+
* - br
|
|
10
|
+
* - cn
|
|
11
|
+
* - de
|
|
12
|
+
* - es
|
|
13
|
+
* - fr
|
|
14
|
+
* - id
|
|
15
|
+
* - it
|
|
16
|
+
* - jp
|
|
17
|
+
* - kr
|
|
18
|
+
* - pl
|
|
19
|
+
* - sv
|
|
20
|
+
* - tr
|
|
21
|
+
*/
|
|
22
|
+
language;
|
|
23
|
+
/**
|
|
24
|
+
* @property {string} title of this flight plan
|
|
25
|
+
*/
|
|
26
|
+
title;
|
|
27
|
+
/**
|
|
28
|
+
* @property {string} description text, mission briefing, etc
|
|
29
|
+
*/
|
|
30
|
+
description;
|
|
7
31
|
/**
|
|
8
32
|
* @param {string} language ISO 639-1 like
|
|
9
33
|
* - br
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { AeroflyConfigurationNode, AeroflyConfigurationNodeComment } from "../node/AeroflyConfigurationNode.js";
|
|
2
|
+
import { AeroflyLocalizedText } from "./AeroflyLocalizedText.js";
|
|
3
|
+
import { AeroflyMissionCheckpoint } from "./AeroflyMissionCheckpoint.js";
|
|
2
4
|
import { AeroflyMissionConditions } from "./AeroflyMissionConditions.js";
|
|
5
|
+
import { AeroflyMissionTargetPlane } from "./AeroflyMissionTargetPlane.js";
|
|
3
6
|
export const feetPerMeter = 3.28084;
|
|
4
7
|
export const meterPerStatuteMile = 1609.344;
|
|
5
8
|
/**
|
|
@@ -11,6 +14,86 @@ export const meterPerStatuteMile = 1609.344;
|
|
|
11
14
|
* for this file via the `toString()` method.
|
|
12
15
|
*/
|
|
13
16
|
export class AeroflyMission {
|
|
17
|
+
/**
|
|
18
|
+
* @property {?string} tutorialName will create a link to a tutorial page at https://www.aerofly.com/aircraft-tutorials/
|
|
19
|
+
*/
|
|
20
|
+
tutorialName;
|
|
21
|
+
/**
|
|
22
|
+
* @property {string} title of this flight plan
|
|
23
|
+
*/
|
|
24
|
+
title;
|
|
25
|
+
/**
|
|
26
|
+
* @property {string} description text, mission briefing, etc
|
|
27
|
+
*/
|
|
28
|
+
description;
|
|
29
|
+
/**
|
|
30
|
+
* @property {AeroflyLocalizedText[]} localizedTexts for title and description
|
|
31
|
+
*/
|
|
32
|
+
localizedTexts;
|
|
33
|
+
/**
|
|
34
|
+
* @property {string[]} tags free-text tags
|
|
35
|
+
*/
|
|
36
|
+
tags;
|
|
37
|
+
/**
|
|
38
|
+
* @property {?boolean} isFeatured makes this mission pop up in "Challenges"
|
|
39
|
+
*/
|
|
40
|
+
isFeatured;
|
|
41
|
+
/**
|
|
42
|
+
* @property {?number} difficulty values between 0.00 and 2.00 have been encountered, but they seem to be without limit
|
|
43
|
+
*/
|
|
44
|
+
difficulty;
|
|
45
|
+
/**
|
|
46
|
+
* @property {"cold_and_dark"|"before_start"|"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"|"pushback"} flightSetting of aircraft, like "taxi", "cruise"
|
|
47
|
+
*/
|
|
48
|
+
flightSetting;
|
|
49
|
+
/**
|
|
50
|
+
* @property {object} aircraft for this mission
|
|
51
|
+
*/
|
|
52
|
+
aircraft;
|
|
53
|
+
/**
|
|
54
|
+
* @property {?number} fuelMass in kg
|
|
55
|
+
*/
|
|
56
|
+
fuelMass;
|
|
57
|
+
/**
|
|
58
|
+
* @property {?number} payloadMass in kg
|
|
59
|
+
*/
|
|
60
|
+
payloadMass;
|
|
61
|
+
/**
|
|
62
|
+
* @property {string} callsign of aircraft, uppercased
|
|
63
|
+
*/
|
|
64
|
+
callsign;
|
|
65
|
+
/**
|
|
66
|
+
* @property {object} origin position of aircraft, as well as name of starting airport. Position does not have match airport.
|
|
67
|
+
*/
|
|
68
|
+
origin;
|
|
69
|
+
/**
|
|
70
|
+
* @property {object} destination position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
71
|
+
*/
|
|
72
|
+
destination;
|
|
73
|
+
/**
|
|
74
|
+
* @property {?number} distance in meters
|
|
75
|
+
*/
|
|
76
|
+
distance;
|
|
77
|
+
/**
|
|
78
|
+
* @property {?number} duration in seconds
|
|
79
|
+
*/
|
|
80
|
+
duration;
|
|
81
|
+
/**
|
|
82
|
+
* @property {?boolean} isScheduled marks this flight as "Scheduled flight".
|
|
83
|
+
*/
|
|
84
|
+
isScheduled;
|
|
85
|
+
/**
|
|
86
|
+
* @property {?AeroflyMissionTargetPlane} finish as finish condition
|
|
87
|
+
*/
|
|
88
|
+
finish;
|
|
89
|
+
/**
|
|
90
|
+
* @property {AeroflyMissionConditions} conditions like time and weather for mission
|
|
91
|
+
*/
|
|
92
|
+
conditions;
|
|
93
|
+
/**
|
|
94
|
+
* @property {AeroflyMissionConditions} checkpoints form the actual flight plan
|
|
95
|
+
*/
|
|
96
|
+
checkpoints;
|
|
14
97
|
/**
|
|
15
98
|
* @param {string} title of this flight plan
|
|
16
99
|
* @param {object} [additionalAttributes] allows to set additional attributes on creation
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AeroflyMission } from "./AeroflyMission.js";
|
|
2
2
|
import { strict as assert } from "node:assert";
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
4
5
|
import { assertIncludes, assertValidAeroflyStructure } from "../check/TestHelpers.js";
|
|
5
6
|
import { describe, it } from "node:test";
|
|
6
7
|
import { AeroflyLocalizedText } from "./AeroflyLocalizedText.js";
|
|
@@ -166,9 +167,9 @@ Landeübung #1: Concord / Buchanan Field`, `Es ist ein böiger, klarer früher M
|
|
|
166
167
|
//console.log(missionList.getElement().toXmlString());
|
|
167
168
|
const file = new AeroflyMissionsList([mission]);
|
|
168
169
|
const fileContent = file.toString();
|
|
169
|
-
fs.writeFileSync("docs/custom_missions_user.tmc", fileContent);
|
|
170
|
+
fs.writeFileSync(path.join(import.meta.dirname, "../..", "docs/custom_missions_user.tmc"), fileContent);
|
|
170
171
|
const xmlContent = file.toXmlString();
|
|
171
|
-
fs.writeFileSync("docs/custom_missions_user.xml", xmlContent);
|
|
172
|
-
fs.writeFileSync("docs/custom_missions_user.json", JSON.stringify(file, null, 2));
|
|
172
|
+
fs.writeFileSync(path.join(import.meta.dirname, "../..", "docs/custom_missions_user.xml"), xmlContent);
|
|
173
|
+
fs.writeFileSync(path.join(import.meta.dirname, "../..", "docs/custom_missions_user.json"), JSON.stringify(file, null, 2));
|
|
173
174
|
});
|
|
174
175
|
});
|
|
@@ -9,6 +9,58 @@ import { feetPerMeter } from "./AeroflyMission.js";
|
|
|
9
9
|
* for this file via the `toString()` method.
|
|
10
10
|
*/
|
|
11
11
|
export class AeroflyMissionCheckpoint {
|
|
12
|
+
/**
|
|
13
|
+
* @property {"origin"|"departure_runway"|"departure"|"waypoint"|"arrival"|"approach"|"destination_runway"|"destination"} type of checkpoint, like "departure_runway"
|
|
14
|
+
*/
|
|
15
|
+
type;
|
|
16
|
+
/**
|
|
17
|
+
* @property {string} name ICAO code for airport, runway designator, navaid
|
|
18
|
+
* designator, fix name, or custom name
|
|
19
|
+
*/
|
|
20
|
+
name;
|
|
21
|
+
/**
|
|
22
|
+
* @property {number} longitude easting, using the World Geodetic
|
|
23
|
+
* System 1984 (WGS 84) [WGS84] datum, with longitude and latitude units
|
|
24
|
+
* of decimal degrees; [-180,180]
|
|
25
|
+
*/
|
|
26
|
+
longitude;
|
|
27
|
+
/**
|
|
28
|
+
* @property {number} latitude northing, using the World Geodetic
|
|
29
|
+
* System 1984 (WGS 84) [WGS84] datum, with longitude and latitude units
|
|
30
|
+
* of decimal degrees; -90..90
|
|
31
|
+
*/
|
|
32
|
+
latitude;
|
|
33
|
+
/**
|
|
34
|
+
* @property {number} altitude The height in meters above or below the WGS
|
|
35
|
+
* 84 reference ellipsoid
|
|
36
|
+
*/
|
|
37
|
+
altitude;
|
|
38
|
+
/**
|
|
39
|
+
* @property {?boolean} altitudeConstraint The altitude given in `altitude`
|
|
40
|
+
* will be interpreted as mandatory flight plan altitude instead of
|
|
41
|
+
* suggestion.
|
|
42
|
+
*/
|
|
43
|
+
altitudeConstraint;
|
|
44
|
+
/**
|
|
45
|
+
* @property {?number} direction of runway, in degree
|
|
46
|
+
*/
|
|
47
|
+
direction;
|
|
48
|
+
/**
|
|
49
|
+
* @property {?number} slope of runway
|
|
50
|
+
*/
|
|
51
|
+
slope;
|
|
52
|
+
/**
|
|
53
|
+
* @property {?number} length of runway, in meters
|
|
54
|
+
*/
|
|
55
|
+
length;
|
|
56
|
+
/**
|
|
57
|
+
* @property {?number} frequency of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
|
|
58
|
+
*/
|
|
59
|
+
frequency;
|
|
60
|
+
/**
|
|
61
|
+
* @property {?boolean} flyOver if waypoint is meant to be flown over
|
|
62
|
+
*/
|
|
63
|
+
flyOver;
|
|
12
64
|
/**
|
|
13
65
|
* @param {string} name ICAO code for airport, runway designator, navaid
|
|
14
66
|
* designator, fix name, or custom name
|
|
@@ -10,6 +10,31 @@ import { AeroflyMissionConditionsCloud } from "./AeroflyMissionConditionsCloud.j
|
|
|
10
10
|
* for this file via the `toString()` method.
|
|
11
11
|
*/
|
|
12
12
|
export class AeroflyMissionConditions {
|
|
13
|
+
/**
|
|
14
|
+
* @property {Date} time of flight plan. Relevant is the UTC part, so
|
|
15
|
+
* consider setting this date in UTC.
|
|
16
|
+
*/
|
|
17
|
+
time;
|
|
18
|
+
/**
|
|
19
|
+
* @property {object} wind state
|
|
20
|
+
*/
|
|
21
|
+
wind;
|
|
22
|
+
/**
|
|
23
|
+
* @property {number} turbulenceStrength normalized value [0,1]
|
|
24
|
+
*/
|
|
25
|
+
turbulenceStrength;
|
|
26
|
+
/**
|
|
27
|
+
* @property {number} thermalStrength normalized value [0,1]
|
|
28
|
+
*/
|
|
29
|
+
thermalStrength;
|
|
30
|
+
/**
|
|
31
|
+
* @property {number} visibility in meters
|
|
32
|
+
*/
|
|
33
|
+
visibility;
|
|
34
|
+
/**
|
|
35
|
+
* @property {AeroflyMissionConditionsCloud[]} clouds for the whole flight
|
|
36
|
+
*/
|
|
37
|
+
clouds = [];
|
|
13
38
|
/**
|
|
14
39
|
* @param {object} additionalAttributes allows to set additional attributes on creation
|
|
15
40
|
* @param {Date} [additionalAttributes.time] of flight plan. Relevant is the UTC part, so
|
|
@@ -27,10 +52,6 @@ export class AeroflyMissionConditions {
|
|
|
27
52
|
speed: 0,
|
|
28
53
|
gusts: 0,
|
|
29
54
|
}, turbulenceStrength = 0, thermalStrength = 0, visibility = 25_000, visibility_sm = 0, temperature = 0, clouds = [], } = {}) {
|
|
30
|
-
/**
|
|
31
|
-
* @property {AeroflyMissionConditionsCloud[]} clouds for the whole flight
|
|
32
|
-
*/
|
|
33
|
-
this.clouds = [];
|
|
34
55
|
this.time = time;
|
|
35
56
|
this.wind = wind;
|
|
36
57
|
this.turbulenceStrength = turbulenceStrength;
|
|
@@ -9,6 +9,14 @@ import { feetPerMeter } from "./AeroflyMission.js";
|
|
|
9
9
|
* for this file via the `toString()` method.
|
|
10
10
|
*/
|
|
11
11
|
export class AeroflyMissionConditionsCloud {
|
|
12
|
+
/**
|
|
13
|
+
* @property {number} cover normalized value [0,1]
|
|
14
|
+
*/
|
|
15
|
+
cover;
|
|
16
|
+
/**
|
|
17
|
+
* @property {number} base altitude in meters AGL
|
|
18
|
+
*/
|
|
19
|
+
base;
|
|
12
20
|
/**
|
|
13
21
|
* @param {number} cover normalized value [0,1]
|
|
14
22
|
* @param {number} base altitude in meters AGL
|
|
@@ -4,6 +4,26 @@ import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
|
4
4
|
* A target plane which the aircraft needs to cross.
|
|
5
5
|
*/
|
|
6
6
|
export class AeroflyMissionTargetPlane {
|
|
7
|
+
/**
|
|
8
|
+
* @property {number} longitude easting, using the World Geodetic
|
|
9
|
+
* System 1984 (WGS 84) [WGS84] datum, with longitude and latitude units
|
|
10
|
+
* of decimal degrees; [-180,180]
|
|
11
|
+
*/
|
|
12
|
+
longitude;
|
|
13
|
+
/**
|
|
14
|
+
* @property {number} latitude northing, using the World Geodetic
|
|
15
|
+
* System 1984 (WGS 84) [WGS84] datum, with longitude and latitude units
|
|
16
|
+
* of decimal degrees; -90..90
|
|
17
|
+
*/
|
|
18
|
+
latitude;
|
|
19
|
+
/**
|
|
20
|
+
* @property {number} dir in degree
|
|
21
|
+
*/
|
|
22
|
+
dir;
|
|
23
|
+
/**
|
|
24
|
+
* @property {string} name of property
|
|
25
|
+
*/
|
|
26
|
+
name;
|
|
7
27
|
/**
|
|
8
28
|
*
|
|
9
29
|
* @param {number} longitude easting, using the World Geodetic
|
|
@@ -9,6 +9,10 @@ import { AeroflyMission } from "./AeroflyMission.js";
|
|
|
9
9
|
* for this file via the `toString()` method.
|
|
10
10
|
*/
|
|
11
11
|
export class AeroflyMissionsList {
|
|
12
|
+
/**
|
|
13
|
+
* @property {AeroflyMission[]} missions in this mission list
|
|
14
|
+
*/
|
|
15
|
+
missions;
|
|
12
16
|
/**
|
|
13
17
|
* @param {AeroflyMission[]} missions in this mission list
|
|
14
18
|
*/
|
|
@@ -1,7 +1,53 @@
|
|
|
1
|
+
import { AeroflyNavigationConfig } from "./AeroflyNavigationConfig.js";
|
|
1
2
|
import { AeroflySettingsAircraft } from "./AeroflySettingsAircraft.js";
|
|
3
|
+
import { AeroflySettingsCloud } from "./AeroflySettingsCloud.js";
|
|
4
|
+
import { AeroflySettingsFlight } from "./AeroflySettingsFlight.js";
|
|
2
5
|
import { AeroflySettingsFuelLoad } from "./AeroflySettingsFuelLoad.js";
|
|
6
|
+
import { AeroflyTimeUtc } from "./AeroflyTimeUtc.js";
|
|
7
|
+
import { AeroflySettingsWind } from "./AeroflySettingsWind.js";
|
|
3
8
|
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
4
9
|
export class AeroflyFlight {
|
|
10
|
+
/**
|
|
11
|
+
* @property {AeroflySettingsAircraft} aircraft settings for the mission
|
|
12
|
+
*/
|
|
13
|
+
aircraft;
|
|
14
|
+
/**
|
|
15
|
+
* @property {AeroflySettingsFlight} flight settings for the mission
|
|
16
|
+
*/
|
|
17
|
+
flightSetting;
|
|
18
|
+
/**
|
|
19
|
+
* @property {AeroflySettingsFuelLoad} fuelLoadSetting fuel load settings for the mission
|
|
20
|
+
*/
|
|
21
|
+
fuelLoadSetting;
|
|
22
|
+
/**
|
|
23
|
+
* @property {AeroflyTimeUtc} timeUtc time settings for the mission
|
|
24
|
+
*/
|
|
25
|
+
timeUtc;
|
|
26
|
+
/**
|
|
27
|
+
* @property {AeroflySettingsWind} wind settings for the mission
|
|
28
|
+
*/
|
|
29
|
+
wind;
|
|
30
|
+
/**
|
|
31
|
+
* @property {AeroflySettingsCloud[]} clouds cloud settings for the mission.
|
|
32
|
+
* Aerofly supports up to 3 cloud layers, so only the first 3 elements of this array will be used.
|
|
33
|
+
*/
|
|
34
|
+
clouds;
|
|
35
|
+
/**
|
|
36
|
+
* @property {AeroflyNavigationConfig} navigation navigation settings for the mission
|
|
37
|
+
*/
|
|
38
|
+
navigation;
|
|
39
|
+
/**
|
|
40
|
+
* @property {number} visibility_meter visibility in meter, 9999 for unlimited visibility
|
|
41
|
+
*/
|
|
42
|
+
visibility_meter;
|
|
43
|
+
/**
|
|
44
|
+
* @property {string} _missionTitle unofficial property to store mission title in. For internal use only, will not be exported in MCF / XML.
|
|
45
|
+
*/
|
|
46
|
+
_missionTitle;
|
|
47
|
+
/**
|
|
48
|
+
* @property {string} _missionBriefing unofficial property to store mission briefing in. For internal use only, will not be exported in MCF / XML.
|
|
49
|
+
*/
|
|
50
|
+
_missionBriefing;
|
|
5
51
|
/**
|
|
6
52
|
*
|
|
7
53
|
* @param {AeroflySettingsAircraft} aircraft settings for the mission
|
|
@@ -15,8 +61,10 @@ export class AeroflyFlight {
|
|
|
15
61
|
* @param {number} [options.visibility_meter] visibility in meter, 9999 for unlimited visibility, default is 9999
|
|
16
62
|
* @param {number} [options.visibility] visibility in normalized value [0,1], where 0 means 0 meter visibility and 1 unlimited visibility, default is 0
|
|
17
63
|
* @param {number} [options.visibility_sm] visibility in statute miles, 10 SM for unlimited visibility, default is 0
|
|
64
|
+
* @param {string} [options._missionTitle] unofficial property to store mission title in. For internal use only, will not be exported in MCF / XML.
|
|
65
|
+
* @param {string} [options._missionBriefing] unofficial property to store mission briefing in. For internal use only, will not be exported in MCF / XML.
|
|
18
66
|
*/
|
|
19
|
-
constructor(aircraft, flightSetting, timeUtc, wind, clouds, navigation, { fuelLoadSetting = new AeroflySettingsFuelLoad(), visibility_meter = 9999, visibility = 0, visibility_sm = 0, } = {}) {
|
|
67
|
+
constructor(aircraft, flightSetting, timeUtc, wind, clouds, navigation, { fuelLoadSetting = new AeroflySettingsFuelLoad(), visibility_meter = 9999, visibility = 0, visibility_sm = 0, _missionTitle = "", _missionBriefing = "", } = {}) {
|
|
20
68
|
this.aircraft = aircraft;
|
|
21
69
|
this.flightSetting = flightSetting;
|
|
22
70
|
this.timeUtc = timeUtc;
|
|
@@ -25,6 +73,8 @@ export class AeroflyFlight {
|
|
|
25
73
|
this.navigation = navigation;
|
|
26
74
|
this.fuelLoadSetting = fuelLoadSetting;
|
|
27
75
|
this.visibility_meter = visibility_meter;
|
|
76
|
+
this._missionTitle = _missionTitle;
|
|
77
|
+
this._missionBriefing = _missionBriefing;
|
|
28
78
|
if (visibility_sm > 0) {
|
|
29
79
|
this.visibility_sm = visibility_sm;
|
|
30
80
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describe, it } from "node:test";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
3
4
|
import { strict as assert } from "node:assert";
|
|
4
5
|
import { assertValidAeroflyStructure } from "../check/TestHelpers.js";
|
|
5
6
|
import { AeroflyFlight } from "./AeroflyFlight.js";
|
|
@@ -58,12 +59,16 @@ describe("AeroflyFlight", () => {
|
|
|
58
59
|
]), {
|
|
59
60
|
fuelLoadSetting: new AeroflySettingsFuelLoad("c172", 80, 90, "Keep"),
|
|
60
61
|
visibility: 0.533333,
|
|
62
|
+
_missionTitle: "Mission title",
|
|
63
|
+
_missionBriefing: "Additional text, which will only be visible internally",
|
|
61
64
|
});
|
|
65
|
+
assert.ok(flight._missionTitle);
|
|
66
|
+
assert.ok(flight._missionBriefing);
|
|
62
67
|
const fileContent = flight.toString();
|
|
63
|
-
fs.writeFileSync("docs/flight.mcf", fileContent);
|
|
68
|
+
fs.writeFileSync(path.join(import.meta.dirname, "../..", "docs/flight.mcf"), fileContent);
|
|
64
69
|
const xmlContent = flight.toXmlString();
|
|
65
|
-
fs.writeFileSync("docs/flight.xml", xmlContent);
|
|
66
|
-
fs.writeFileSync("docs/flight.json", JSON.stringify(flight, null, 2));
|
|
70
|
+
fs.writeFileSync(path.join(import.meta.dirname, "../..", "docs/flight.xml"), xmlContent);
|
|
71
|
+
fs.writeFileSync(path.join(import.meta.dirname, "../..", "docs/flight.json"), JSON.stringify(flight, null, 2));
|
|
67
72
|
assertValidAeroflyStructure(fileContent);
|
|
68
73
|
assert.ok(fileContent.includes("c172"));
|
|
69
74
|
});
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
1
2
|
import { Convert } from "../node/Convert.js";
|
|
2
3
|
import { AeroflyNavRouteBase } from "./AeroflyNavRouteBase.js";
|
|
3
4
|
class AeroflyNavRouteAirport extends AeroflyNavRouteBase {
|
|
5
|
+
/**
|
|
6
|
+
* @property {number | null} elevation in meters, null if not set
|
|
7
|
+
*/
|
|
8
|
+
elevation;
|
|
4
9
|
/**
|
|
5
10
|
* @param {AeroflyNavRouteType} type like "origin", "departure_runway", "departure", "waypoint", "arrival", "approach", "destination_runway" or "destination"
|
|
6
11
|
* @param {string} identifier alphanumeric identifier, e.g. "SEA", "PDX", "RWY16L", "FIX1"
|
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
import { Convert } from "../node/Convert.js";
|
|
2
2
|
import { AeroflyConfigurationNode, AeroflyConfigurationNodeComment } from "../node/AeroflyConfigurationNode.js";
|
|
3
3
|
export class AeroflyNavRouteBase {
|
|
4
|
+
/**
|
|
5
|
+
* @property {AeroflyNavRouteType} type like "origin", "departure_runway", "departure", "waypoint", "arrival", "approach", "destination_runway" or "destination"
|
|
6
|
+
*/
|
|
7
|
+
type;
|
|
8
|
+
/**
|
|
9
|
+
* @property {string} identifier alphanumeric identifier, e.g. "SEA", "PDX", "RWY16L", "FIX1"
|
|
10
|
+
*/
|
|
11
|
+
identifier;
|
|
12
|
+
/**
|
|
13
|
+
* @property {number} longitude WGS84
|
|
14
|
+
*/
|
|
15
|
+
longitude;
|
|
16
|
+
/**
|
|
17
|
+
* @property {number} latitude WGS84
|
|
18
|
+
*/
|
|
19
|
+
latitude;
|
|
20
|
+
/**
|
|
21
|
+
* @property {?bigint} uid unique identifier for the waypoint, must match Aerofly FS internal UID if used in an existing mission, can be null for new waypoints
|
|
22
|
+
*/
|
|
23
|
+
uid;
|
|
4
24
|
/**
|
|
5
25
|
* @param {AeroflyNavRouteType} type like "origin", "departure_runway", "departure", "waypoint", "arrival", "approach", "destination_runway" or "destination"
|
|
6
26
|
* @param {string} identifier alphanumeric identifier, e.g. "SEA", "PDX", "RWY16L", "FIX1"
|
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import { Convert } from "../node/Convert.js";
|
|
2
|
+
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
2
3
|
import { AeroflyNavRouteBase } from "./AeroflyNavRouteBase.js";
|
|
3
4
|
class AeroflyNavRouteRunway extends AeroflyNavRouteBase {
|
|
5
|
+
/**
|
|
6
|
+
* @property {?number} direction_degree runway direction in degrees, null if not set
|
|
7
|
+
*/
|
|
8
|
+
direction_degree;
|
|
9
|
+
/**
|
|
10
|
+
* @property {number | null} elevation in meters, null if not set
|
|
11
|
+
*/
|
|
12
|
+
elevation;
|
|
13
|
+
/**
|
|
14
|
+
* @property {number | null} runwayLength in meters, null if not set
|
|
15
|
+
*/
|
|
16
|
+
runwayLength;
|
|
4
17
|
constructor(type, identifier, longitude, latitude, { direction_degree = null, elevation = null, elevation_ft = null, runwayLength = null, uid = null, } = {}) {
|
|
5
18
|
super(type, identifier, longitude, latitude, { uid });
|
|
6
19
|
this.elevation = elevation;
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
import { Convert } from "../node/Convert.js";
|
|
2
|
+
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
2
3
|
import { AeroflyNavRouteBase } from "./AeroflyNavRouteBase.js";
|
|
3
4
|
class AeroflyNavRouteTransition extends AeroflyNavRouteBase {
|
|
5
|
+
/**
|
|
6
|
+
* @property {string} airport ICAO code of the airport this transition belongs to, e.g. "SEA", "PDX"
|
|
7
|
+
*/
|
|
8
|
+
airport;
|
|
9
|
+
/**
|
|
10
|
+
* @property {string} transition name, e.g. "SID1", "STAR1", "APP1"
|
|
11
|
+
*/
|
|
12
|
+
transition;
|
|
13
|
+
/**
|
|
14
|
+
* @property {?bigint} transitionUid unique identifier for the transition, can be null if not set
|
|
15
|
+
*/
|
|
16
|
+
transitionUid;
|
|
17
|
+
/**
|
|
18
|
+
* @property {?number} elevation in meters, null if not set
|
|
19
|
+
*/
|
|
20
|
+
elevation;
|
|
4
21
|
constructor(type, identifier, airport, options = {}) {
|
|
5
22
|
super(type, identifier, 0, 0, options);
|
|
6
23
|
this.airport = airport;
|
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
import { Convert } from "../node/Convert.js";
|
|
2
|
+
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
2
3
|
import { AeroflyNavRouteBase } from "./AeroflyNavRouteBase.js";
|
|
3
4
|
export class AeroflyNavRouteWaypoint extends AeroflyNavRouteBase {
|
|
5
|
+
identifier;
|
|
6
|
+
longitude;
|
|
7
|
+
latitude;
|
|
8
|
+
/**
|
|
9
|
+
* @property {?number} navaidFrequency if the waypoint is a navaid, its frequency in Hz
|
|
10
|
+
*/
|
|
11
|
+
navaidFrequency;
|
|
12
|
+
/**
|
|
13
|
+
* @property {number | null} altitude in meter, null if not set
|
|
14
|
+
*/
|
|
15
|
+
altitude;
|
|
16
|
+
/**
|
|
17
|
+
* @property {boolean} flyOver if true, the waypoint is meant to be flown over, otherwise it can be used as a fly-by waypoint
|
|
18
|
+
*/
|
|
19
|
+
flyOver;
|
|
4
20
|
/**
|
|
5
21
|
* @param {string} identifier alphanumeric identifier, e.g. "SEA", "PDX", "RWY16L", "FIX1"
|
|
6
22
|
* @param {number} longitude WGS84
|
|
@@ -1,21 +1,37 @@
|
|
|
1
1
|
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
2
2
|
import { Convert } from "../node/Convert.js";
|
|
3
|
+
import { AeroflyNavRouteBase } from "./AeroflyNavRouteBase.js";
|
|
3
4
|
export class AeroflyNavigationConfig {
|
|
5
|
+
/**
|
|
6
|
+
* @property {number} cruiseAltitude in meters
|
|
7
|
+
*/
|
|
8
|
+
cruiseAltitude;
|
|
9
|
+
/**
|
|
10
|
+
* @property {AeroflyNavRouteBase[]} waypoints in order of flight, if used in an array will set the array index
|
|
11
|
+
*/
|
|
12
|
+
waypoints;
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
*/
|
|
16
|
+
_cruiseSpeed_kts;
|
|
4
17
|
/**
|
|
5
18
|
* @param {number} cruiseAltitude in meters
|
|
6
19
|
* @param {AeroflyNavRouteBase[]} waypoints in order of flight, if used in an array will set the array index
|
|
20
|
+
* @param {number|undefined} _cruiseSpeed_kts in knots
|
|
7
21
|
*/
|
|
8
|
-
constructor(cruiseAltitude, waypoints = []) {
|
|
22
|
+
constructor(cruiseAltitude, waypoints = [], _cruiseSpeed_kts = undefined) {
|
|
9
23
|
this.cruiseAltitude = cruiseAltitude;
|
|
10
24
|
this.waypoints = waypoints;
|
|
25
|
+
this._cruiseSpeed_kts = _cruiseSpeed_kts;
|
|
11
26
|
}
|
|
12
27
|
/**
|
|
13
28
|
* @param {number} cruiseAltitude_ft in feet
|
|
14
29
|
* @param {AeroflyNavRouteBase[]} waypoints in order of flight, if used in an array will set the array index
|
|
30
|
+
* @param {number|undefined} _cruiseSpeed_kts in knots
|
|
15
31
|
* @returns {AeroflyNavigationConfig} with cruise altitude converted to meters
|
|
16
32
|
*/
|
|
17
|
-
static createInFeet(cruiseAltitude_ft, waypoints = []) {
|
|
18
|
-
return new AeroflyNavigationConfig(Convert.convertFeetToMeter(cruiseAltitude_ft), waypoints);
|
|
33
|
+
static createInFeet(cruiseAltitude_ft, waypoints = [], _cruiseSpeed_kts = undefined) {
|
|
34
|
+
return new AeroflyNavigationConfig(Convert.convertFeetToMeter(cruiseAltitude_ft), waypoints, _cruiseSpeed_kts);
|
|
19
35
|
}
|
|
20
36
|
/**
|
|
21
37
|
* @returns {number} cruise altitude in feet
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
2
2
|
export class AeroflySettingsAircraft {
|
|
3
|
+
/**
|
|
4
|
+
* @property {string} name of the aircraft as internal Aerofly FS 4 code, e.g. "c172"
|
|
5
|
+
*/
|
|
6
|
+
name;
|
|
7
|
+
/**
|
|
8
|
+
* @property {string} paintscheme of the aircraft as internal Aerofly FS 4 code, e.g. "default"
|
|
9
|
+
*/
|
|
10
|
+
paintscheme;
|
|
11
|
+
/**
|
|
12
|
+
* @property {string[]} options for the aircraft, e.g. ["wheel_chocks", "tie_downs"]
|
|
13
|
+
*/
|
|
14
|
+
options;
|
|
15
|
+
/**
|
|
16
|
+
* @property {boolean} profi if true will set the aircraft to the profi version if available, otherwise will use the standard version
|
|
17
|
+
*/
|
|
18
|
+
profi;
|
|
3
19
|
/**
|
|
4
20
|
* @param {string} name of the aircraft as internal Aerofly FS 4 code, e.g. "c172"
|
|
5
21
|
* @param {string} paintscheme of the aircraft as internal Aerofly FS 4 code, e.g. "default"
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { AeroflyConfigurationNode, AeroflyConfigurationNodeComment } from "../node/AeroflyConfigurationNode.js";
|
|
2
2
|
export class AeroflySettingsCloud {
|
|
3
|
+
/**
|
|
4
|
+
* @property {number} density as normalized value [0,1], e.g. 0.5 for 50% cloud cover
|
|
5
|
+
*/
|
|
6
|
+
density;
|
|
7
|
+
/**
|
|
8
|
+
* @property {number} height in 10,000 ft AGL, e.g. 0.5 for 5,000 ft AGL
|
|
9
|
+
*/
|
|
10
|
+
height;
|
|
3
11
|
/**
|
|
4
12
|
* @param {number} density as normalized value [0,1], e.g. 0.5 for 50% cloud cover
|
|
5
13
|
* @param {number} height in 10,000 ft AGL, e.g. 0.5 for 5,000 ft AGL
|