@fboes/aerofly-custom-missions 1.6.0 → 1.8.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 +9 -0
- package/dist/dto/AeroflyMission.js +43 -0
- package/dist/dto/AeroflyMission.test.js +11 -3
- package/dist/dto/AeroflyMissionConditions.js +24 -0
- package/dist/dto/AeroflyMissionsList.js +11 -0
- package/dist/dto-flight/AeroflyFlight.test.js +1 -0
- package/dist/dto-flight/AeroflyNavRouteAirports.js +8 -0
- package/dist/dto-flight/AeroflyNavRouteBase.js +6 -0
- package/dist/dto-flight/AeroflyNavRouteRunway.js +10 -0
- package/dist/dto-flight/AeroflyNavRouteTransition.js +9 -0
- package/dist/dto-flight/AeroflyNavRouteWaypoint.js +29 -1
- package/dist/dto-flight/AeroflyNavigationConfig.js +7 -0
- package/dist/dto-flight/AeroflySettingsCloud.js +7 -0
- package/dist/dto-flight/AeroflySettingsFlight.js +7 -0
- package/dist/dto-flight/AeroflySettingsFuelLoad.js +13 -0
- package/dist/node/Convert.js +6 -0
- package/docs/custom_missions_user.json +131 -0
- package/docs/custom_missions_user.schema.json +269 -0
- package/docs/custom_missions_user.tmc +8 -3
- package/docs/custom_missions_user.xml +8 -3
- package/docs/flight-generator-prompt.md +91 -0
- package/docs/flight.json +134 -0
- package/package.json +1 -1
- package/src/dto/AeroflyMission.test.ts +18 -3
- package/src/dto/AeroflyMission.ts +44 -0
- package/src/dto/AeroflyMissionConditions.ts +27 -0
- package/src/dto/AeroflyMissionsList.ts +12 -0
- package/src/dto-flight/AeroflyFlight.test.ts +2 -0
- package/src/dto-flight/AeroflyNavRouteAirports.ts +9 -0
- package/src/dto-flight/AeroflyNavRouteBase.ts +7 -0
- package/src/dto-flight/AeroflyNavRouteRunway.ts +11 -0
- package/src/dto-flight/AeroflyNavRouteTransition.ts +10 -0
- package/src/dto-flight/AeroflyNavRouteWaypoint.ts +35 -0
- package/src/dto-flight/AeroflyNavigationConfig.ts +8 -0
- package/src/dto-flight/AeroflySettingsCloud.ts +8 -0
- package/src/dto-flight/AeroflySettingsFlight.ts +28 -1
- package/src/dto-flight/AeroflySettingsFuelLoad.ts +17 -0
- package/src/node/Convert.ts +8 -0
- package/types/dto/AeroflyMission.d.ts +1 -0
- package/types/dto/AeroflyMission.d.ts.map +1 -1
- package/types/dto/AeroflyMissionConditions.d.ts +1 -0
- package/types/dto/AeroflyMissionConditions.d.ts.map +1 -1
- package/types/dto/AeroflyMissionsList.d.ts +2 -0
- package/types/dto/AeroflyMissionsList.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteAirports.d.ts +1 -0
- package/types/dto-flight/AeroflyNavRouteAirports.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteBase.d.ts +3 -0
- package/types/dto-flight/AeroflyNavRouteBase.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteRunway.d.ts +1 -0
- package/types/dto-flight/AeroflyNavRouteRunway.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteTransition.d.ts +1 -0
- package/types/dto-flight/AeroflyNavRouteTransition.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavRouteWaypoint.d.ts +14 -1
- package/types/dto-flight/AeroflyNavRouteWaypoint.d.ts.map +1 -1
- package/types/dto-flight/AeroflyNavigationConfig.d.ts +1 -0
- package/types/dto-flight/AeroflyNavigationConfig.d.ts.map +1 -1
- package/types/dto-flight/AeroflySettingsCloud.d.ts +1 -0
- package/types/dto-flight/AeroflySettingsCloud.d.ts.map +1 -1
- package/types/dto-flight/AeroflySettingsFlight.d.ts +17 -1
- package/types/dto-flight/AeroflySettingsFlight.d.ts.map +1 -1
- package/types/dto-flight/AeroflySettingsFuelLoad.d.ts +4 -0
- package/types/dto-flight/AeroflySettingsFuelLoad.d.ts.map +1 -1
- package/types/node/Convert.d.ts +2 -0
- package/types/node/Convert.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
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.7.0] - 2026-04-19
|
|
6
|
+
|
|
7
|
+
- Added new flight configuration strings to `AeroflySettingsFlight`
|
|
8
|
+
|
|
9
|
+
## [1.6.0]
|
|
10
|
+
|
|
11
|
+
- Added `toJSON` improvements to most DTOs
|
|
12
|
+
- Added JSON schema for custom missions as JSON
|
|
13
|
+
|
|
5
14
|
## [1.5.0]
|
|
6
15
|
|
|
7
16
|
- Added clouds elements getter
|
|
@@ -180,4 +180,47 @@ export class AeroflyMission {
|
|
|
180
180
|
toString() {
|
|
181
181
|
return this.getElement().toString();
|
|
182
182
|
}
|
|
183
|
+
static fromJSON(json) {
|
|
184
|
+
if (typeof json !== "object" || json === null) {
|
|
185
|
+
throw new Error("Invalid mission data");
|
|
186
|
+
}
|
|
187
|
+
const data = json;
|
|
188
|
+
return new AeroflyMission(String(data.title ?? ""), {
|
|
189
|
+
tutorialName: String(data.tutorialName ?? ""),
|
|
190
|
+
description: String(data.description ?? ""),
|
|
191
|
+
localizedTexts: [], // TODO
|
|
192
|
+
tags: [], // TODO
|
|
193
|
+
isFeatured: data.isFeatured !== undefined ? Boolean(data.isFeatured) : null,
|
|
194
|
+
difficulty: data.difficulty !== undefined ? Number(data.difficulty) : null,
|
|
195
|
+
flightSetting: String(data.flightSetting ?? "taxi"),
|
|
196
|
+
aircraft: {
|
|
197
|
+
name: "c172",
|
|
198
|
+
icao: "",
|
|
199
|
+
livery: "",
|
|
200
|
+
},
|
|
201
|
+
callsign: String(data.callsign ?? ""),
|
|
202
|
+
fuelMass: data.fuelMass !== undefined ? Number(data.fuelMass) : null,
|
|
203
|
+
payloadMass: data.payloadMass !== undefined ? Number(data.payloadMass) : null,
|
|
204
|
+
origin: {
|
|
205
|
+
icao: "",
|
|
206
|
+
longitude: 0,
|
|
207
|
+
latitude: 0,
|
|
208
|
+
dir: 0,
|
|
209
|
+
alt: 0,
|
|
210
|
+
},
|
|
211
|
+
destination: {
|
|
212
|
+
icao: "",
|
|
213
|
+
longitude: 0,
|
|
214
|
+
latitude: 0,
|
|
215
|
+
dir: 0,
|
|
216
|
+
alt: 0,
|
|
217
|
+
},
|
|
218
|
+
distance: data.distance !== undefined ? Number(data.distance) : null,
|
|
219
|
+
duration: data.duration !== undefined ? Number(data.duration) : null,
|
|
220
|
+
isScheduled: data.isScheduled !== undefined ? Boolean(data.isScheduled) : null,
|
|
221
|
+
finish: null, // TODO
|
|
222
|
+
conditions: AeroflyMissionConditions.fromJSON(data.conditions),
|
|
223
|
+
checkpoints: [], // TODO
|
|
224
|
+
});
|
|
225
|
+
}
|
|
183
226
|
}
|
|
@@ -75,10 +75,11 @@ describe("AeroflyMission", () => {
|
|
|
75
75
|
flyOver: false,
|
|
76
76
|
}),
|
|
77
77
|
];
|
|
78
|
-
const mission = new AeroflyMission("
|
|
78
|
+
const mission = new AeroflyMission("Landing practice #1: Concord / Buchanan Field", {
|
|
79
79
|
checkpoints,
|
|
80
80
|
conditions,
|
|
81
|
-
description:
|
|
81
|
+
description: `\
|
|
82
|
+
It is a gusty, clear early morning, and you are 8 NM to the north of the towered airport Concord / Buchanan Field (27ft). As the wind is 11 kts from 190°, the main landing runway is 19L (191° / 844m). Fly the pattern and land safely.
|
|
82
83
|
|
|
83
84
|
- Local tower / CTAF frequency: 123.90
|
|
84
85
|
- Local navigational aids: VOR/DME CCR (117.00) 3.4 NM to the north`,
|
|
@@ -89,6 +90,8 @@ describe("AeroflyMission", () => {
|
|
|
89
90
|
icao: "C172",
|
|
90
91
|
},
|
|
91
92
|
callsign: "N51911",
|
|
93
|
+
fuelMass: 80,
|
|
94
|
+
payloadMass: 90,
|
|
92
95
|
origin: {
|
|
93
96
|
icao: "KCCR",
|
|
94
97
|
longitude: -122.0736009331662,
|
|
@@ -133,7 +136,11 @@ describe("AeroflyMission", () => {
|
|
|
133
136
|
//console.log(missionListString);
|
|
134
137
|
mission.difficulty = 1.0;
|
|
135
138
|
mission.isFeatured = true;
|
|
136
|
-
mission.localizedTexts.push(new AeroflyLocalizedText("de",
|
|
139
|
+
mission.localizedTexts.push(new AeroflyLocalizedText("de", `\
|
|
140
|
+
Landeübung #1: Concord / Buchanan Field`, `Es ist ein böiger, klarer früher Morgen, und du bist 8 Seemeilen nördlich des turmhohen Flughafens Concord / Buchanan Field (27 Fuß). Da der Wind 11 Knoten aus 190° erreicht, beträgt die Hauptlandebahn 19L (191° / 844m). Fliege das Muster und lande sicher.
|
|
141
|
+
|
|
142
|
+
- Lokaler Tower / CTAF-Frequenz: 123,90
|
|
143
|
+
- Lokale Navigationshilfen: VOR/DME CCR (117,00) 3,4 Seemeilen nördlich`));
|
|
137
144
|
mission.distance = 1400;
|
|
138
145
|
mission.duration = 2 * 60 * 60;
|
|
139
146
|
mission.tags.push("approach");
|
|
@@ -162,5 +169,6 @@ describe("AeroflyMission", () => {
|
|
|
162
169
|
fs.writeFileSync("docs/custom_missions_user.tmc", fileContent);
|
|
163
170
|
const xmlContent = file.toXmlString();
|
|
164
171
|
fs.writeFileSync("docs/custom_missions_user.xml", xmlContent);
|
|
172
|
+
fs.writeFileSync("docs/custom_missions_user.json", JSON.stringify(file, null, 2));
|
|
165
173
|
});
|
|
166
174
|
});
|
|
@@ -119,4 +119,28 @@ export class AeroflyMissionConditions {
|
|
|
119
119
|
toString() {
|
|
120
120
|
return this.getElement().toString();
|
|
121
121
|
}
|
|
122
|
+
static fromJSON(json) {
|
|
123
|
+
if (typeof json !== "object" || json === null) {
|
|
124
|
+
throw new Error("Invalid mission condition data");
|
|
125
|
+
}
|
|
126
|
+
const data = json;
|
|
127
|
+
if (typeof data.wind !== "object" || data.wind === null) {
|
|
128
|
+
throw new Error("Invalid wind data");
|
|
129
|
+
}
|
|
130
|
+
const wind = data.wind;
|
|
131
|
+
return new AeroflyMissionConditions({
|
|
132
|
+
time: data.time ? new Date(String(data.time)) : new Date(),
|
|
133
|
+
wind: {
|
|
134
|
+
direction: Number(wind.direction ?? 0),
|
|
135
|
+
speed: Number(wind.speed ?? 0),
|
|
136
|
+
gusts: Number(wind.gusts ?? 0),
|
|
137
|
+
},
|
|
138
|
+
turbulenceStrength: Number(data.turbulenceStrength ?? 0),
|
|
139
|
+
thermalStrength: Number(data.thermalStrength ?? 0),
|
|
140
|
+
visibility: Number(data.visibility ?? 25_000),
|
|
141
|
+
visibility_sm: Number(data.visibility_sm ?? 0),
|
|
142
|
+
temperature: Number(data.temperature ?? 0),
|
|
143
|
+
clouds: [], // TODO
|
|
144
|
+
});
|
|
145
|
+
}
|
|
122
146
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AeroflyConfigurationNode, AeroflyConfigurationNodeSpacer } from "../node/AeroflyConfigurationNode.js";
|
|
2
|
+
import { AeroflyMission } from "./AeroflyMission.js";
|
|
2
3
|
/**
|
|
3
4
|
* @class
|
|
4
5
|
* A list of flight plans.
|
|
@@ -29,4 +30,14 @@ export class AeroflyMissionsList {
|
|
|
29
30
|
toXmlString() {
|
|
30
31
|
return this.getElement().toXmlString();
|
|
31
32
|
}
|
|
33
|
+
toJSON() {
|
|
34
|
+
return this.missions;
|
|
35
|
+
}
|
|
36
|
+
static fromJSON(json) {
|
|
37
|
+
if (!Array.isArray(json)) {
|
|
38
|
+
throw new Error("Mission list base node must be of array type");
|
|
39
|
+
}
|
|
40
|
+
const data = json;
|
|
41
|
+
return new AeroflyMissionsList(data.map((d) => AeroflyMission.fromJSON(d)));
|
|
42
|
+
}
|
|
32
43
|
}
|
|
@@ -63,6 +63,7 @@ describe("AeroflyFlight", () => {
|
|
|
63
63
|
fs.writeFileSync("docs/flight.mcf", fileContent);
|
|
64
64
|
const xmlContent = flight.toXmlString();
|
|
65
65
|
fs.writeFileSync("docs/flight.xml", xmlContent);
|
|
66
|
+
fs.writeFileSync("docs/flight.json", JSON.stringify(flight, null, 2));
|
|
66
67
|
assertValidAeroflyStructure(fileContent);
|
|
67
68
|
assert.ok(fileContent.includes("c172"));
|
|
68
69
|
});
|
|
@@ -34,6 +34,14 @@ class AeroflyNavRouteAirport extends AeroflyNavRouteBase {
|
|
|
34
34
|
}
|
|
35
35
|
return element;
|
|
36
36
|
}
|
|
37
|
+
toJSON() {
|
|
38
|
+
return {
|
|
39
|
+
...this,
|
|
40
|
+
uid: this.uid !== null ? this.uid.toString() : null,
|
|
41
|
+
elevation: undefined,
|
|
42
|
+
elevation_ft: this.elevation_ft,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
37
45
|
}
|
|
38
46
|
export class AeroflyNavRouteOrigin extends AeroflyNavRouteAirport {
|
|
39
47
|
/**
|
|
@@ -45,6 +45,12 @@ export class AeroflyNavRouteBase {
|
|
|
45
45
|
: new AeroflyConfigurationNodeComment("uint64", "Uid", ""));
|
|
46
46
|
return element;
|
|
47
47
|
}
|
|
48
|
+
toJSON() {
|
|
49
|
+
return {
|
|
50
|
+
...this,
|
|
51
|
+
uid: this.uid !== null ? this.uid.toString() : null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
48
54
|
/**
|
|
49
55
|
* @returns {string} to use in Aerofly FS4's `main.mcf`
|
|
50
56
|
*/
|
|
@@ -51,6 +51,16 @@ class AeroflyNavRouteRunway extends AeroflyNavRouteBase {
|
|
|
51
51
|
}
|
|
52
52
|
return element;
|
|
53
53
|
}
|
|
54
|
+
toJSON() {
|
|
55
|
+
return {
|
|
56
|
+
...this,
|
|
57
|
+
uid: this.uid !== null ? this.uid.toString() : null,
|
|
58
|
+
elevation: undefined,
|
|
59
|
+
elevation_ft: this.elevation_ft,
|
|
60
|
+
runwayLength: undefined,
|
|
61
|
+
runwayLength_ft: this.runwayLength_ft,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
54
64
|
}
|
|
55
65
|
export class AeroflyNavRouteDepartureRunway extends AeroflyNavRouteRunway {
|
|
56
66
|
/**
|
|
@@ -39,6 +39,15 @@ class AeroflyNavRouteTransition extends AeroflyNavRouteBase {
|
|
|
39
39
|
.appendChild("uint64", "TransitionUid", this.transitionUid ?? 0);
|
|
40
40
|
return element;
|
|
41
41
|
}
|
|
42
|
+
toJSON() {
|
|
43
|
+
return {
|
|
44
|
+
...this,
|
|
45
|
+
uid: this.uid !== null ? this.uid.toString() : null,
|
|
46
|
+
transitionUid: this.transitionUid !== null ? this.transitionUid.toString() : null,
|
|
47
|
+
elevation: undefined,
|
|
48
|
+
elevation_ft: this.elevation_ft,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
42
51
|
}
|
|
43
52
|
export class AeroflyNavRouteApproach extends AeroflyNavRouteTransition {
|
|
44
53
|
/**
|
|
@@ -12,7 +12,7 @@ export class AeroflyNavRouteWaypoint extends AeroflyNavRouteBase {
|
|
|
12
12
|
* @param {boolean} [options.flyOver] if true, the waypoint is meant to be flown over, otherwise it can be used as a fly-by waypoint
|
|
13
13
|
* @param {?bigint} [options.uid] unique identifier for the waypoint, will be generated automatically if not provided
|
|
14
14
|
*/
|
|
15
|
-
constructor(identifier, longitude, latitude, { navaidFrequency = null, altitude = null, altitude_ft = null, flyOver = false, uid = null, } = {}) {
|
|
15
|
+
constructor(identifier, longitude, latitude, { navaidFrequency = null, navaidFrequency_khz = null, navaidFrequency_mhz = null, altitude = null, altitude_ft = null, flyOver = false, uid = null, } = {}) {
|
|
16
16
|
super("waypoint", identifier, longitude, latitude, { uid });
|
|
17
17
|
this.identifier = identifier;
|
|
18
18
|
this.longitude = longitude;
|
|
@@ -22,6 +22,12 @@ export class AeroflyNavRouteWaypoint extends AeroflyNavRouteBase {
|
|
|
22
22
|
if (altitude_ft !== null) {
|
|
23
23
|
this.altitude_ft = altitude_ft;
|
|
24
24
|
}
|
|
25
|
+
if (navaidFrequency_khz !== null) {
|
|
26
|
+
this.navaidFrequency_khz = navaidFrequency_khz;
|
|
27
|
+
}
|
|
28
|
+
if (navaidFrequency_mhz !== null) {
|
|
29
|
+
this.navaidFrequency_mhz = navaidFrequency_mhz;
|
|
30
|
+
}
|
|
25
31
|
this.flyOver = flyOver;
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
@@ -33,6 +39,18 @@ export class AeroflyNavRouteWaypoint extends AeroflyNavRouteBase {
|
|
|
33
39
|
set altitude_ft(altitude_ft) {
|
|
34
40
|
this.altitude = altitude_ft !== null ? Convert.convertFeetToMeter(altitude_ft) : null;
|
|
35
41
|
}
|
|
42
|
+
get navaidFrequency_khz() {
|
|
43
|
+
return this.navaidFrequency ? this.navaidFrequency / 1000 : null;
|
|
44
|
+
}
|
|
45
|
+
set navaidFrequency_khz(navaidFrequency_khz) {
|
|
46
|
+
this.navaidFrequency = navaidFrequency_khz !== null ? navaidFrequency_khz * 1000 : null;
|
|
47
|
+
}
|
|
48
|
+
get navaidFrequency_mhz() {
|
|
49
|
+
return this.navaidFrequency ? this.navaidFrequency / 1000_000 : null;
|
|
50
|
+
}
|
|
51
|
+
set navaidFrequency_mhz(navaidFrequency_mhz) {
|
|
52
|
+
this.navaidFrequency = navaidFrequency_mhz !== null ? navaidFrequency_mhz * 1000_000 : null;
|
|
53
|
+
}
|
|
36
54
|
/**
|
|
37
55
|
* @returns {AeroflyVector3Float} to use in Aerofly FS4's `main.mcf`
|
|
38
56
|
*/
|
|
@@ -55,4 +73,14 @@ export class AeroflyNavRouteWaypoint extends AeroflyNavRouteBase {
|
|
|
55
73
|
.appendChild("bool", "FlyOver", this.flyOver);
|
|
56
74
|
return element;
|
|
57
75
|
}
|
|
76
|
+
toJSON() {
|
|
77
|
+
return {
|
|
78
|
+
...this,
|
|
79
|
+
uid: this.uid !== null ? this.uid.toString() : null,
|
|
80
|
+
altitude: undefined,
|
|
81
|
+
altitude_ft: this.altitude_ft,
|
|
82
|
+
navaidFrequency: undefined,
|
|
83
|
+
navaidFrequency_khz: this.navaidFrequency_khz,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
58
86
|
}
|
|
@@ -41,6 +41,13 @@ export class AeroflyNavigationConfig {
|
|
|
41
41
|
.append(new AeroflyConfigurationNode("pointer_list_tmnav_route_way", "Ways").append(...this.getCheckpointElements())))
|
|
42
42
|
.append(new AeroflyConfigurationNode("list_fixed_tmnav_fix", "Fixes", []));
|
|
43
43
|
}
|
|
44
|
+
toJSON() {
|
|
45
|
+
return {
|
|
46
|
+
...this,
|
|
47
|
+
cruiseAltitude: undefined,
|
|
48
|
+
cruiseAltitude_ft: this.cruiseAltitude_ft,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
44
51
|
/**
|
|
45
52
|
* @returns {string} to use in Aerofly FS4's `main.mcf`
|
|
46
53
|
*/
|
|
@@ -91,6 +91,13 @@ export class AeroflySettingsCloud {
|
|
|
91
91
|
new AeroflyConfigurationNodeComment("float64", `${indexString}_height`, this.height, `${Math.floor(this.height_ft)} ft AGL`),
|
|
92
92
|
];
|
|
93
93
|
}
|
|
94
|
+
toJSON() {
|
|
95
|
+
return {
|
|
96
|
+
...this,
|
|
97
|
+
height: undefined,
|
|
98
|
+
height_ft: this.height_ft,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
94
101
|
/**
|
|
95
102
|
* @param {number} index if used in an array will set the array index
|
|
96
103
|
* @returns {string} to use in Aerofly FS4's `main.mcf`
|
|
@@ -86,6 +86,13 @@ export class AeroflySettingsFlight {
|
|
|
86
86
|
.appendChild("string8u", "airport", this.airport)
|
|
87
87
|
.appendChild("string8u", "runway", this.runway);
|
|
88
88
|
}
|
|
89
|
+
toJSON() {
|
|
90
|
+
return {
|
|
91
|
+
...this,
|
|
92
|
+
altitude_meter: undefined,
|
|
93
|
+
altitude_ft: this.altitude_ft,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
89
96
|
/**
|
|
90
97
|
* @returns {string} to use in Aerofly FS4's `main.mcf`
|
|
91
98
|
*/
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AeroflyConfigurationNode } from "../node/AeroflyConfigurationNode.js";
|
|
2
|
+
import { Convert } from "../node/Convert.js";
|
|
2
3
|
export class AeroflySettingsFuelLoad {
|
|
3
4
|
/**
|
|
4
5
|
* @param {string} aircraft aerofly aircraft name (e.g. "c172")
|
|
@@ -14,6 +15,18 @@ export class AeroflySettingsFuelLoad {
|
|
|
14
15
|
this.payloadMass = payloadMass;
|
|
15
16
|
this.configuration = configuration;
|
|
16
17
|
}
|
|
18
|
+
get fuelMass_lb() {
|
|
19
|
+
return Convert.convertKgToLb(this.fuelMass);
|
|
20
|
+
}
|
|
21
|
+
set fuelMass_lb(fuelMass_lb) {
|
|
22
|
+
this.fuelMass = Convert.convertLbToKg(fuelMass_lb);
|
|
23
|
+
}
|
|
24
|
+
get payloadMass_lb() {
|
|
25
|
+
return Convert.convertKgToLb(this.payloadMass);
|
|
26
|
+
}
|
|
27
|
+
set payloadMass_lb(payloadMass_lb) {
|
|
28
|
+
this.payloadMass = Convert.convertLbToKg(payloadMass_lb);
|
|
29
|
+
}
|
|
17
30
|
getElement() {
|
|
18
31
|
return new AeroflyConfigurationNode("tmsettings_fuel_load", "fuel_load_setting")
|
|
19
32
|
.appendChild("fuel_load_configuration", "configuration", this.fuelMass > 0 ? "Keep" : this.configuration)
|
package/dist/node/Convert.js
CHANGED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"tutorialName": "c172",
|
|
4
|
+
"title": "Landing practice #1: Concord / Buchanan Field",
|
|
5
|
+
"checkpoints": [
|
|
6
|
+
{
|
|
7
|
+
"type": "origin",
|
|
8
|
+
"name": "KCCR",
|
|
9
|
+
"longitude": -122.057,
|
|
10
|
+
"latitude": 37.9897,
|
|
11
|
+
"altitude": 8,
|
|
12
|
+
"altitudeConstraint": null,
|
|
13
|
+
"direction": null,
|
|
14
|
+
"slope": null,
|
|
15
|
+
"length": null,
|
|
16
|
+
"frequency": null,
|
|
17
|
+
"flyOver": null
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"type": "departure_runway",
|
|
21
|
+
"name": "19L",
|
|
22
|
+
"longitude": -122.05504061196366,
|
|
23
|
+
"latitude": 37.993168229891225,
|
|
24
|
+
"altitude": 0,
|
|
25
|
+
"altitudeConstraint": null,
|
|
26
|
+
"direction": null,
|
|
27
|
+
"slope": null,
|
|
28
|
+
"length": 844.2959729825288,
|
|
29
|
+
"frequency": null,
|
|
30
|
+
"flyOver": null
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "destination_runway",
|
|
34
|
+
"name": "24",
|
|
35
|
+
"longitude": -70.60730234370952,
|
|
36
|
+
"latitude": 41.399093035543366,
|
|
37
|
+
"altitude": 20,
|
|
38
|
+
"altitudeConstraint": null,
|
|
39
|
+
"direction": null,
|
|
40
|
+
"slope": null,
|
|
41
|
+
"length": 1677.6191463161874,
|
|
42
|
+
"frequency": 108700000,
|
|
43
|
+
"flyOver": null
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"type": "destination",
|
|
47
|
+
"name": "KMVY",
|
|
48
|
+
"longitude": -70.6139,
|
|
49
|
+
"latitude": 41.3934,
|
|
50
|
+
"altitude": 20,
|
|
51
|
+
"altitudeConstraint": null,
|
|
52
|
+
"direction": null,
|
|
53
|
+
"slope": null,
|
|
54
|
+
"length": null,
|
|
55
|
+
"frequency": null,
|
|
56
|
+
"flyOver": false
|
|
57
|
+
}
|
|
58
|
+
],
|
|
59
|
+
"description": "It is a gusty, clear early morning, and you are 8 NM to the north of the towered airport Concord / Buchanan Field (27ft). As the wind is 11 kts from 190°, the main landing runway is 19L (191° / 844m). Fly the pattern and land safely.\n\n- Local tower / CTAF frequency: 123.90\n- Local navigational aids: VOR/DME CCR (117.00) 3.4 NM to the north",
|
|
60
|
+
"localizedTexts": [
|
|
61
|
+
{
|
|
62
|
+
"language": "de",
|
|
63
|
+
"title": "Landeübung #1: Concord / Buchanan Field",
|
|
64
|
+
"description": "Es ist ein böiger, klarer früher Morgen, und du bist 8 Seemeilen nördlich des turmhohen Flughafens Concord / Buchanan Field (27 Fuß). Da der Wind 11 Knoten aus 190° erreicht, beträgt die Hauptlandebahn 19L (191° / 844m). Fliege das Muster und lande sicher.\n\n- Lokaler Tower / CTAF-Frequenz: 123,90\n- Lokale Navigationshilfen: VOR/DME CCR (117,00) 3,4 Seemeilen nördlich"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"tags": [
|
|
68
|
+
"approach",
|
|
69
|
+
"pattern"
|
|
70
|
+
],
|
|
71
|
+
"isFeatured": true,
|
|
72
|
+
"difficulty": 1,
|
|
73
|
+
"flightSetting": "cruise",
|
|
74
|
+
"aircraft": {
|
|
75
|
+
"name": "c172",
|
|
76
|
+
"livery": "default",
|
|
77
|
+
"icao": "C172"
|
|
78
|
+
},
|
|
79
|
+
"callsign": "N51911",
|
|
80
|
+
"fuelMass": 80,
|
|
81
|
+
"payloadMass": 90,
|
|
82
|
+
"origin": {
|
|
83
|
+
"icao": "KCCR",
|
|
84
|
+
"longitude": -122.0736009331662,
|
|
85
|
+
"latitude": 38.122300745843944,
|
|
86
|
+
"dir": 174.37511511143452,
|
|
87
|
+
"alt": 1066.799965862401
|
|
88
|
+
},
|
|
89
|
+
"destination": {
|
|
90
|
+
"icao": "KMVY",
|
|
91
|
+
"longitude": -70.6139,
|
|
92
|
+
"latitude": 41.3934,
|
|
93
|
+
"dir": 221,
|
|
94
|
+
"alt": 20
|
|
95
|
+
},
|
|
96
|
+
"distance": 1400,
|
|
97
|
+
"duration": 7200,
|
|
98
|
+
"isScheduled": true,
|
|
99
|
+
"finish": {
|
|
100
|
+
"longitude": 0,
|
|
101
|
+
"latitude": 1,
|
|
102
|
+
"dir": 2,
|
|
103
|
+
"name": "finish"
|
|
104
|
+
},
|
|
105
|
+
"conditions": {
|
|
106
|
+
"clouds": [
|
|
107
|
+
{
|
|
108
|
+
"cover": 0.1,
|
|
109
|
+
"base": 1523.9999512320016
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"cover": 0.2,
|
|
113
|
+
"base": 2285.9999268480024
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"cover": 0.1,
|
|
117
|
+
"base": 2895.599907340803
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"time": "2024-06-14T13:15:38.000Z",
|
|
121
|
+
"wind": {
|
|
122
|
+
"direction": 190,
|
|
123
|
+
"speed": 11,
|
|
124
|
+
"gusts": 22
|
|
125
|
+
},
|
|
126
|
+
"turbulenceStrength": 1,
|
|
127
|
+
"thermalStrength": 0.5184,
|
|
128
|
+
"visibility": 14484.096000000001
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
]
|