protected void AddBriefingRemarkFromFeature(T featureDB, DCSMission mission, bool useEnemyRemarkIfAvailable, UnitMakerGroupInfo?groupInfo, Dictionary <string, object> stringReplacements) { string[] remarks; if (useEnemyRemarkIfAvailable && featureDB.BriefingRemarks[(int)Side.Enemy].Length > 0) { remarks = featureDB.BriefingRemarks[(int)Side.Enemy].ToArray(); } else { remarks = featureDB.BriefingRemarks[(int)Side.Ally].ToArray(); } if (remarks.Length == 0) { return; // No briefing remarks for this feature } string remark = Toolbox.RandomFrom(remarks); foreach (KeyValuePair <string, object> stringReplacement in stringReplacements) { GeneratorTools.ReplaceKey(ref remark, stringReplacement.Key, stringReplacement.Value.ToString()); } if (groupInfo.HasValue) { GeneratorTools.ReplaceKey(ref remark, "GroupName", groupInfo.Value.Name); GeneratorTools.ReplaceKey(ref remark, "GroupFrequency", GeneratorTools.FormatRadioFrequency(groupInfo.Value.Frequency)); GeneratorTools.ReplaceKey(ref remark, "GroupUnitName", groupInfo.Value.UnitDB.UIDisplayName); } mission.Briefing.AddItem(DCSMissionBriefingItemType.Remark, remark, featureDB is DBEntryFeatureMission); }
private static void GenerateFOB( UnitMaker unitMaker, ZoneMaker zoneMaker, MissionTemplateFlightGroupRecord flightGroup, Dictionary <string, UnitMakerGroupInfo> carrierDictionary, DCSMission mission, MissionTemplateRecord template, Coordinates landbaseCoordinates, Coordinates objectivesCenter) { DBEntryTheater theaterDB = Database.Instance.GetEntry <DBEntryTheater>(template.ContextTheater); if (theaterDB == null) { return; // Theater doesn't exist. Should never happen. } Coordinates?spawnPoint = unitMaker.SpawnPointSelector.GetRandomSpawnPoint( new SpawnPointType[] { SpawnPointType.LandLarge }, landbaseCoordinates, new MinMaxD(5, template.FlightPlanObjectiveDistance), objectivesCenter, new MinMaxD(10, template.FlightPlanObjectiveDistance / 2), template.ContextPlayerCoalition); if (!spawnPoint.HasValue) { BriefingRoom.PrintToLog($"No spawn point found for FOB air defense unit groups", LogMessageErrorLevel.Warning); return; } DBEntryUnit unitDB = Database.Instance.GetEntry <DBEntryUnit>(flightGroup.Carrier); if (unitDB == null) { return; // Unit doesn't exist or is not a carrier } double radioFrequency = 127.5 + carrierDictionary.Count; var FOBNames = new List <string> { "FOB_London", "FOB_Dallas", "FOB_Paris", "FOB_Moscow", "FOB_Berlin" }; UnitMakerGroupInfo?groupInfo = unitMaker.AddUnitGroup( unitDB.Families[0], 1, Side.Ally, "GroupStatic", "UnitStaticFOB", spawnPoint.Value, 0, "FOBCallSignIndex".ToKeyValuePair(FOBNames.IndexOf(flightGroup.Carrier) + 1), "RadioBand".ToKeyValuePair((int)RadioModulation.AM), "RadioFrequency".ToKeyValuePair(GeneratorTools.GetRadioFrenquency(radioFrequency))); if (!groupInfo.HasValue || (groupInfo.Value.UnitsID.Length == 0)) { return; // Couldn't generate group } zoneMaker.AddCTLDPickupZone(spawnPoint.Value, true); mission.Briefing.AddItem( DCSMissionBriefingItemType.Airbase, $"{unitDB.UIDisplayName}\t-\t{GeneratorTools.FormatRadioFrequency(radioFrequency)}\t\t"); carrierDictionary.Add(flightGroup.Carrier, groupInfo.Value); // This bit limits FOBS to one per game think about how we can fix this }
private static void SaveFlightGroup(DCSMission mission, UnitMakerGroupInfo?groupInfo, MissionTemplateFlightGroupRecord flightGroup, DBEntryUnit unitDB, string homeBase) { mission.Briefing.AddItem(DCSMissionBriefingItemType.FlightGroup, $"{groupInfo.Value.Name}(P)\t" + $"{flightGroup.Count}× {unitDB.UIDisplayName}\t" + $"{GeneratorTools.FormatRadioFrequency(unitDB.AircraftData.RadioFrequency)}\t" + $"{Toolbox.FormatPayload(flightGroup.Payload)}\t" + $"{homeBase}"); for (int i = 0; i < flightGroup.Count; i++) { mission.AppendValue("SCRIPTCLIENTPILOTNAMES", $"\"{groupInfo.Value.Name} {i + 2}\","); } }
private void SpawnExtraGroups(T featureDB, DCSMission mission, Side groupSide, UnitMakerGroupFlags groupFlags, Coordinates coordinates, Coordinates coordinates2, Dictionary <string, object> extraSettings) { foreach (var i in Enumerable.Range(1, featureDB.ExtraGroups.GetValue())) { var groupLua = featureDB.UnitGroupLuaGroup; var unitCount = featureDB.UnitGroupSize.GetValue(); var unitFamily = Toolbox.RandomFrom(featureDB.UnitGroupFamilies); var luaUnit = featureDB.UnitGroupLuaUnit; var spawnCoords = _unitMaker.SpawnPointSelector.GetRandomSpawnPoint( featureDB.UnitGroupValidSpawnPoints, coordinates, new MinMaxD(0, 5), coalition: GeneratorTools.GetSpawnPointCoalition(_template, groupSide) ); if (!spawnCoords.HasValue) { continue; } SetAirbase(featureDB, unitFamily, ref groupLua, ref luaUnit, groupSide, ref coordinates, coordinates2, unitCount, ref extraSettings); var groupInfo = _unitMaker.AddUnitGroup( unitFamily, unitCount, groupSide, groupLua, luaUnit, spawnCoords.Value, groupFlags, extraSettings.ToArray()); if ( groupSide == Side.Ally && groupInfo.HasValue && groupInfo.Value.UnitDB != null && groupInfo.Value.UnitDB.IsAircraft) { mission.Briefing.AddItem(DCSMissionBriefingItemType.FlightGroup, $"{groupInfo.Value.Name}\t" + $"{unitCount}× {groupInfo.Value.UnitDB.UIDisplayName}\t" + $"{GeneratorTools.FormatRadioFrequency(groupInfo.Value.Frequency)}\t" + $"{Toolbox.FormatPayload(featureDB.UnitGroupPayload)}"); } } }
protected UnitMakerGroupInfo?AddMissionFeature(T featureDB, DCSMission mission, Coordinates coordinates, Coordinates?coordinates2, ref Dictionary <string, object> extraSettings, Side?objectiveTargetSide = null, bool hideEnemy = false) { // Add secondary coordinates (destination point) to the extra settings if (!coordinates2.HasValue) { coordinates2 = coordinates; // No destination point? Use initial point } extraSettings.AddIfKeyUnused("GroupX2", coordinates2.Value.X); extraSettings.AddIfKeyUnused("GroupY2", coordinates2.Value.Y); var TACANStr = GetExtraSettingsFromFeature(featureDB, ref extraSettings); // Add specific settings for this feature (TACAN frequencies, etc) // Feature unit group UnitMakerGroupInfo?groupInfo = null; if (FeatureHasUnitGroup(featureDB)) { UnitMakerGroupFlags groupFlags = 0; if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.ImmediateAircraftActivation)) { groupFlags |= UnitMakerGroupFlags.ImmediateAircraftSpawn; } if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.RadioAircraftActivation)) { groupFlags |= UnitMakerGroupFlags.RadioAircraftSpawn; } Side groupSide = Side.Enemy; if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.Friendly)) { groupSide = Side.Ally; } else if (featureDB.UnitGroupFlags.HasFlag(FeatureUnitGroupFlags.SameSideAsTarget) && objectiveTargetSide.HasValue) { groupSide = objectiveTargetSide.Value; } if (hideEnemy && groupSide == Side.Enemy) { groupFlags |= UnitMakerGroupFlags.AlwaysHidden; } extraSettings.AddIfKeyUnused("Payload", featureDB.UnitGroupPayload); var groupLua = featureDB.UnitGroupLuaGroup; var unitCount = featureDB.UnitGroupSize.GetValue(); var unitFamily = Toolbox.RandomFrom(featureDB.UnitGroupFamilies); var luaUnit = featureDB.UnitGroupLuaUnit; SetAirbase(featureDB, unitFamily, ref groupLua, ref luaUnit, groupSide, ref coordinates, coordinates2.Value, unitCount, ref extraSettings); groupInfo = _unitMaker.AddUnitGroup( unitFamily, unitCount, groupSide, groupLua, luaUnit, coordinates, groupFlags, extraSettings.ToArray()); if ( groupSide == Side.Ally && groupInfo.HasValue && groupInfo.Value.UnitDB != null && groupInfo.Value.UnitDB.IsAircraft) { mission.Briefing.AddItem(DCSMissionBriefingItemType.FlightGroup, $"{groupInfo.Value.Name}\t" + $"{unitCount}× {groupInfo.Value.UnitDB.UIDisplayName}\t" + $"{GeneratorTools.FormatRadioFrequency(groupInfo.Value.Frequency)}{TACANStr}\t" + $"{Toolbox.FormatPayload(featureDB.UnitGroupPayload)}"); // TODO: human-readable payload name } if (featureDB.ExtraGroups.Max > 1) { SpawnExtraGroups(featureDB, mission, groupSide, groupFlags, coordinates, coordinates2.Value, extraSettings); } } // Feature Lua script string featureLua = ""; // Adds the features' group ID to the briefingRoom.mission.missionFeatures.groupsID table if (this is MissionGeneratorFeaturesMission) { featureLua += $"briefingRoom.mission.missionFeatures.groupsID.{GeneratorTools.LowercaseFirstCharacter(featureDB.ID)} = {(groupInfo.HasValue ? groupInfo.Value.GroupID : 0)}\n"; featureLua += $"briefingRoom.mission.missionFeatures.unitsID.{GeneratorTools.LowercaseFirstCharacter(featureDB.ID)} = {{{(groupInfo.HasValue ? string.Join(",", groupInfo.Value.UnitsID) : "")}}}\n"; } if (!string.IsNullOrEmpty(featureDB.IncludeLuaSettings)) { featureLua = featureDB.IncludeLuaSettings + "\n"; } foreach (string luaFile in featureDB.IncludeLua) { featureLua += Toolbox.ReadAllTextIfFileExists($"{featureDB.SourceLuaDirectory}{luaFile}") + "\n"; } foreach (KeyValuePair <string, object> extraSetting in extraSettings) { GeneratorTools.ReplaceKey(ref featureLua, extraSetting.Key, extraSetting.Value); } if (groupInfo.HasValue) { GeneratorTools.ReplaceKey(ref featureLua, "FeatureGroupID", groupInfo.Value.GroupID); } if (featureDB is DBEntryFeatureObjective) { mission.AppendValue("ScriptObjectivesFeatures", featureLua); } else { mission.AppendValue("ScriptMissionFeatures", featureLua); } // Add feature ogg files foreach (string oggFile in featureDB.IncludeOgg) { mission.AddMediaFile($"l10n/DEFAULT/{oggFile}", $"{BRPaths.INCLUDE_OGG}{oggFile}"); } return(groupInfo); }
internal static Dictionary <string, UnitMakerGroupInfo> GenerateCarrierGroup( UnitMaker unitMaker, ZoneMaker zoneMaker, DCSMission mission, MissionTemplateRecord template, Coordinates landbaseCoordinates, Coordinates objectivesCenter, double windSpeedAtSeaLevel, double windDirectionAtSeaLevel) { Dictionary <string, UnitMakerGroupInfo> carrierDictionary = new Dictionary <string, UnitMakerGroupInfo>(StringComparer.InvariantCultureIgnoreCase); DBEntryTheater theaterDB = Database.Instance.GetEntry <DBEntryTheater>(template.ContextTheater); double carrierSpeed = Math.Max( Database.Instance.Common.CarrierGroup.MinimumCarrierSpeed, Database.Instance.Common.CarrierGroup.IdealWindOfDeck - windSpeedAtSeaLevel); if (windSpeedAtSeaLevel == 0) // No wind? Pick a random direction so carriers don't always go to a 0 course when wind is calm. { windDirectionAtSeaLevel = Toolbox.RandomDouble(Toolbox.TWO_PI); } var carrierPathDeg = ((windDirectionAtSeaLevel + Math.PI) % Toolbox.TWO_PI) * Toolbox.RADIANS_TO_DEGREES; var usedCoordinates = new List <Coordinates>(); foreach (MissionTemplateFlightGroupRecord flightGroup in template.PlayerFlightGroups) { if (string.IsNullOrEmpty(flightGroup.Carrier)) { continue; // No carrier for } if (carrierDictionary.ContainsKey(flightGroup.Carrier)) { continue; // Carrier type already added } if (flightGroup.Carrier.StartsWith("FOB")) { //It Carries therefore carrier not because I can't think of a name to rename this lot GenerateFOB(unitMaker, zoneMaker, flightGroup, carrierDictionary, mission, template, landbaseCoordinates, objectivesCenter); continue; } DBEntryUnit unitDB = Database.Instance.GetEntry <DBEntryUnit>(flightGroup.Carrier); if ((unitDB == null) || !unitDB.Families.Any(x => x.IsCarrier())) { continue; // Unit doesn't exist or is not a carrier } var(shipCoordinates, shipDestination) = GetSpawnAndDestination(unitMaker, template, theaterDB, usedCoordinates, landbaseCoordinates, objectivesCenter, carrierPathDeg); usedCoordinates.Add(shipCoordinates); string cvnID = carrierDictionary.Count > 0 ? (carrierDictionary.Count + 1).ToString() : ""; int ilsChannel = 11 + carrierDictionary.Count; double radioFrequency = 127.5 + carrierDictionary.Count; string tacanCallsign = $"CVN{cvnID}"; int tacanChannel = 74 + carrierDictionary.Count; UnitMakerGroupInfo?groupInfo = unitMaker.AddUnitGroup( new string[] { unitDB.ID }, Side.Ally, unitDB.Families[0], "GroupShipCarrier", "UnitShip", shipCoordinates, 0, "GroupX2".ToKeyValuePair(shipDestination.X), "GroupY2".ToKeyValuePair(shipDestination.Y), "ILS".ToKeyValuePair(ilsChannel), "RadioBand".ToKeyValuePair((int)RadioModulation.AM), "RadioFrequency".ToKeyValuePair(GeneratorTools.GetRadioFrenquency(radioFrequency)), "Speed".ToKeyValuePair(carrierSpeed), "TACANCallsign".ToKeyValuePair(tacanCallsign), "TACANChannel".ToKeyValuePair(tacanChannel), "TACANFrequency".ToKeyValuePair(GeneratorTools.GetTACANFrequency(tacanChannel, 'X', false)), "TACANMode".ToKeyValuePair("X")); if (!groupInfo.HasValue || (groupInfo.Value.UnitsID.Length == 0)) { continue; // Couldn't generate group } mission.Briefing.AddItem( DCSMissionBriefingItemType.Airbase, $"{unitDB.UIDisplayName}\t-\t{GeneratorTools.FormatRadioFrequency(radioFrequency)}\t{ilsChannel}\t{tacanCallsign}, {tacanChannel}X"); carrierDictionary.Add(flightGroup.Carrier, groupInfo.Value); } return(carrierDictionary); }