/// <summary> /// Generates the mission briefing. /// </summary> /// <param name="mission">Mission</param> /// <param name="template">Template from which the mission should be built</param> /// <param name="airbaseDB">Airbase player will take off from and land back on</param> /// <param name="coalitionsDB">Database entries for the mission coalitions</param> public void GenerateMissionBriefing(DCSMission mission, MissionTemplate template, DBEntryObjective objectiveDB, DBEntryTheaterAirbase airbaseDB, DBEntryUnit carrierDB, List <UnitFlightGroupBriefingDescription> flightGroups, DBEntryCoalition[] coalitionsDB) { DebugLog.Instance.WriteLine("Generating mission briefing...", 1); // Get mission features DBEntryMissionFeature[] features = Database.Instance.GetEntries <DBEntryMissionFeature>(objectiveDB.MissionFeatures); string description = GeneratorTools.SanitizeString(template.BriefingDescription); if (string.IsNullOrEmpty(description)) // No custom mission description has been provided, generate one { description = objectiveDB.BriefingDescriptionByUnitFamily[(int)mission.Objectives[0].TargetFamily]; if (string.IsNullOrEmpty(description)) // No custom briefing for this target family, use the default { description = objectiveDB.BriefingDescription; } description = GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(description), mission, coalitionsDB); } description = GeneratorTools.SanitizeString(description); // Generate tasks string baseName = carrierDB != null? carrierDB.ID : airbaseDB.Name; List <string> tasks = new List <string> { $"Take off from {baseName}" }; string objectiveTask = GeneratorTools.ParseRandomString(objectiveDB.BriefingTask); for (int i = 0; i < mission.Objectives.Length; i++) { string taskString = GeneratorTools.MakeBriefingStringReplacements(objectiveTask, mission, coalitionsDB, i); tasks.Add(taskString); mission.CoreLuaScript += $"briefingRoom.mission.objectives[{i + 1}].task = \"{taskString}\"\r\n"; } tasks.Add($"Return to {baseName}"); DebugLog.Instance.WriteLine($"{tasks.Count} task(s)", 2); // Generate mission remarks... List <string> remarks = new List <string>(); remarks.AddRange( // ...from objective from string remark in objectiveDB.BriefingRemarks select GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(remark), mission, coalitionsDB)); foreach (DBEntryMissionFeature feature in features) { remarks.AddRange( // ...from features from string remark in feature.BriefingRemarks select GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(remark), mission, coalitionsDB)); } /* * // Opposition Remarks * string airDefenseNumbers = template.OppositionAirDefense == AmountN.Random? "Unknown":template.OppositionAirDefense.ToString(); * string airDefenseSkill = template.OppositionSkillLevelGround == BRSkillLevel.Random? "Varied":template.OppositionSkillLevelGround.ToString(); * string airForceNumbers = template.OppositionAirForce == AmountN.Random? "Unknown":template.OppositionAirForce.ToString(); * string airForceSkill = template.OppositionSkillLevelAir == BRSkillLevel.Random? "Varied":template.OppositionSkillLevelAir.ToString(); * string allyAirDefenseNumbers = template.PlayerFriendlyAirDefense == AmountN.Random? "Unknown":template.PlayerFriendlyAirDefense.ToString(); * string allyAirDefenseSkill = template.PlayerAISkillLevel == BRSkillLevel.Random? "Varied":template.PlayerAISkillLevel.ToString(); * remarks.AddRange(new List<string>{ * $"Enemy Air Defenses are {airDefenseNumbers} and they are {airDefenseSkill} troops", * $"Expected Enemy Air Force response is {airForceNumbers} and they are {airForceSkill} pilots", * $"Our Air Defenses are {allyAirDefenseNumbers} and they are {allyAirDefenseSkill} troops",}); * remarks.Add("Use the \"F10/Other\" item in the comms for additional options"); * DebugLog.Instance.WriteLine($"{remarks.Count} remark(s)", 2); */ mission.BriefingHTML = CreateHTMLBriefing(mission, template, description, tasks, remarks, flightGroups, airbaseDB, carrierDB, coalitionsDB); mission.BriefingTXT = CreateTXTBriefing(description, tasks, remarks, flightGroups, airbaseDB, carrierDB); }
private string CreateHTMLBriefing( DCSMission mission, MissionTemplate template, string description, List <string> tasks, List <string> remarks, List <UnitFlightGroupBriefingDescription> flightGroups, DBEntryTheaterAirbase airbaseDB, DBEntryUnit carrierDB, DBEntryCoalition[] coalitionsDB) { DebugLog.Instance.WriteLine("Generating HTML mission briefing...", 2); if (!File.Exists(HTML_TEMPLATE_FILE)) // Briefing template not found { DebugLog.Instance.WriteLine("HTML template file not found.", 1, DebugLogMessageErrorLevel.Warning); return("HTML template file not found."); } string briefing = File.ReadAllText(HTML_TEMPLATE_FILE); // Title briefing = briefing.Replace("$MISSIONNAME$", mission.MissionName); briefing = briefing.Replace("$MISSIONTYPE$", GeneratorTools.RemoveAfterComma(template.ObjectiveType) + " mission " + ((template.GetMissionType() == MissionType.SinglePlayer) ? "(single-player)" : $"({template.GetPlayerCount()}-players multiplayer)")); // Situation summary briefing = briefing.Replace("$LONGDATE$", mission.DateTime.ToDateString(true)); briefing = briefing.Replace("$LONGTIME$", mission.DateTime.ToTimeString()); briefing = briefing.Replace("$SHORTDATE$", mission.DateTime.ToDateString(false)); briefing = briefing.Replace("$SHORTTIME$", mission.DateTime.ToTimeString()); briefing = briefing.Replace("$WEATHER$", GeneratorTools.GetEnumString(mission.Weather.WeatherLevel)); briefing = briefing.Replace("$WIND$", GeneratorTools.GetEnumString(mission.Weather.WindLevel)); briefing = briefing.Replace("$WINDSPEED$", mission.Weather.WindSpeedAverage.ToString("F0")); // Friends and enemies briefing = briefing.Replace("$PLAYERCOALITION$", GeneratorTools.RemoveAfterComma(template.GetCoalition(mission.CoalitionPlayer))); briefing = briefing.Replace("$ENEMYCOALITION$", GeneratorTools.RemoveAfterComma(template.GetCoalition(mission.CoalitionEnemy))); // Description briefing = briefing.Replace("$DESCRIPTION$", description.Replace("\n", "<br />")); // Tasks string tasksHTML = ""; foreach (string task in tasks) { tasksHTML += $"<li>{task}</li>"; } briefing = briefing.Replace("$TASKS$", tasksHTML); // Remarks string remarksHTML = ""; foreach (string remark in remarks) { remarksHTML += $"<li>{remark}</li>"; } briefing = briefing.Replace("$REMARKS$", remarksHTML); // Flight groups string flightGroupsHTML = ""; foreach (UnitFlightGroupBriefingDescription fg in flightGroups) { flightGroupsHTML += "<tr>" + $"<td>{fg.Callsign}</td>" + $"<td>{fg.Count}×{fg.Type}</td>" + $"<td>{fg.Task}</td><td>{fg.Radio}</td>" + $"<td>{fg.Remarks}</td>" + "</tr>"; } briefing = briefing.Replace("$FLIGHTGROUPS$", flightGroupsHTML); // Airbases string airbasesHTML = "<tr>" + $"<td>{airbaseDB.Name}</td>" + $"<td>{airbaseDB.Runways}</td>" + $"<td>{airbaseDB.ATC}</td>" + $"<td>{airbaseDB.ILS}</td>" + $"<td>{airbaseDB.TACAN}</td>" + "</tr>"; briefing = briefing.Replace("$AIRBASES$", airbasesHTML); string carrierHTML = ""; if (carrierDB != null) { carrierHTML = "<tr>" + $"<td>{carrierDB.ID}</td>" + $"<td>127.500AM</td>" + $"<td>11</td>" + $"<td>74X</td>" + "</tr>"; } briefing = briefing.Replace("$CARRIERS$", carrierHTML); // Waypoints string waypointsHTML = ""; double distance; double totalDistance = 0.0; Coordinates currentPosition = mission.InitialPosition; waypointsHTML += $"<tr><td><strong>TAKEOFF</strong></td><td>-</td><td>-</td></tr>"; foreach (DCSMissionWaypoint wp in mission.Waypoints) { distance = currentPosition.GetDistanceFrom(wp.Coordinates); totalDistance += distance; currentPosition = wp.Coordinates; waypointsHTML += $"<tr><td>{wp.Name}</td>" + $"<td>{GeneratorTools.ConvertDistance(distance, template.BriefingUnitSystem)}</td>" + $"<td>{GeneratorTools.ConvertDistance(totalDistance, template.BriefingUnitSystem)}</td></tr>"; } distance = currentPosition.GetDistanceFrom(mission.InitialPosition); totalDistance += distance; waypointsHTML += $"<tr><td><strong>LANDING</strong></td>" + $"<td>{GeneratorTools.ConvertDistance(distance, template.BriefingUnitSystem)}</td>" + $"<td>{GeneratorTools.ConvertDistance(totalDistance, template.BriefingUnitSystem)}</td></tr>"; briefing = briefing.Replace("$WAYPOINTS$", waypointsHTML); return(briefing); }
/// <summary> /// Generates the content of the Lua file. /// </summary> /// <param name="mission">An HQ4DCS mission.</param> /// <returns>The contents of the Lua file.</returns> public string MakeLua(DCSMission mission) { int i; string lua = LuaTools.ReadIncludeLuaFile("Mission.lua"); LuaTools.ReplaceKey(ref lua, "TheaterID", Database.Instance.GetEntry <DBEntryTheater>(mission.Theater).DCSID); LuaTools.ReplaceKey(ref lua, "PlayerCoalition", mission.CoalitionPlayer.ToString().ToLowerInvariant()); LuaTools.ReplaceKey(ref lua, "DateDay", mission.DateTime.Day); LuaTools.ReplaceKey(ref lua, "DateMonth", (int)mission.DateTime.Month + 1); LuaTools.ReplaceKey(ref lua, "DateYear", mission.DateTime.Year); LuaTools.ReplaceKey(ref lua, "StartTime", mission.DateTimeTotalSeconds); if (mission.CoalitionPlayer == Coalition.Red) { LuaTools.ReplaceKey(ref lua, "USACountryBlue", ""); LuaTools.ReplaceKey(ref lua, "USACountryRed", "[2] = 2,"); } else { LuaTools.ReplaceKey(ref lua, "USACountryBlue", "[2] = 2,"); LuaTools.ReplaceKey(ref lua, "USACountryRed", ""); } LuaTools.ReplaceKey(ref lua, "WeatherCloudsBase", mission.Weather.CloudBase); LuaTools.ReplaceKey(ref lua, "WeatherCloudsDensity", mission.Weather.CloudsDensity); LuaTools.ReplaceKey(ref lua, "WeatherCloudsPrecipitation", (int)mission.Weather.CloudsPrecipitation); LuaTools.ReplaceKey(ref lua, "WeatherCloudsThickness", mission.Weather.CloudsThickness); LuaTools.ReplaceKey(ref lua, "WeatherDustDensity", mission.Weather.DustDensity); LuaTools.ReplaceKey(ref lua, "WeatherDustEnabled", mission.Weather.DustEnabled); LuaTools.ReplaceKey(ref lua, "WeatherFogEnabled", mission.Weather.Turbulence); LuaTools.ReplaceKey(ref lua, "WeatherFogThickness", mission.Weather.FogThickness); LuaTools.ReplaceKey(ref lua, "WeatherFogVisibility", mission.Weather.FogVisibility); LuaTools.ReplaceKey(ref lua, "WeatherGroundTurbulence", mission.Weather.Turbulence); LuaTools.ReplaceKey(ref lua, "WeatherQNH", mission.Weather.QNH); LuaTools.ReplaceKey(ref lua, "WeatherTemperature", mission.Weather.Temperature); LuaTools.ReplaceKey(ref lua, "WeatherVisibilityDistance", mission.Weather.Visibility); for (i = 0; i < 3; i++) { LuaTools.ReplaceKey(ref lua, $"WeatherWind{i + 1}", mission.Weather.WindSpeed[i]); LuaTools.ReplaceKey(ref lua, $"WeatherWind{i + 1}Dir", mission.Weather.WindDirection[i]); } LuaTools.ReplaceKey(ref lua, "BullseyeBlueX", mission.Bullseye[(int)Coalition.Blue].X); LuaTools.ReplaceKey(ref lua, "BullseyeBlueY", mission.Bullseye[(int)Coalition.Blue].Y); LuaTools.ReplaceKey(ref lua, "BullseyeRedX", mission.Bullseye[(int)Coalition.Red].X); LuaTools.ReplaceKey(ref lua, "BullseyeRedY", mission.Bullseye[(int)Coalition.Red].Y); LuaTools.ReplaceKey(ref lua, "MissionName", mission.MissionName); LuaTools.ReplaceKey(ref lua, "BriefingDescription", mission.BriefingTXT, true); CreateUnitGroups(ref lua, mission); // Create unit groups Debug.DebugLog.Instance.WriteLine("Building Airbase"); DBEntryTheaterAirbase airbase = (from DBEntryTheaterAirbase ab in Database.Instance.GetEntry <DBEntryTheater>(mission.Theater).Airbases where ab.DCSID == mission.InitialAirbaseID select ab).FirstOrDefault(); LuaTools.ReplaceKey(ref lua, "MissionAirbaseID", mission.InitialAirbaseID); LuaTools.ReplaceKey(ref lua, "MissionAirbaseX", airbase.Coordinates.X); LuaTools.ReplaceKey(ref lua, "MissionAirbaseY", airbase.Coordinates.Y); if (mission.Carrier != null) { Debug.DebugLog.Instance.WriteLine("Building Carrier"); LuaTools.ReplaceKey(ref lua, "LinkUnit", mission.Carrier.ID); LuaTools.ReplaceKey(ref lua, "CarrierBaseX", mission.Carrier.Coordinates.X); LuaTools.ReplaceKey(ref lua, "CarrierBaseY", mission.Carrier.Coordinates.Y); } // The following replacements must be performed after unit groups and player waypoints have been added LuaTools.ReplaceKey(ref lua, "PlayerGroupID", mission.PlayerGroupID); LuaTools.ReplaceKey(ref lua, "InitialWPName", Database.Instance.Common.WPNameInitial); LuaTools.ReplaceKey(ref lua, "FinalWPName", Database.Instance.Common.WPNameFinal); LuaTools.ReplaceKey(ref lua, "FinalWPName", Database.Instance.Common.WPNameFinal); //Duplicate switch (mission.PlayerStartLocation) { default: // case PlayerStartLocation.ParkingCold LuaTools.ReplaceKey(ref lua, "PlayerStartingAction", "From Parking Area"); LuaTools.ReplaceKey(ref lua, "PlayerStartingType", "TakeOffParking"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAction", "From Parking Area"); // Player starts cold, AI escorts start cold too LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingType", "TakeOffParking"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAltitude", 13); break; case PlayerStartLocation.ParkingHot: LuaTools.ReplaceKey(ref lua, "PlayerStartingAction", "From Parking Area Hot"); LuaTools.ReplaceKey(ref lua, "PlayerStartingType", "TakeOffParkingHot"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAction", "From Parking Area Hot"); // Player starts hot, AI escorts start hot too LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingType", "TakeOffParkingHot"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAltitude", 13); break; case PlayerStartLocation.Runway: LuaTools.ReplaceKey(ref lua, "PlayerStartingAction", "From Runway"); LuaTools.ReplaceKey(ref lua, "PlayerStartingType", "TakeOff"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAction", "Turning Point"); // Player starts on runway, AI escorts start in air above him LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingType", "Turning Point"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAltitude", GetAircraftCruiseAltitude(UnitCategory.Plane, Amount.Average)); break; } LuaTools.ReplaceKey(ref lua, "MissionID", mission.UniqueID); return(lua); }
/// <summary> /// Generates the content of the Lua file. /// </summary> /// <param name="mission">An HQ4DCS mission.</param> /// <returns>The contents of the Lua file.</returns> public string MakeLua(DCSMission mission) { int i; string lua = LuaTools.ReadIncludeLuaFile("Mission.lua"); LuaTools.ReplaceKey(ref lua, "TheaterID", Database.Instance.GetEntry <DBEntryTheater>(mission.Theater).DCSID); LuaTools.ReplaceKey(ref lua, "PlayerCoalition", mission.CoalitionPlayer.ToString().ToLowerInvariant()); LuaTools.ReplaceKey(ref lua, "DateDay", mission.DateTime.Day); LuaTools.ReplaceKey(ref lua, "DateMonth", (int)mission.DateTime.Month + 1); LuaTools.ReplaceKey(ref lua, "DateYear", mission.DateTime.Year); LuaTools.ReplaceKey(ref lua, "StartTime", mission.DateTimeTotalSeconds); LuaTools.ReplaceKey(ref lua, "WeatherCloudsBase", mission.Weather.CloudBase); LuaTools.ReplaceKey(ref lua, "WeatherCloudsDensity", mission.Weather.CloudsDensity); LuaTools.ReplaceKey(ref lua, "WeatherCloudsPrecipitation", (int)mission.Weather.CloudsPrecipitation); LuaTools.ReplaceKey(ref lua, "WeatherCloudsThickness", mission.Weather.CloudsThickness); LuaTools.ReplaceKey(ref lua, "WeatherCloudsPreset", mission.Weather.CloudsPreset.ToString()); LuaTools.ReplaceKey(ref lua, "WeatherDustDensity", mission.Weather.DustDensity); LuaTools.ReplaceKey(ref lua, "WeatherDustEnabled", mission.Weather.DustEnabled); LuaTools.ReplaceKey(ref lua, "WeatherFogEnabled", mission.Weather.Turbulence); LuaTools.ReplaceKey(ref lua, "WeatherFogThickness", mission.Weather.FogThickness); LuaTools.ReplaceKey(ref lua, "WeatherFogVisibility", mission.Weather.FogVisibility); LuaTools.ReplaceKey(ref lua, "WeatherGroundTurbulence", mission.Weather.Turbulence); LuaTools.ReplaceKey(ref lua, "WeatherQNH", mission.Weather.QNH); LuaTools.ReplaceKey(ref lua, "WeatherTemperature", mission.Weather.Temperature); LuaTools.ReplaceKey(ref lua, "WeatherVisibilityDistance", mission.Weather.Visibility); for (i = 0; i < 3; i++) { LuaTools.ReplaceKey(ref lua, $"WeatherWind{i + 1}", mission.Weather.WindSpeed[i]); LuaTools.ReplaceKey(ref lua, $"WeatherWind{i + 1}Dir", mission.Weather.WindDirection[i]); } var neutrals = Enum.GetValues(typeof(Country)).Cast <Country>().Where(x => !mission.CountryBlues.Contains(x) && !mission.CountryReds.Contains(x)); LuaTools.ReplaceKey(ref lua, "Neutrals", Toolbox.ListToLuaString(neutrals.Cast <int>())); LuaTools.ReplaceKey(ref lua, "Reds", Toolbox.ListToLuaString(mission.CountryReds.Cast <int>())); LuaTools.ReplaceKey(ref lua, "Blues", Toolbox.ListToLuaString(mission.CountryBlues.Cast <int>())); LuaTools.ReplaceKey(ref lua, "BullseyeBlueX", mission.Bullseye[(int)Coalition.Blue].X); LuaTools.ReplaceKey(ref lua, "BullseyeBlueY", mission.Bullseye[(int)Coalition.Blue].Y); LuaTools.ReplaceKey(ref lua, "BullseyeRedX", mission.Bullseye[(int)Coalition.Red].X); LuaTools.ReplaceKey(ref lua, "BullseyeRedY", mission.Bullseye[(int)Coalition.Red].Y); LuaTools.ReplaceKey(ref lua, "MissionName", mission.MissionName); LuaTools.ReplaceKey(ref lua, "BriefingDescription", mission.BriefingTXT, true); CreateUnitGroups(ref lua, mission); // Create unit groups Debug.DebugLog.Instance.WriteLine("Building Airbase"); DBEntryTheaterAirbase airbase = (from DBEntryTheaterAirbase ab in Database.Instance.GetEntry <DBEntryTheater>(mission.Theater).Airbases where ab.DCSID == mission.InitialAirbaseID select ab).FirstOrDefault(); LuaTools.ReplaceKey(ref lua, "MissionAirbaseID", mission.InitialAirbaseID); LuaTools.ReplaceKey(ref lua, "MissionAirbaseX", airbase.Coordinates.X); LuaTools.ReplaceKey(ref lua, "MissionAirbaseY", airbase.Coordinates.Y); // The following replacements must be performed after unit groups and player waypoints have been added LuaTools.ReplaceKey(ref lua, "PlayerGroupID", mission.PlayerGroupID); LuaTools.ReplaceKey(ref lua, "InitialWPName", Database.Instance.Common.WPNameInitial); LuaTools.ReplaceKey(ref lua, "FinalWPName", Database.Instance.Common.WPNameFinal); LuaTools.ReplaceKey(ref lua, "FinalWPName", Database.Instance.Common.WPNameFinal); //Duplicate switch (mission.UnitGroups.Find(x => x.IsAPlayerGroup()).StartLocation) { default: // case PlayerStartLocation.ParkingCold LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAction", "From Parking Area"); // Player starts cold, AI escorts start cold too LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingType", "TakeOffParking"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAltitude", 13); break; case PlayerStartLocation.ParkingHot: LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAction", "From Parking Area Hot"); // Player starts hot, AI escorts start hot too LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingType", "TakeOffParkingHot"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAltitude", 13); break; case PlayerStartLocation.Runway: LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAction", "Turning Point"); // Player starts on runway, AI escorts start in air above him LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingType", "Turning Point"); LuaTools.ReplaceKey(ref lua, "PlayerEscortStartingAltitude", 10000 * Toolbox.FEET_TO_METERS); break; } LuaTools.ReplaceKey(ref lua, "MissionID", mission.UniqueID); LuaTools.ReplaceKey(ref lua, "ForcedOptions", GetForcedOptionsLua(mission)); return(lua); }
/// <summary> /// Generates the mission briefing. /// </summary> /// <param name="mission">Mission</param> /// <param name="template">Template from which the mission should be built</param> /// <param name="airbaseDB">Airbase player will take off from and land back on</param> /// <param name="coalitionsDB">Database entries for the mission coalitions</param> public void GenerateMissionBriefing(DCSMission mission, MissionTemplate template, DBEntryObjective objectiveDB, DBEntryTheaterAirbase airbaseDB, List <UnitFlightGroupBriefingDescription> flightGroups, DBEntryCoalition[] coalitionsDB) { DebugLog.Instance.WriteLine("Generating mission briefing...", 1); // Get mission features DBEntryMissionFeature[] features = Database.Instance.GetEntries <DBEntryMissionFeature>(objectiveDB.MissionFeatures); string description = objectiveDB.BriefingDescriptionByUnitFamily[(int)mission.Objectives[0].TargetFamily]; if (string.IsNullOrEmpty(description)) // No custom briefing for this target family, use the default { description = objectiveDB.BriefingDescription; } description = GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(description), mission, coalitionsDB); description = GeneratorTools.SanitizeString(description); // Generate tasks string baseName = airbaseDB.Name; // TODO: this doesn't work for lots of carriers so simplifying for now List <string> tasks = new List <string> { $"Take off from {baseName}" }; string objectiveTask = GeneratorTools.ParseRandomString(objectiveDB.BriefingTask); for (int i = 0; i < mission.Objectives.Length; i++) { string taskString = GeneratorTools.MakeBriefingStringReplacements(objectiveTask, mission, coalitionsDB, i); tasks.Add(taskString); mission.CoreLuaScript += $"briefingRoom.mission.objectives[{i + 1}].task = \"{taskString}\"\r\n"; } tasks.Add($"Return to {baseName}"); DebugLog.Instance.WriteLine($"{tasks.Count} task(s)", 2); // Generate mission remarks... List <string> remarks = new List <string>(); remarks.AddRange( // ...from objective from string remark in objectiveDB.BriefingRemarks select GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(remark), mission, coalitionsDB)); foreach (DBEntryMissionFeature feature in features) { remarks.AddRange( // ...from features from string remark in feature.BriefingRemarks select GeneratorTools.MakeBriefingStringReplacements(GeneratorTools.ParseRandomString(remark), mission, coalitionsDB)); } mission.BriefingHTML = CreateHTMLBriefing(mission, template, description, tasks, remarks, flightGroups, airbaseDB, coalitionsDB, objectiveDB); mission.BriefingTXT = CreateTXTBriefing(mission, description, tasks, remarks, flightGroups, airbaseDB); }