private Coordinates PlaceInAirbase(MissionTemplateRecord template, DBEntrySituation situationDB, DBEntryAirbase playerAirbase, List <KeyValuePair <string, object> > extraSettings, DBEntryObjectiveTarget targetDB, DBEntryObjectiveTargetBehavior targetBehaviorDB, ref string luaUnit, Coordinates objectiveCoordinates, int unitCount, UnitFamily objectiveTargetUnitFamily) { int airbaseID = 0; var parkingSpotIDsList = new List <int>(); var parkingSpotCoordinatesList = new List <Coordinates>(); var targetAirbaseOptions = (from DBEntryAirbase airbaseDB in situationDB.GetAirbases(template.OptionsMission.Contains("InvertCountriesCoalitions")) where airbaseDB.DCSID != playerAirbase.DCSID select airbaseDB).OrderBy(x => x.Coordinates.GetDistanceFrom(objectiveCoordinates)); DBEntryAirbase targetAirbase = targetAirbaseOptions.FirstOrDefault(x => template.OptionsMission.Contains("SpawnAnywhere") ? true : x.Coalition == template.ContextPlayerCoalition.GetEnemy()); airbaseID = targetAirbase.DCSID; var parkingSpots = UnitMaker.SpawnPointSelector.GetFreeParkingSpots( targetAirbase.DCSID, unitCount, objectiveTargetUnitFamily, targetBehaviorDB.Location == DBEntryObjectiveTargetBehaviorLocation.SpawnOnAirbaseParkingNoHardenedShelter); parkingSpotIDsList = parkingSpots.Select(x => x.DCSID).ToList(); parkingSpotCoordinatesList = parkingSpots.Select(x => x.Coordinates).ToList(); luaUnit += "Parked"; extraSettings.Add("GroupAirbaseID".ToKeyValuePair(airbaseID)); extraSettings.Add("ParkingID".ToKeyValuePair(parkingSpotIDsList.ToArray())); extraSettings.Add("UnitX".ToKeyValuePair((from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.X).ToArray())); extraSettings.Add("UnitY".ToKeyValuePair((from Coordinates coordinates in parkingSpotCoordinatesList select coordinates.Y).ToArray())); return(targetAirbase.Coordinates); }
internal UnitMakerSpawnPointSelector(DBEntryTheater theaterDB, DBEntrySituation situationDB, bool invertCoalition) { TheaterDB = theaterDB; SituationDB = situationDB; AirbaseParkingSpots = new Dictionary <int, List <DBEntryAirbaseParkingSpot> >(); SpawnPoints = new List <DBEntryTheaterSpawnPoint>(); InvertCoalition = invertCoalition; if (TheaterDB.SpawnPoints is not null) { SpawnPoints.AddRange(TheaterDB.SpawnPoints.Where(x => CheckNotInNoSpawnCoords(x.Coordinates)).ToList()); } foreach (DBEntryAirbase airbase in SituationDB.GetAirbases(InvertCoalition)) { if (airbase.ParkingSpots.Length < 1) { continue; } if (AirbaseParkingSpots.ContainsKey(airbase.DCSID)) { continue; } AirbaseParkingSpots.Add(airbase.DCSID, airbase.ParkingSpots.ToList()); } }
internal DrawingMaker( DCSMission mission, MissionTemplateRecord template, DBEntryTheater theaterDB, DBEntrySituation situationDB) { Mission = mission; Template = template; TheaterDB = theaterDB; SituationDB = situationDB; Clear(); AddTheaterZones(); }
internal UnitMaker( DCSMission mission, MissionTemplateRecord template, DBEntryCoalition[] coalitionsDB, DBEntryTheater theaterDB, DBEntrySituation situationDB, Coalition playerCoalition, Country[][] coalitionsCountries, bool singlePlayerMission) { CallsignGenerator = new UnitMakerCallsignGenerator(coalitionsDB); SpawnPointSelector = new UnitMakerSpawnPointSelector(theaterDB, situationDB, template.OptionsMission.Contains("InvertCountriesCoalitions")); Mission = mission; Template = template; CoalitionsDB = coalitionsDB; PlayerCoalition = playerCoalition; CoalitionsCountries = coalitionsCountries; SinglePlayerMission = singlePlayerMission; GroupID = 1; UnitID = 1; }
internal static void GenerateMissionBriefingDescription(DCSMission mission, MissionTemplateRecord template, List <UnitFamily> objectiveTargetUnitFamilies, DBEntrySituation situationDB) { // Try to get the provided custom mission description. string briefingDescription = (template.BriefingMissionDescription ?? "").Replace("\r\n", "\n").Replace("\n", " ").Trim(); // No custom description found, generate one from the most frequent objective task/target combination. if (string.IsNullOrEmpty(briefingDescription)) { if (template.Objectives.Count == 0) { briefingDescription = ""; } else { var familyCount = 0; Dictionary <string, List <string> > descriptionsMap = new Dictionary <string, List <string> >(); foreach (var obj in template.Objectives) { DBEntryBriefingDescription descriptionDB = Database.Instance.GetEntry <DBEntryBriefingDescription>( Database.Instance.GetEntry <DBEntryObjectiveTask>(obj.Task).BriefingDescription); AppendDescription(obj.Task, descriptionDB.DescriptionText[(int)objectiveTargetUnitFamilies[familyCount]], ref descriptionsMap); familyCount++; AddSubTasks(obj, objectiveTargetUnitFamilies, ref descriptionsMap, ref familyCount); } briefingDescription = ConstructTaskDescriptions(descriptionsMap, mission); } } if (situationDB.BriefingDescriptions != null && situationDB.BriefingDescriptions.Count > 0) { briefingDescription = GeneratorTools.ParseRandomString(string.Join(" ", Toolbox.RandomFrom(situationDB.BriefingDescriptions), briefingDescription), mission); } mission.Briefing.Description = briefingDescription; mission.SetValue("BRIEFINGDESCRIPTION", briefingDescription); }
internal Tuple <Coordinates, List <Waypoint> > GenerateObjective( DCSMission mission, MissionTemplateRecord template, DBEntrySituation situationDB, MissionTemplateObjectiveRecord objectiveTemplate, Coordinates lastCoordinates, DBEntryAirbase playerAirbase, bool useObjectivePreset, ref int objectiveIndex, ref List <Coordinates> objectiveCoordinatesList, ref List <Waypoint> waypoints, ref List <UnitFamily> objectiveTargetUnitFamilies) { var extraSettings = new List <KeyValuePair <string, object> >(); var waypointList = new List <Waypoint>(); string[] featuresID; DBEntryObjectiveTarget targetDB; DBEntryObjectiveTargetBehavior targetBehaviorDB; DBEntryObjectiveTask taskDB; ObjectiveOption[] objectiveOptions; GetObjectiveData(objectiveTemplate, useObjectivePreset, out featuresID, out targetDB, out targetBehaviorDB, out taskDB, out objectiveOptions); var luaUnit = targetBehaviorDB.UnitLua[(int)targetDB.UnitCategory]; Coordinates objectiveCoordinates = GetSpawnCoordinates(template, lastCoordinates, playerAirbase, targetDB); // Spawn target on airbase var unitCount = targetDB.UnitCount[(int)objectiveTemplate.TargetCount].GetValue(); var objectiveTargetUnitFamily = Toolbox.RandomFrom(targetDB.UnitFamilies); if (AIRBASE_LOCATIONS.Contains(targetBehaviorDB.Location) && targetDB.UnitCategory.IsAircraft()) { objectiveCoordinates = PlaceInAirbase(template, situationDB, playerAirbase, extraSettings, targetDB, targetBehaviorDB, ref luaUnit, objectiveCoordinates, unitCount, objectiveTargetUnitFamily); } UnitMakerGroupFlags groupFlags = 0; if (objectiveOptions.Contains(ObjectiveOption.ShowTarget)) { groupFlags = UnitMakerGroupFlags.NeverHidden; } else if (objectiveOptions.Contains(ObjectiveOption.HideTarget)) { groupFlags = UnitMakerGroupFlags.AlwaysHidden; } if (objectiveOptions.Contains(ObjectiveOption.EmbeddedAirDefense)) { groupFlags |= UnitMakerGroupFlags.EmbeddedAirDefense; } // Set destination point for moving unit groups Coordinates destinationPoint = objectiveCoordinates + ( (targetDB.UnitCategory == UnitCategory.Plane ? Coordinates.CreateRandom(30, 60) : Coordinates.CreateRandom(10, 20)) * Toolbox.NM_TO_METERS ); if (targetBehaviorDB.Location == DBEntryObjectiveTargetBehaviorLocation.GoToPlayerAirbase) { destinationPoint = playerAirbase.Coordinates; } var unitCoordinates = objectiveCoordinates; var objectiveName = Toolbox.RandomFrom(ObjectiveNames); if (TRANSPORT_TASKS.Contains(taskDB.ID)) { Coordinates?spawnPoint = UnitMaker.SpawnPointSelector.GetRandomSpawnPoint( targetDB.ValidSpawnPoints, playerAirbase.Coordinates, new MinMaxD(1, 5), coalition: GeneratorTools.GetSpawnPointCoalition(template, Side.Ally)); if (!spawnPoint.HasValue) // Failed to generate target group { throw new BriefingRoomException($"Failed to find Cargo SpawnPoint"); } unitCoordinates = spawnPoint.Value; var cargoWaypoint = GenerateObjectiveWaypoint(objectiveTemplate, unitCoordinates, $"{objectiveName} Pickup", template, true); waypoints.Add(cargoWaypoint); waypointList.Add(cargoWaypoint); if (taskDB.isEscort()) { extraSettings.Add("GroupX2".ToKeyValuePair(objectiveCoordinates.X)); extraSettings.Add("GroupY2".ToKeyValuePair(objectiveCoordinates.Y)); groupFlags |= UnitMakerGroupFlags.RadioAircraftSpawn; } } extraSettings.Add("GroupX2".ToKeyValuePair(destinationPoint.X)); extraSettings.Add("GroupY2".ToKeyValuePair(destinationPoint.Y)); UnitMakerGroupInfo?targetGroupInfo = UnitMaker.AddUnitGroup( objectiveTargetUnitFamily, unitCount, taskDB.TargetSide, targetBehaviorDB.GroupLua[(int)targetDB.UnitCategory], luaUnit, unitCoordinates, groupFlags, extraSettings.ToArray()); if (!targetGroupInfo.HasValue) // Failed to generate target group { throw new BriefingRoomException($"Failed to generate group for objective."); } if (objectiveOptions.Contains(ObjectiveOption.EmbeddedAirDefense) && (targetDB.UnitCategory == UnitCategory.Static)) { AddEmbeddedAirDefenseUnits(template, targetDB, targetBehaviorDB, taskDB, objectiveOptions, objectiveCoordinates, groupFlags, extraSettings); } var pluralIndex = targetGroupInfo.Value.UnitsID.Length == 1 ? 0 : 1; var taskString = GeneratorTools.ParseRandomString(taskDB.BriefingTask[pluralIndex], mission).Replace("\"", "''"); // Pick a name, then remove it from the list ObjectiveNames.Remove(objectiveName); CreateTaskString(mission, pluralIndex, ref taskString, objectiveName, objectiveTargetUnitFamily); CreateLua(mission, template, targetDB, taskDB, objectiveIndex, objectiveName, targetGroupInfo, taskString); // Add briefing remarks for this objective task if (taskDB.BriefingRemarks.Length > 0) { string remark = Toolbox.RandomFrom(taskDB.BriefingRemarks); GeneratorTools.ReplaceKey(ref remark, "ObjectiveName", objectiveName); GeneratorTools.ReplaceKey(ref remark, "UnitFamily", Database.Instance.Common.Names.UnitFamilies[(int)objectiveTargetUnitFamily][pluralIndex]); mission.Briefing.AddItem(DCSMissionBriefingItemType.Remark, remark); } // Add feature ogg files foreach (string oggFile in taskDB.IncludeOgg) { mission.AddMediaFile($"l10n/DEFAULT/{oggFile}", $"{BRPaths.INCLUDE_OGG}{oggFile}"); } // Add objective features Lua for this objective mission.AppendValue("ScriptObjectivesFeatures", ""); // Just in case there's no features foreach (string featureID in featuresID) { FeaturesGenerator.GenerateMissionFeature(mission, featureID, objectiveName, objectiveIndex, targetGroupInfo.Value.GroupID, objectiveCoordinates, taskDB.TargetSide, objectiveOptions.Contains(ObjectiveOption.HideTarget)); } objectiveCoordinatesList.Add(objectiveCoordinates); var waypoint = GenerateObjectiveWaypoint(objectiveTemplate, objectiveCoordinates, objectiveName, template); waypoints.Add(waypoint); waypointList.Add(waypoint); objectiveTargetUnitFamilies.Add(objectiveTargetUnitFamily); var preValidSpawns = targetDB.ValidSpawnPoints.ToList(); foreach (var subTasks in objectiveTemplate.SubTasks) { objectiveIndex++; GenerateSubTask(mission, template, situationDB, subTasks, objectiveCoordinates, playerAirbase, preValidSpawns, targetBehaviorDB.Location, featuresID, ref objectiveIndex, ref objectiveCoordinatesList, ref waypoints, ref waypointList, ref objectiveTargetUnitFamilies); } return(new (objectiveCoordinates, waypointList)); }
internal MissionGeneratorAirbases(MissionTemplateRecord template, DBEntrySituation situationDB) { _template = template; _situationDB = situationDB; }