UNPKG

@fboes/aerofly-custom-missions

Version:

Builder for Aerofly FS4 Custom Missions Files

175 lines (172 loc) 8.45 kB
import { AeroflyMission } from "./AeroflyMission.js"; import { strict as assert } from "node:assert"; import fs from "node:fs"; import { assertIncludes, assertValidAeroflyStructure } from "../check/TestHelpers.js"; import { describe, it } from "node:test"; import { AeroflyLocalizedText } from "./AeroflyLocalizedText.js"; import { AeroflyMissionCheckpoint } from "./AeroflyMissionCheckpoint.js"; import { AeroflyMissionConditions } from "./AeroflyMissionConditions.js"; import { AeroflyMissionConditionsCloud } from "./AeroflyMissionConditionsCloud.js"; import { AeroflyMissionsList } from "./AeroflyMissionsList.js"; import { AeroflyMissionTargetPlane } from "./AeroflyMissionTargetPlane.js"; describe("AeroflyMission", () => { const mission = new AeroflyMission("Title", { origin: { icao: "XXXX", longitude: 0, latitude: 0, dir: 0, alt: 0, }, destination: { icao: "XXXX", longitude: 0, latitude: 0, dir: 0, alt: 0, }, }); it("should correctly map constructor values", () => { assert.strictEqual(mission.title, "Title"); }); it("should create a valid Aerofly mission", () => { assertValidAeroflyStructure(mission.toString()); }); it("should create a valid XML mission", () => { assertValidAeroflyStructure(mission.getElement().toXmlString()); }); it("should create AeroflyMissionConditions correctly", () => { const conditions = new AeroflyMissionConditions({ time: new Date(Date.UTC(2024, 5, 14, 13, 15, 38)), wind: { direction: 190, speed: 11, gusts: 22, }, turbulenceStrength: 1, temperature: 21, visibility: 14484.096000000001, clouds: [ AeroflyMissionConditionsCloud.createInFeet(0.1, 5000), AeroflyMissionConditionsCloud.createInFeet(0.2, 7500), AeroflyMissionConditionsCloud.createInFeet(0.1, 9500), ], }); assert.strictEqual(conditions.wind.direction, 190); assert.strictEqual(conditions.wind.speed, 11); assert.strictEqual(conditions.wind.gusts, 22); assert.strictEqual(conditions.turbulenceStrength, 1); assert.strictEqual(conditions.temperature, 21); assert.strictEqual(conditions.visibility, 14484.096000000001); const checkpoints = [ new AeroflyMissionCheckpoint("KCCR", "origin", -122.057, 37.9897, { altitude: 8, }), new AeroflyMissionCheckpoint("19L", "departure_runway", -122.05504061196366, 37.993168229891225, { length: 844.2959729825288, }), new AeroflyMissionCheckpoint("24", "destination_runway", -70.60730234370952, 41.399093035543366, { altitude: 20, length: 1677.6191463161874, frequency: 108700000, }), new AeroflyMissionCheckpoint("KMVY", "destination", -70.6139, 41.3934, { altitude: 20, flyOver: false, }), ]; const mission = new AeroflyMission("Landing practice #1: Concord / Buchanan Field", { checkpoints, conditions, 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. - Local tower / CTAF frequency: 123.90 - Local navigational aids: VOR/DME CCR (117.00) 3.4 NM to the north`, flightSetting: "cruise", aircraft: { name: "c172", livery: "default", icao: "C172", }, callsign: "N51911", fuelMass: 80, payloadMass: 90, origin: { icao: "KCCR", longitude: -122.0736009331662, latitude: 38.122300745843944, dir: 174.37511511143452, alt: 1066.799965862401, }, destination: { icao: "KMVY", longitude: -70.6139, latitude: 41.3934, dir: 221, alt: 20, }, }); const missionList = new AeroflyMissionsList([mission]); assert.strictEqual(missionList.missions.length, 1); assert.strictEqual(missionList.missions[0].aircraft.name, "c172"); assert.strictEqual(missionList.missions[0].aircraft.icao, "C172"); let missionListString = missionList.toString(); assert.strictEqual(missionListString, missionList.toString()); assertIncludes(missionListString, "[origin]"); assertIncludes(missionListString, "[tmmission_definition]"); assertIncludes(missionListString, "[list_tmmission_checkpoint]"); assertIncludes(missionListString, "[tmmission_checkpoint]"); assertIncludes(missionListString, "[departure_runway]"); assertIncludes(missionListString, "[cloud_cover]"); assertIncludes(missionListString, "[cirrus_cover]"); assertIncludes(missionListString, "[tmmission_checkpoint][element][0]"); assertIncludes(missionListString, "[tmmission_checkpoint][element][1]"); assertIncludes(missionListString, "[tmmission_checkpoint][element][2]"); assertIncludes(missionListString, "[tmmission_checkpoint][element][3]"); assertIncludes(missionListString, "<[float64][length][844.2959729825288]>"); assert.ok(!missionListString.includes("[tags]")); assert.ok(!missionListString.includes("[difficulty]")); assert.ok(!missionListString.includes("[is_featured]")); assert.ok(!missionListString.includes("[tmmission_definition_localized]")); assert.ok(!missionListString.includes("[distance]")); assert.ok(!missionListString.includes("[duration]")); assert.ok(!missionListString.includes("[alt_cst]")); assertValidAeroflyStructure(missionListString); //console.log(missionListString); mission.difficulty = 1.0; mission.isFeatured = true; mission.localizedTexts.push(new AeroflyLocalizedText("de", `\ 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. - Lokaler Tower / CTAF-Frequenz: 123,90 - Lokale Navigationshilfen: VOR/DME CCR (117,00) 3,4 Seemeilen nördlich`)); mission.distance = 1400; mission.duration = 2 * 60 * 60; mission.tags.push("approach"); mission.tags.push("pattern"); mission.finish = new AeroflyMissionTargetPlane(0, 1, 2); mission.tutorialName = "c172"; mission.isScheduled = true; missionListString = missionList.toString(); assertIncludes(missionListString, "[tags]"); assertIncludes(missionListString, "[difficulty]"); assertIncludes(missionListString, "[is_featured]"); assertIncludes(missionListString, "true"); assertIncludes(missionListString, "[tmmission_definition_localized]"); assertIncludes(missionListString, "Landeübung"); assertIncludes(missionListString, "[distance]"); assertIncludes(missionListString, "[duration]"); assertIncludes(missionListString, "[finish]"); assertIncludes(missionListString, "[tutorial_name]"); assertIncludes(missionListString, "[is_scheduled]"); assertValidAeroflyStructure(missionListString); //console.dir(missionList.missions[0], { depth: null }); //console.log(missionListString); //console.log(missionList.getElement().toXmlString()); const file = new AeroflyMissionsList([mission]); const fileContent = file.toString(); fs.writeFileSync("docs/custom_missions_user.tmc", fileContent); const xmlContent = file.toXmlString(); fs.writeFileSync("docs/custom_missions_user.xml", xmlContent); fs.writeFileSync("docs/custom_missions_user.json", JSON.stringify(file, null, 2)); }); });