@fboes/aerofly-custom-missions 1.0.4 → 1.1.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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.0
4
+
5
+ - Added new mission properties `tags`, `isFeatured`, `difficulty`, `distance`, `duration` and translations
6
+ - Added new flight settings `"winch_launch`, `aerotow`
7
+ - Improved temperature property
8
+
9
+ ## 1.0.4
10
+
3
11
  - Added documentation for known issues
4
12
  - Added property `AeroflyMissionConditions.temperature`
5
13
 
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Builder for Aerofly FS4 Custom Missions Files
4
4
 
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 programatically.
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
7
  This library is intended to work in modern browsers as well as [Node.js](https://nodejs.org/en).
8
8
 
@@ -119,6 +119,44 @@ console.log(missionList.toString());
119
119
 
120
120
  As there are lots of properties for the mission object, check the type hinting on the various objects to find out which properties you are able to set.
121
121
 
122
+ ### Values for tags
123
+
124
+ The `tags` property of a single mission can contain multiple values. The following values have been used officially by Aerofly FS4.
125
+
126
+ - aerobatics
127
+ - aerotow
128
+ - airline
129
+ - airshow
130
+ - circling_approach
131
+ - crosswind
132
+ - dropoff
133
+ - full_flight
134
+ - gliding
135
+ - instruments
136
+ - landing
137
+ - law_enforcement
138
+ - low_level_flight
139
+ - low_visibility
140
+ - medical
141
+ - military
142
+ - night
143
+ - pattern
144
+ - practice
145
+ - race
146
+ - short_runway
147
+ - sidestep_approach
148
+ - sight_seeing
149
+ - sloped_runway
150
+ - steep_approach
151
+ - straight_in_approach
152
+ - supersonic
153
+ - surveillance
154
+ - takeoff
155
+ - terrain_avoidance
156
+ - vip
157
+ - winch_launch
158
+ - windy
159
+
122
160
  ### Important notices
123
161
 
124
162
  - Be aware that `mission.origin` and `mission.destination` do not need to match the flight plan. In case of `origin` you may want to set the position to the actual parking position of your aircraft, which may not be the first way point in your flight plan.
@@ -129,6 +167,13 @@ As there are lots of properties for the mission object, check the type hinting o
129
167
  - `destination`
130
168
  - Be aware that all units for altitude, elevation or distance are measured in meters! In most cases there will be helper functions for defining these values in feet (for length, altitude, elevation) or statute miles (for visibility).
131
169
 
170
+ There are also some unsupported properties, which are present in Aerofly FS4, but as of yet will not be generated by this library:
171
+
172
+ ```
173
+ <[string8][tutorial_name][c172]> // Opens https://www.aerofly.com/aircraft-tutorials/${tutorial_name}
174
+ <[bool][is_scheduled][true]>
175
+ ```
176
+
132
177
  ### Known issues
133
178
 
134
179
  - `AeroflyMissionConditions.time`: Even though a date property is available in Aerofly FS 4 (which is not accessible to the user), [the custom missions cannot change the date in Aerofly FS 4](https://www.aerofly.com/community/forum/index.php?thread/22487-more-settings-for-environment-conditions/&pageNo=1).
package/dist/index.js CHANGED
@@ -40,15 +40,21 @@ export class AeroflyMission {
40
40
  * @param {string} title of this flight plan
41
41
  * @param {object} [additionalAttributes] allows to set additional attributes on creation
42
42
  * @param {string} [additionalAttributes.description] text, mission briefing, etc
43
- * @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
43
+ * @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
44
+ * @param {string[]} [additionalAttributes.tags]
45
+ * @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
46
+ * @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
47
+ * @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
44
48
  * @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
45
49
  * @param {string} [additionalAttributes.callsign] of aircraft, uppercased
46
50
  * @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
47
51
  * @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
52
+ * @param {number} [additionalAttributes.distance] in meters
53
+ * @param {number} [additionalAttributes.duration] in seconds
48
54
  * @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
49
55
  * @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
50
56
  */
51
- constructor(title, { description = "", flightSetting = "taxi", aircraft = {
57
+ constructor(title, { description = "", localizedTexts = [], tags = [], isFeatured = false, difficulty = undefined, flightSetting = "taxi", aircraft = {
52
58
  name: "c172",
53
59
  icao: "",
54
60
  livery: "",
@@ -64,15 +70,21 @@ export class AeroflyMission {
64
70
  latitude: 0,
65
71
  dir: 0,
66
72
  alt: 0,
67
- }, conditions = new AeroflyMissionConditions(), checkpoints = [], } = {}) {
73
+ }, distance = 0, duration = 0, conditions = new AeroflyMissionConditions(), checkpoints = [], } = {}) {
68
74
  this.title = title;
69
75
  this.checkpoints = checkpoints;
70
76
  this.description = description;
77
+ this.localizedTexts = localizedTexts;
78
+ this.tags = tags;
79
+ this.isFeatured = isFeatured;
80
+ this.difficulty = difficulty;
71
81
  this.flightSetting = flightSetting;
72
82
  this.aircraft = aircraft;
73
83
  this.callsign = callsign;
74
84
  this.origin = origin;
75
85
  this.destination = destination;
86
+ this.distance = distance;
87
+ this.duration = duration;
76
88
  this.conditions = conditions;
77
89
  }
78
90
  /**
@@ -85,6 +97,16 @@ export class AeroflyMission {
85
97
  })
86
98
  .join("\n");
87
99
  }
100
+ /**
101
+ * @returns {string} indexed checkpoints
102
+ */
103
+ getLocalizedTextsString() {
104
+ return this.localizedTexts
105
+ .map((c, index) => {
106
+ return c.toString(index);
107
+ })
108
+ .join("\n");
109
+ }
88
110
  /**
89
111
  * @throws {Error} on missing waypoints
90
112
  * @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
@@ -113,9 +135,32 @@ export class AeroflyMission {
113
135
  alt: lastCheckpoint.altitude,
114
136
  };
115
137
  }
138
+ const optionalProperties = [];
139
+ if (this.localizedTexts.length > 0) {
140
+ optionalProperties.push(` <[list_tmmission_definition_localized][localized_text][]
141
+ ${this.getLocalizedTextsString()}
142
+ >`);
143
+ }
144
+ if (this.tags.length > 0) {
145
+ optionalProperties.push(` <[string8u][tags][ ${this.tags.join(" ")} ]>`);
146
+ }
147
+ if (this.difficulty !== undefined) {
148
+ optionalProperties.push(` <[float64] [difficulty] [${this.difficulty}]>`);
149
+ }
150
+ if (this.isFeatured) {
151
+ optionalProperties.push(` <[bool][is_featured][[${this.isFeatured ? "true" : "false"}]>`);
152
+ }
153
+ const moreOptionalProperties = [];
154
+ if (this.distance) {
155
+ moreOptionalProperties.push(` <[float64] [distance] [${this.distance}]> // ${Math.ceil(this.distance / 1000)} km`);
156
+ }
157
+ if (this.duration) {
158
+ moreOptionalProperties.push(` <[float64] [duration] [${this.duration}]> // ${Math.ceil(this.duration / 60)} min`);
159
+ }
116
160
  return ` <[tmmission_definition][mission][]
117
161
  <[string8][title][${this.title}]>
118
162
  <[string8][description][${this.description}]>
163
+ ${optionalProperties.join("\n")}
119
164
  <[string8] [flight_setting] [${this.flightSetting}]>
120
165
  <[string8u] [aircraft_name] [${this.aircraft.name}]>
121
166
  //<[string8u][aircraft_livery] [${this.aircraft.livery}]>
@@ -123,11 +168,13 @@ export class AeroflyMission {
123
168
  <[stringt8c] [callsign] [${this.callsign}]>
124
169
  <[stringt8c] [origin_icao] [${this.origin.icao}]>
125
170
  <[tmvector2d][origin_lon_lat] [${this.origin.longitude} ${this.origin.latitude}]>
126
- <[float64] [origin_dir] [${this.origin.dir}]>
127
171
  <[float64] [origin_alt] [${this.origin.alt}]> // ${this.origin.alt * feetPerMeter} ft MSL
172
+ <[float64] [origin_dir] [${this.origin.dir}]>
128
173
  <[stringt8c] [destination_icao] [${this.destination.icao}]>
129
174
  <[tmvector2d][destination_lon_lat][${this.destination.longitude} ${this.destination.latitude}]>
175
+ <[float64] [destination_alt] [${this.destination.alt}]> // ${this.destination.alt * feetPerMeter} ft MSL
130
176
  <[float64] [destination_dir] [${this.destination.dir}]>
177
+ ${moreOptionalProperties.join("\n")}
131
178
  ${this.conditions}
132
179
  <[list_tmmission_checkpoint][checkpoints][]
133
180
  ${this.getCheckpointsString()}
@@ -152,27 +199,31 @@ export class AeroflyMissionConditions {
152
199
  * @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
153
200
  * @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
154
201
  * @param {number} [additionalAttributes.visibility] in meters
155
- * @param {number?} [additionalAttributes.visibility_sm] in statute miles
202
+ * @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
203
+ * @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
156
204
  * @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
157
205
  */
158
206
  constructor({ time = new Date(), wind = {
159
207
  direction: 0,
160
208
  speed: 0,
161
209
  gusts: 0,
162
- }, turbulenceStrength = 0, thermalStrength = 0, visibility = 25_000, visibility_sm = null, clouds = [], } = {}) {
210
+ }, turbulenceStrength = 0, thermalStrength = 0, visibility = 25000, visibility_sm = null, temperature = null, clouds = [], } = {}) {
163
211
  /**
164
212
  * @property {AeroflyMissionConditionsCloud[]} clouds for the whole flight
165
213
  */
166
214
  this.clouds = [];
167
- if (visibility_sm) {
168
- visibility = visibility_sm * meterPerStatuteMile;
169
- }
170
215
  this.time = time;
171
216
  this.wind = wind;
172
217
  this.turbulenceStrength = turbulenceStrength;
173
218
  this.thermalStrength = thermalStrength;
174
219
  this.visibility = visibility;
175
220
  this.clouds = clouds;
221
+ if (visibility_sm) {
222
+ this.visibility_sm = visibility_sm;
223
+ }
224
+ if (temperature) {
225
+ this.temperature = temperature;
226
+ }
176
227
  }
177
228
  /**
178
229
  * @returns {number} the Aerofly value for UTC hours + minutes/60 + seconds/3600. Ignores milliseconds ;)
@@ -207,8 +258,14 @@ export class AeroflyMissionConditions {
207
258
  * @param {number} temperature in °C
208
259
  */
209
260
  set temperature(temperature) {
210
- // Range from 5°C to 30°C
211
- this.thermalStrength = Math.max(0, (temperature - 5) / 25);
261
+ // Range from -15°C to 35°C
262
+ this.thermalStrength = Math.max(0, (temperature + 15) / 50) ** 2;
263
+ }
264
+ /**
265
+ * @returns {number} in °C
266
+ */
267
+ get temperature() {
268
+ return Math.sqrt(this.thermalStrength) * 50 - 15;
212
269
  }
213
270
  /**
214
271
  * @returns {string}
@@ -238,7 +295,7 @@ export class AeroflyMissionConditions {
238
295
  <[float64][wind_speed][${this.wind.speed}]> // kts
239
296
  <[float64][wind_gusts][${this.wind.gusts}]> // kts
240
297
  <[float64][turbulence_strength][${this.turbulenceStrength}]>
241
- <[float64][thermal_strength][${this.thermalStrength}]>
298
+ <[float64][thermal_strength][${this.thermalStrength}]> // ${this.temperature} °C
242
299
  <[float64][visibility][${this.visibility}]> // ${this.visibility_sm} SM
243
300
  ${this.getCloudsString()}
244
301
  >`;
@@ -333,20 +390,14 @@ export class AeroflyMissionCheckpoint {
333
390
  * @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
334
391
  * 84 reference ellipsoid
335
392
  * @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
336
- * 84 reference ellipsoid
393
+ * 84 reference ellipsoid. Will overwrite altitude
337
394
  * @param {number} [additionalAttributes.direction] of runway, in degree
338
395
  * @param {number?} [additionalAttributes.slope] of runway
339
396
  * @param {number?} [additionalAttributes.length] of runway, in meters
340
- * @param {number?} [additionalAttributes.length_feet] of runway, in feet
397
+ * @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
341
398
  * @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
342
399
  */
343
400
  constructor(name, type, longitude, latitude, { altitude = 0, altitude_feet = null, direction = null, slope = null, length = null, length_feet = null, frequency = null, } = {}) {
344
- if (altitude_feet) {
345
- altitude = altitude_feet / feetPerMeter;
346
- }
347
- if (length_feet) {
348
- length = length_feet / feetPerMeter;
349
- }
350
401
  this.type = type;
351
402
  this.name = name;
352
403
  this.longitude = longitude;
@@ -356,6 +407,12 @@ export class AeroflyMissionCheckpoint {
356
407
  this.slope = slope;
357
408
  this.length = length;
358
409
  this.frequency = frequency;
410
+ if (altitude_feet) {
411
+ this.altitude_feet = altitude_feet;
412
+ }
413
+ if (length_feet) {
414
+ this.length_feet = length_feet;
415
+ }
359
416
  }
360
417
  /**
361
418
  * @param {number} altitude_feet
@@ -388,11 +445,11 @@ export class AeroflyMissionCheckpoint {
388
445
  if (!this.frequency) {
389
446
  return "None";
390
447
  }
391
- if (this.frequency > 1_000_000) {
392
- return String(this.frequency / 1_000_000) + " MHz";
448
+ if (this.frequency > 1000000) {
449
+ return String(this.frequency / 1000000) + " MHz";
393
450
  }
394
- if (this.frequency > 1_000) {
395
- return String(this.frequency / 1_000) + " kHz";
451
+ if (this.frequency > 1000) {
452
+ return String(this.frequency / 1000) + " kHz";
396
453
  }
397
454
  return String(this.frequency) + " Hz";
398
455
  }
@@ -413,10 +470,46 @@ export class AeroflyMissionCheckpoint {
413
470
  >`;
414
471
  }
415
472
  }
473
+ export class AeroflyLocalizedText {
474
+ /**
475
+ * @param {string} language like
476
+ * - br
477
+ * - cn
478
+ * - de
479
+ * - es
480
+ * - fr
481
+ * - id
482
+ * - it
483
+ * - jp
484
+ * - kr
485
+ * - pl
486
+ * - sv
487
+ * - tr
488
+ * @param {string} title of this flight plan
489
+ * @param {string} description text, mission briefing, etc
490
+ */
491
+ constructor(language, title, description) {
492
+ this.language = language;
493
+ this.title = title;
494
+ this.description = description;
495
+ }
496
+ /**
497
+ * @param {number} index if used in an array will se the array index
498
+ * @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
499
+ */
500
+ toString(index) {
501
+ return ` <[tmmission_definition_localized][element][${index}]
502
+ <[string8u][language][${this.language}]>
503
+ <[string8][title][${this.title}]>
504
+ <[string8][description][${this.description}]>
505
+ >`;
506
+ }
507
+ }
416
508
  export default {
417
509
  AeroflyMissionsList,
418
510
  AeroflyMission,
419
511
  AeroflyMissionConditions,
420
512
  AeroflyMissionConditionsCloud,
421
513
  AeroflyMissionCheckpoint,
514
+ AeroflyLocalizedText,
422
515
  };
@@ -1,4 +1,4 @@
1
- import { AeroflyMissionsList, AeroflyMission, AeroflyMissionConditions, AeroflyMissionConditionsCloud, AeroflyMissionCheckpoint, } from "./index.js";
1
+ import { AeroflyMissionsList, AeroflyMission, AeroflyMissionConditions, AeroflyMissionConditionsCloud, AeroflyMissionCheckpoint, AeroflyLocalizedText, } from "./index.js";
2
2
  import { strict as assert } from "node:assert";
3
3
  {
4
4
  const mission = new AeroflyMission("Title");
@@ -7,8 +7,8 @@ import { strict as assert } from "node:assert";
7
7
  }
8
8
  {
9
9
  const conditions = new AeroflyMissionConditions();
10
- conditions.visibility = 15_000;
11
- assert.deepStrictEqual(conditions.visibility, 15_000);
10
+ conditions.visibility = 15000;
11
+ assert.deepStrictEqual(conditions.visibility, 15000);
12
12
  conditions.visibility_sm = 10;
13
13
  assert.notDeepStrictEqual(conditions.visibility, 10);
14
14
  assert.deepStrictEqual(Math.round(conditions.visibility_sm), 10);
@@ -16,9 +16,9 @@ import { strict as assert } from "node:assert";
16
16
  }
17
17
  {
18
18
  const conditions = new AeroflyMissionConditions({
19
- visibility: 15_000,
19
+ visibility: 15000,
20
20
  });
21
- assert.deepStrictEqual(conditions.visibility, 15_000);
21
+ assert.deepStrictEqual(conditions.visibility, 15000);
22
22
  console.log("✅ AeroflyMissionConditions test successful");
23
23
  }
24
24
  {
@@ -53,7 +53,7 @@ import { strict as assert } from "node:assert";
53
53
  gusts: 22,
54
54
  },
55
55
  turbulenceStrength: 1,
56
- thermalStrength: 0.31200000000000006,
56
+ temperature: 21,
57
57
  visibility: 14484.096000000001,
58
58
  clouds: [
59
59
  AeroflyMissionConditionsCloud.createInFeet(0.1, 5000),
@@ -64,7 +64,7 @@ import { strict as assert } from "node:assert";
64
64
  assert.strictEqual(conditions.wind.speed, 11);
65
65
  assert.strictEqual(conditions.wind.gusts, 22);
66
66
  assert.strictEqual(conditions.turbulenceStrength, 1);
67
- assert.strictEqual(conditions.thermalStrength, 0.31200000000000006);
67
+ assert.strictEqual(conditions.temperature, 21);
68
68
  assert.strictEqual(conditions.visibility, 14484.096000000001);
69
69
  const checkpoints = [
70
70
  new AeroflyMissionCheckpoint("KCCR", "origin", -122.057, 37.9897, {
@@ -115,9 +115,7 @@ import { strict as assert } from "node:assert";
115
115
  assert.strictEqual(missionList.missions.length, 1);
116
116
  assert.strictEqual(missionList.missions[0].aircraft.name, "c172");
117
117
  assert.strictEqual(missionList.missions[0].aircraft.icao, "C172");
118
- //console.dir(missionList.missions[0], { depth: null });
119
- const missionListString = missionList.toString();
120
- //console.log(missionListString);
118
+ let missionListString = missionList.toString();
121
119
  assert.ok(missionListString.includes("[origin]"));
122
120
  assert.ok(missionListString.includes("[tmmission_definition]"));
123
121
  assert.ok(missionListString.includes("[list_tmmission_checkpoint]"));
@@ -130,5 +128,30 @@ import { strict as assert } from "node:assert";
130
128
  assert.ok(missionListString.includes("[tmmission_checkpoint][element][2]"));
131
129
  assert.ok(missionListString.includes("[tmmission_checkpoint][element][3]"));
132
130
  assert.ok(missionListString.includes("<[float64][length][844.2959729825288]>"));
131
+ assert.ok(!missionListString.includes("[tags]"));
132
+ assert.ok(!missionListString.includes("[difficulty]"));
133
+ assert.ok(!missionListString.includes("[is_featured]"));
134
+ assert.ok(!missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
135
+ assert.ok(!missionListString.includes("[distance]"));
136
+ assert.ok(!missionListString.includes("[duration]"));
137
+ //console.log(missionListString);
138
+ mission.difficulty = 1.0;
139
+ mission.isFeatured = true;
140
+ mission.localizedTexts.push(new AeroflyLocalizedText("de", "Landeübung #1", "Probier die Landung"));
141
+ mission.distance = 1400;
142
+ mission.duration = 2 * 60 * 60;
143
+ mission.tags.push("approach");
144
+ mission.tags.push("pattern");
145
+ missionListString = missionList.toString();
146
+ assert.ok(missionListString.includes("[tags]"));
147
+ assert.ok(missionListString.includes("[difficulty]"));
148
+ assert.ok(missionListString.includes("[is_featured]"));
149
+ assert.ok(missionListString.includes("true"));
150
+ assert.ok(missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
151
+ assert.ok(missionListString.includes("Landeübung"));
152
+ assert.ok(missionListString.includes("[distance]"));
153
+ assert.ok(missionListString.includes("[duration]"));
154
+ //console.dir(missionList.missions[0], { depth: null });
155
+ //console.log(missionListString);
133
156
  console.log("✅ AeroflyMissionsList test successful");
134
157
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fboes/aerofly-custom-missions",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Builder for Aerofly FS4 Custom Missions Files",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
package/src/index.test.ts CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  AeroflyMissionConditions,
5
5
  AeroflyMissionConditionsCloud,
6
6
  AeroflyMissionCheckpoint,
7
+ AeroflyLocalizedText,
7
8
  } from "./index.js";
8
9
  import { strict as assert } from "node:assert";
9
10
 
@@ -69,7 +70,7 @@ import { strict as assert } from "node:assert";
69
70
  gusts: 22,
70
71
  },
71
72
  turbulenceStrength: 1,
72
- thermalStrength: 0.31200000000000006,
73
+ temperature: 21,
73
74
  visibility: 14484.096000000001,
74
75
  clouds: [
75
76
  AeroflyMissionConditionsCloud.createInFeet(0.1, 5000),
@@ -81,7 +82,7 @@ import { strict as assert } from "node:assert";
81
82
  assert.strictEqual(conditions.wind.speed, 11);
82
83
  assert.strictEqual(conditions.wind.gusts, 22);
83
84
  assert.strictEqual(conditions.turbulenceStrength, 1);
84
- assert.strictEqual(conditions.thermalStrength, 0.31200000000000006);
85
+ assert.strictEqual(conditions.temperature, 21);
85
86
  assert.strictEqual(conditions.visibility, 14484.096000000001);
86
87
 
87
88
  const checkpoints = [
@@ -137,11 +138,7 @@ import { strict as assert } from "node:assert";
137
138
  assert.strictEqual(missionList.missions[0].aircraft.name, "c172");
138
139
  assert.strictEqual(missionList.missions[0].aircraft.icao, "C172");
139
140
 
140
- //console.dir(missionList.missions[0], { depth: null });
141
-
142
- const missionListString = missionList.toString();
143
-
144
- //console.log(missionListString);
141
+ let missionListString = missionList.toString();
145
142
 
146
143
  assert.ok(missionListString.includes("[origin]"));
147
144
  assert.ok(missionListString.includes("[tmmission_definition]"));
@@ -155,6 +152,35 @@ import { strict as assert } from "node:assert";
155
152
  assert.ok(missionListString.includes("[tmmission_checkpoint][element][2]"));
156
153
  assert.ok(missionListString.includes("[tmmission_checkpoint][element][3]"));
157
154
  assert.ok(missionListString.includes("<[float64][length][844.2959729825288]>"));
155
+ assert.ok(!missionListString.includes("[tags]"));
156
+ assert.ok(!missionListString.includes("[difficulty]"));
157
+ assert.ok(!missionListString.includes("[is_featured]"));
158
+ assert.ok(!missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
159
+ assert.ok(!missionListString.includes("[distance]"));
160
+ assert.ok(!missionListString.includes("[duration]"));
161
+
162
+ //console.log(missionListString);
163
+
164
+ mission.difficulty = 1.0;
165
+ mission.isFeatured = true;
166
+ mission.localizedTexts.push(new AeroflyLocalizedText("de", "Landeübung #1", "Probier die Landung"));
167
+ mission.distance = 1400;
168
+ mission.duration = 2 * 60 * 60;
169
+ mission.tags.push("approach");
170
+ mission.tags.push("pattern");
171
+ missionListString = missionList.toString();
172
+
173
+ assert.ok(missionListString.includes("[tags]"));
174
+ assert.ok(missionListString.includes("[difficulty]"));
175
+ assert.ok(missionListString.includes("[is_featured]"));
176
+ assert.ok(missionListString.includes("true"));
177
+ assert.ok(missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
178
+ assert.ok(missionListString.includes("Landeübung"));
179
+ assert.ok(missionListString.includes("[distance]"));
180
+ assert.ok(missionListString.includes("[duration]"));
181
+
182
+ //console.dir(missionList.missions[0], { depth: null });
183
+ //console.log(missionListString);
158
184
 
159
185
  console.log("✅ AeroflyMissionsList test successful");
160
186
  }
package/src/index.ts CHANGED
@@ -25,7 +25,7 @@ export type AeroflyMissionPosition = {
25
25
  /**
26
26
  * State of aircraft systems. Configures power settings, flap positions etc
27
27
  */
28
- export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing";
28
+ export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing" | "winch_launch" | "aerotow";
29
29
 
30
30
  /**
31
31
  * Types of checkpoints. Required are usually "origin", "departure_runway" at the start and "destination_runway", "destination" at the end.
@@ -112,6 +112,8 @@ export class AeroflyMissionsList {
112
112
  * for this file via the `toString()` method.
113
113
  */
114
114
  export class AeroflyMission {
115
+ // tutorial_name
116
+
115
117
  /**
116
118
  * @property {string} title of this flight plan
117
119
  */
@@ -123,7 +125,27 @@ export class AeroflyMission {
123
125
  description: string;
124
126
 
125
127
  /**
126
- * @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"} flightSetting of aircraft, like "taxi", "cruise"
128
+ * @property {AeroflyLocalizedText[]} localizedTexts for title and description
129
+ */
130
+ localizedTexts: AeroflyLocalizedText[];
131
+
132
+ /**
133
+ * @property {string[]} tags
134
+ */
135
+ tags: string[];
136
+
137
+ /**
138
+ * @property {boolean} isFeatured makes this mission pop up in "Challenges"
139
+ */
140
+ isFeatured: boolean;
141
+
142
+ /**
143
+ * @property {number|undefined} difficulty in 0..1, percentage
144
+ */
145
+ difficulty: number | undefined;
146
+
147
+ /**
148
+ * @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} flightSetting of aircraft, like "taxi", "cruise"
127
149
  */
128
150
  flightSetting: AeroflyMissionSetting;
129
151
 
@@ -147,6 +169,16 @@ export class AeroflyMission {
147
169
  */
148
170
  destination: AeroflyMissionPosition;
149
171
 
172
+ /**
173
+ * @property {number} in meters
174
+ */
175
+ distance: number;
176
+
177
+ /**
178
+ * @property {number} in seconds
179
+ */
180
+ duration: number;
181
+
150
182
  /**
151
183
  * @property {AeroflyMissionConditions} conditions like time and weather for mission
152
184
  */
@@ -161,11 +193,17 @@ export class AeroflyMission {
161
193
  * @param {string} title of this flight plan
162
194
  * @param {object} [additionalAttributes] allows to set additional attributes on creation
163
195
  * @param {string} [additionalAttributes.description] text, mission briefing, etc
164
- * @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
196
+ * @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
197
+ * @param {string[]} [additionalAttributes.tags]
198
+ * @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
199
+ * @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
200
+ * @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
165
201
  * @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
166
202
  * @param {string} [additionalAttributes.callsign] of aircraft, uppercased
167
203
  * @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
168
204
  * @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
205
+ * @param {number} [additionalAttributes.distance] in meters
206
+ * @param {number} [additionalAttributes.duration] in seconds
169
207
  * @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
170
208
  * @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
171
209
  */
@@ -173,6 +211,10 @@ export class AeroflyMission {
173
211
  title: string,
174
212
  {
175
213
  description = "",
214
+ localizedTexts = [],
215
+ tags = [],
216
+ isFeatured = false,
217
+ difficulty = undefined,
176
218
  flightSetting = "taxi",
177
219
  aircraft = {
178
220
  name: "c172",
@@ -194,15 +236,23 @@ export class AeroflyMission {
194
236
  dir: 0,
195
237
  alt: 0,
196
238
  },
239
+ distance = 0,
240
+ duration = 0,
197
241
  conditions = new AeroflyMissionConditions(),
198
242
  checkpoints = [],
199
243
  }: {
200
244
  description?: string;
245
+ localizedTexts?: AeroflyLocalizedText[];
246
+ tags?: string[];
247
+ isFeatured?: boolean;
248
+ difficulty?: number | undefined;
201
249
  flightSetting?: AeroflyMissionSetting;
202
250
  aircraft?: AeroflyMissionAircraft;
203
251
  callsign?: string;
204
252
  origin?: AeroflyMissionPosition;
205
253
  destination?: AeroflyMissionPosition;
254
+ distance?: number;
255
+ duration?: number;
206
256
  conditions?: AeroflyMissionConditions;
207
257
  checkpoints?: AeroflyMissionCheckpoint[];
208
258
  } = {},
@@ -210,11 +260,17 @@ export class AeroflyMission {
210
260
  this.title = title;
211
261
  this.checkpoints = checkpoints;
212
262
  this.description = description;
263
+ this.localizedTexts = localizedTexts;
264
+ this.tags = tags;
265
+ this.isFeatured = isFeatured;
266
+ this.difficulty = difficulty;
213
267
  this.flightSetting = flightSetting;
214
268
  this.aircraft = aircraft;
215
269
  this.callsign = callsign;
216
270
  this.origin = origin;
217
271
  this.destination = destination;
272
+ this.distance = distance;
273
+ this.duration = duration;
218
274
  this.conditions = conditions;
219
275
  }
220
276
 
@@ -229,6 +285,17 @@ export class AeroflyMission {
229
285
  .join("\n");
230
286
  }
231
287
 
288
+ /**
289
+ * @returns {string} indexed checkpoints
290
+ */
291
+ getLocalizedTextsString(): string {
292
+ return this.localizedTexts
293
+ .map((c: AeroflyLocalizedText, index: number): string => {
294
+ return c.toString(index);
295
+ })
296
+ .join("\n");
297
+ }
298
+
232
299
  /**
233
300
  * @throws {Error} on missing waypoints
234
301
  * @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
@@ -260,9 +327,38 @@ export class AeroflyMission {
260
327
  };
261
328
  }
262
329
 
330
+ const optionalProperties = [];
331
+ if (this.localizedTexts.length > 0) {
332
+ optionalProperties.push(` <[list_tmmission_definition_localized][localized_text][]
333
+ ${this.getLocalizedTextsString()}
334
+ >`);
335
+ }
336
+ if (this.tags.length > 0) {
337
+ optionalProperties.push(` <[string8u][tags][ ${this.tags.join(" ")} ]>`);
338
+ }
339
+ if (this.difficulty !== undefined) {
340
+ optionalProperties.push(` <[float64] [difficulty] [${this.difficulty}]>`);
341
+ }
342
+ if (this.isFeatured) {
343
+ optionalProperties.push(` <[bool][is_featured][[${this.isFeatured ? "true" : "false"}]>`);
344
+ }
345
+
346
+ const moreOptionalProperties = [];
347
+ if (this.distance) {
348
+ moreOptionalProperties.push(
349
+ ` <[float64] [distance] [${this.distance}]> // ${Math.ceil(this.distance / 1000)} km`,
350
+ );
351
+ }
352
+ if (this.duration) {
353
+ moreOptionalProperties.push(
354
+ ` <[float64] [duration] [${this.duration}]> // ${Math.ceil(this.duration / 60)} min`,
355
+ );
356
+ }
357
+
263
358
  return ` <[tmmission_definition][mission][]
264
359
  <[string8][title][${this.title}]>
265
360
  <[string8][description][${this.description}]>
361
+ ${optionalProperties.join("\n")}
266
362
  <[string8] [flight_setting] [${this.flightSetting}]>
267
363
  <[string8u] [aircraft_name] [${this.aircraft.name}]>
268
364
  //<[string8u][aircraft_livery] [${this.aircraft.livery}]>
@@ -270,11 +366,13 @@ export class AeroflyMission {
270
366
  <[stringt8c] [callsign] [${this.callsign}]>
271
367
  <[stringt8c] [origin_icao] [${this.origin.icao}]>
272
368
  <[tmvector2d][origin_lon_lat] [${this.origin.longitude} ${this.origin.latitude}]>
273
- <[float64] [origin_dir] [${this.origin.dir}]>
274
369
  <[float64] [origin_alt] [${this.origin.alt}]> // ${this.origin.alt * feetPerMeter} ft MSL
370
+ <[float64] [origin_dir] [${this.origin.dir}]>
275
371
  <[stringt8c] [destination_icao] [${this.destination.icao}]>
276
372
  <[tmvector2d][destination_lon_lat][${this.destination.longitude} ${this.destination.latitude}]>
373
+ <[float64] [destination_alt] [${this.destination.alt}]> // ${this.destination.alt * feetPerMeter} ft MSL
277
374
  <[float64] [destination_dir] [${this.destination.dir}]>
375
+ ${moreOptionalProperties.join("\n")}
278
376
  ${this.conditions}
279
377
  <[list_tmmission_checkpoint][checkpoints][]
280
378
  ${this.getCheckpointsString()}
@@ -331,7 +429,8 @@ export class AeroflyMissionConditions {
331
429
  * @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
332
430
  * @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
333
431
  * @param {number} [additionalAttributes.visibility] in meters
334
- * @param {number?} [additionalAttributes.visibility_sm] in statute miles
432
+ * @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
433
+ * @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
335
434
  * @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
336
435
  */
337
436
  constructor({
@@ -345,6 +444,7 @@ export class AeroflyMissionConditions {
345
444
  thermalStrength = 0,
346
445
  visibility = 25_000,
347
446
  visibility_sm = null,
447
+ temperature = null,
348
448
  clouds = [],
349
449
  }: {
350
450
  time?: Date;
@@ -357,17 +457,22 @@ export class AeroflyMissionConditions {
357
457
  thermalStrength?: number;
358
458
  visibility?: number;
359
459
  visibility_sm?: number | null;
460
+ temperature?: number | null;
360
461
  clouds?: AeroflyMissionConditionsCloud[];
361
462
  } = {}) {
362
- if (visibility_sm) {
363
- visibility = visibility_sm * meterPerStatuteMile;
364
- }
365
463
  this.time = time;
366
464
  this.wind = wind;
367
465
  this.turbulenceStrength = turbulenceStrength;
368
466
  this.thermalStrength = thermalStrength;
369
467
  this.visibility = visibility;
370
468
  this.clouds = clouds;
469
+
470
+ if (visibility_sm) {
471
+ this.visibility_sm = visibility_sm;
472
+ }
473
+ if (temperature) {
474
+ this.temperature = temperature;
475
+ }
371
476
  }
372
477
 
373
478
  /**
@@ -407,8 +512,15 @@ export class AeroflyMissionConditions {
407
512
  * @param {number} temperature in °C
408
513
  */
409
514
  set temperature(temperature: number) {
410
- // Range from 5°C to 30°C
411
- this.thermalStrength = Math.max(0, (temperature - 5) / 25);
515
+ // Range from -15°C to 35°C
516
+ this.thermalStrength = Math.max(0, (temperature + 15) / 50) ** 2;
517
+ }
518
+
519
+ /**
520
+ * @returns {number} in °C
521
+ */
522
+ get temperature(): number {
523
+ return Math.sqrt(this.thermalStrength) * 50 - 15;
412
524
  }
413
525
 
414
526
  /**
@@ -441,7 +553,7 @@ export class AeroflyMissionConditions {
441
553
  <[float64][wind_speed][${this.wind.speed}]> // kts
442
554
  <[float64][wind_gusts][${this.wind.gusts}]> // kts
443
555
  <[float64][turbulence_strength][${this.turbulenceStrength}]>
444
- <[float64][thermal_strength][${this.thermalStrength}]>
556
+ <[float64][thermal_strength][${this.thermalStrength}]> // ${this.temperature} °C
445
557
  <[float64][visibility][${this.visibility}]> // ${this.visibility_sm} SM
446
558
  ${this.getCloudsString()}
447
559
  >`;
@@ -602,11 +714,11 @@ export class AeroflyMissionCheckpoint {
602
714
  * @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
603
715
  * 84 reference ellipsoid
604
716
  * @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
605
- * 84 reference ellipsoid
717
+ * 84 reference ellipsoid. Will overwrite altitude
606
718
  * @param {number} [additionalAttributes.direction] of runway, in degree
607
719
  * @param {number?} [additionalAttributes.slope] of runway
608
720
  * @param {number?} [additionalAttributes.length] of runway, in meters
609
- * @param {number?} [additionalAttributes.length_feet] of runway, in feet
721
+ * @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
610
722
  * @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
611
723
  */
612
724
  constructor(
@@ -632,13 +744,6 @@ export class AeroflyMissionCheckpoint {
632
744
  frequency?: number | null;
633
745
  } = {},
634
746
  ) {
635
- if (altitude_feet) {
636
- altitude = altitude_feet / feetPerMeter;
637
- }
638
- if (length_feet) {
639
- length = length_feet / feetPerMeter;
640
- }
641
-
642
747
  this.type = type;
643
748
  this.name = name;
644
749
  this.longitude = longitude;
@@ -648,6 +753,13 @@ export class AeroflyMissionCheckpoint {
648
753
  this.slope = slope;
649
754
  this.length = length;
650
755
  this.frequency = frequency;
756
+
757
+ if (altitude_feet) {
758
+ this.altitude_feet = altitude_feet;
759
+ }
760
+ if (length_feet) {
761
+ this.length_feet = length_feet;
762
+ }
651
763
  }
652
764
 
653
765
  /**
@@ -713,10 +825,75 @@ export class AeroflyMissionCheckpoint {
713
825
  }
714
826
  }
715
827
 
828
+ export class AeroflyLocalizedText {
829
+ /**
830
+ * @property {string} language like
831
+ * - br
832
+ * - cn
833
+ * - de
834
+ * - es
835
+ * - fr
836
+ * - id
837
+ * - it
838
+ * - jp
839
+ * - kr
840
+ * - pl
841
+ * - sv
842
+ * - tr
843
+ */
844
+ language: string;
845
+
846
+ /**
847
+ * @property {string} title of this flight plan
848
+ */
849
+ title: string;
850
+
851
+ /**
852
+ * @property {string} description text, mission briefing, etc
853
+ */
854
+ description: string;
855
+
856
+ /**
857
+ * @param {string} language like
858
+ * - br
859
+ * - cn
860
+ * - de
861
+ * - es
862
+ * - fr
863
+ * - id
864
+ * - it
865
+ * - jp
866
+ * - kr
867
+ * - pl
868
+ * - sv
869
+ * - tr
870
+ * @param {string} title of this flight plan
871
+ * @param {string} description text, mission briefing, etc
872
+ */
873
+ constructor(language: string, title: string, description: string) {
874
+ this.language = language;
875
+ this.title = title;
876
+ this.description = description;
877
+ }
878
+
879
+ /**
880
+ * @param {number} index if used in an array will se the array index
881
+ * @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
882
+ */
883
+ toString(index: number): string {
884
+ return ` <[tmmission_definition_localized][element][${index}]
885
+ <[string8u][language][${this.language}]>
886
+ <[string8][title][${this.title}]>
887
+ <[string8][description][${this.description}]>
888
+ >`;
889
+ }
890
+ }
891
+
716
892
  export default {
717
893
  AeroflyMissionsList,
718
894
  AeroflyMission,
719
895
  AeroflyMissionConditions,
720
896
  AeroflyMissionConditionsCloud,
721
897
  AeroflyMissionCheckpoint,
898
+ AeroflyLocalizedText,
722
899
  };
package/types/index.d.ts CHANGED
@@ -21,7 +21,7 @@ export type AeroflyMissionPosition = {
21
21
  /**
22
22
  * State of aircraft systems. Configures power settings, flap positions etc
23
23
  */
24
- export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing";
24
+ export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing" | "winch_launch" | "aerotow";
25
25
  /**
26
26
  * Types of checkpoints. Required are usually "origin", "departure_runway" at the start and "destination_runway", "destination" at the end.
27
27
  */
@@ -100,7 +100,23 @@ export declare class AeroflyMission {
100
100
  */
101
101
  description: string;
102
102
  /**
103
- * @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"} flightSetting of aircraft, like "taxi", "cruise"
103
+ * @property {AeroflyLocalizedText[]} localizedTexts for title and description
104
+ */
105
+ localizedTexts: AeroflyLocalizedText[];
106
+ /**
107
+ * @property {string[]} tags
108
+ */
109
+ tags: string[];
110
+ /**
111
+ * @property {boolean} isFeatured makes this mission pop up in "Challenges"
112
+ */
113
+ isFeatured: boolean;
114
+ /**
115
+ * @property {number|undefined} difficulty in 0..1, percentage
116
+ */
117
+ difficulty: number | undefined;
118
+ /**
119
+ * @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} flightSetting of aircraft, like "taxi", "cruise"
104
120
  */
105
121
  flightSetting: AeroflyMissionSetting;
106
122
  /**
@@ -119,6 +135,14 @@ export declare class AeroflyMission {
119
135
  * @property {object} destination position of aircraft, as well as name of destination airport. Position does not have match airport.
120
136
  */
121
137
  destination: AeroflyMissionPosition;
138
+ /**
139
+ * @property {number} in meters
140
+ */
141
+ distance: number;
142
+ /**
143
+ * @property {number} in seconds
144
+ */
145
+ duration: number;
122
146
  /**
123
147
  * @property {AeroflyMissionConditions} conditions like time and weather for mission
124
148
  */
@@ -131,11 +155,17 @@ export declare class AeroflyMission {
131
155
  * @param {string} title of this flight plan
132
156
  * @param {object} [additionalAttributes] allows to set additional attributes on creation
133
157
  * @param {string} [additionalAttributes.description] text, mission briefing, etc
134
- * @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
158
+ * @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
159
+ * @param {string[]} [additionalAttributes.tags]
160
+ * @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
161
+ * @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
162
+ * @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
135
163
  * @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
136
164
  * @param {string} [additionalAttributes.callsign] of aircraft, uppercased
137
165
  * @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
138
166
  * @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
167
+ * @param {number} [additionalAttributes.distance] in meters
168
+ * @param {number} [additionalAttributes.duration] in seconds
139
169
  * @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
140
170
  * @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
141
171
  */
@@ -143,20 +173,32 @@ export declare class AeroflyMission {
143
173
  title: string,
144
174
  {
145
175
  description,
176
+ localizedTexts,
177
+ tags,
178
+ isFeatured,
179
+ difficulty,
146
180
  flightSetting,
147
181
  aircraft,
148
182
  callsign,
149
183
  origin,
150
184
  destination,
185
+ distance,
186
+ duration,
151
187
  conditions,
152
188
  checkpoints,
153
189
  }?: {
154
190
  description?: string;
191
+ localizedTexts?: AeroflyLocalizedText[];
192
+ tags?: string[];
193
+ isFeatured?: boolean;
194
+ difficulty?: number | undefined;
155
195
  flightSetting?: AeroflyMissionSetting;
156
196
  aircraft?: AeroflyMissionAircraft;
157
197
  callsign?: string;
158
198
  origin?: AeroflyMissionPosition;
159
199
  destination?: AeroflyMissionPosition;
200
+ distance?: number;
201
+ duration?: number;
160
202
  conditions?: AeroflyMissionConditions;
161
203
  checkpoints?: AeroflyMissionCheckpoint[];
162
204
  },
@@ -165,6 +207,10 @@ export declare class AeroflyMission {
165
207
  * @returns {string} indexed checkpoints
166
208
  */
167
209
  getCheckpointsString(): string;
210
+ /**
211
+ * @returns {string} indexed checkpoints
212
+ */
213
+ getLocalizedTextsString(): string;
168
214
  /**
169
215
  * @throws {Error} on missing waypoints
170
216
  * @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
@@ -213,7 +259,8 @@ export declare class AeroflyMissionConditions {
213
259
  * @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
214
260
  * @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
215
261
  * @param {number} [additionalAttributes.visibility] in meters
216
- * @param {number?} [additionalAttributes.visibility_sm] in statute miles
262
+ * @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
263
+ * @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
217
264
  * @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
218
265
  */
219
266
  constructor({
@@ -223,6 +270,7 @@ export declare class AeroflyMissionConditions {
223
270
  thermalStrength,
224
271
  visibility,
225
272
  visibility_sm,
273
+ temperature,
226
274
  clouds,
227
275
  }?: {
228
276
  time?: Date;
@@ -235,6 +283,7 @@ export declare class AeroflyMissionConditions {
235
283
  thermalStrength?: number;
236
284
  visibility?: number;
237
285
  visibility_sm?: number | null;
286
+ temperature?: number | null;
238
287
  clouds?: AeroflyMissionConditionsCloud[];
239
288
  });
240
289
  /**
@@ -258,6 +307,10 @@ export declare class AeroflyMissionConditions {
258
307
  * @param {number} temperature in °C
259
308
  */
260
309
  set temperature(temperature: number);
310
+ /**
311
+ * @returns {number} in °C
312
+ */
313
+ get temperature(): number;
261
314
  /**
262
315
  * @returns {string}
263
316
  */
@@ -378,11 +431,11 @@ export declare class AeroflyMissionCheckpoint {
378
431
  * @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
379
432
  * 84 reference ellipsoid
380
433
  * @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
381
- * 84 reference ellipsoid
434
+ * 84 reference ellipsoid. Will overwrite altitude
382
435
  * @param {number} [additionalAttributes.direction] of runway, in degree
383
436
  * @param {number?} [additionalAttributes.slope] of runway
384
437
  * @param {number?} [additionalAttributes.length] of runway, in meters
385
- * @param {number?} [additionalAttributes.length_feet] of runway, in feet
438
+ * @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
386
439
  * @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
387
440
  */
388
441
  constructor(
@@ -434,12 +487,62 @@ export declare class AeroflyMissionCheckpoint {
434
487
  */
435
488
  toString(index?: number): string;
436
489
  }
490
+ export declare class AeroflyLocalizedText {
491
+ /**
492
+ * @property {string} language like
493
+ * - br
494
+ * - cn
495
+ * - de
496
+ * - es
497
+ * - fr
498
+ * - id
499
+ * - it
500
+ * - jp
501
+ * - kr
502
+ * - pl
503
+ * - sv
504
+ * - tr
505
+ */
506
+ language: string;
507
+ /**
508
+ * @property {string} title of this flight plan
509
+ */
510
+ title: string;
511
+ /**
512
+ * @property {string} description text, mission briefing, etc
513
+ */
514
+ description: string;
515
+ /**
516
+ * @param {string} language like
517
+ * - br
518
+ * - cn
519
+ * - de
520
+ * - es
521
+ * - fr
522
+ * - id
523
+ * - it
524
+ * - jp
525
+ * - kr
526
+ * - pl
527
+ * - sv
528
+ * - tr
529
+ * @param {string} title of this flight plan
530
+ * @param {string} description text, mission briefing, etc
531
+ */
532
+ constructor(language: string, title: string, description: string);
533
+ /**
534
+ * @param {number} index if used in an array will se the array index
535
+ * @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
536
+ */
537
+ toString(index: number): string;
538
+ }
437
539
  declare const _default: {
438
540
  AeroflyMissionsList: typeof AeroflyMissionsList;
439
541
  AeroflyMission: typeof AeroflyMission;
440
542
  AeroflyMissionConditions: typeof AeroflyMissionConditions;
441
543
  AeroflyMissionConditionsCloud: typeof AeroflyMissionConditionsCloud;
442
544
  AeroflyMissionCheckpoint: typeof AeroflyMissionCheckpoint;
545
+ AeroflyLocalizedText: typeof AeroflyLocalizedText;
443
546
  };
444
547
  export default _default;
445
548
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}