Пример #1
0
        private Waypoint GenerateSubTaskWaypoint(MissionTemplateSubTask objectiveTemplate, Coordinates objectiveCoordinates, string objectiveName, MissionTemplateRecord template, bool scriptIgnore = false)
        {
            var AirOnGroundBehaviorLocations = new List <DBEntryObjectiveTargetBehaviorLocation> {
                DBEntryObjectiveTargetBehaviorLocation.SpawnOnAirbaseParking,
                DBEntryObjectiveTargetBehaviorLocation.SpawnOnAirbaseParkingNoHardenedShelter
            };

            DBEntryObjectiveTarget targetDB = Database.Instance.GetEntry <DBEntryObjectiveTarget>(objectiveTemplate.Target);
            DBEntryObjectiveTargetBehaviorLocation targetBehaviorLocation = Database.Instance.GetEntry <DBEntryObjectiveTargetBehavior>(objectiveTemplate.TargetBehavior).Location;

            if (targetDB == null)
            {
                throw new BriefingRoomException($"Target \"{targetDB.UIDisplayName}\" not found for objective.");
            }

            Coordinates waypointCoordinates = objectiveCoordinates;
            bool        onGround            = !targetDB.UnitCategory.IsAircraft() || AirOnGroundBehaviorLocations.Contains(targetBehaviorLocation); // Ground targets = waypoint on the ground

            var taskDB = Database.Instance.GetEntry <DBEntryObjectiveTask>(objectiveTemplate.Task);

            if (objectiveTemplate.Options.Contains(ObjectiveOption.InaccurateWaypoint) && !TRANSPORT_TASKS.Contains(taskDB.ID))
            {
                waypointCoordinates += Coordinates.CreateRandom(3.0, 6.0) * Toolbox.NM_TO_METERS;
                if (template.OptionsMission.Contains("MarkWaypoints"))
                {
                    DrawingMaker.AddDrawing($"Target Zone {objectiveName}", DrawingType.Circle, waypointCoordinates, "Radius".ToKeyValuePair(6.0 * Toolbox.NM_TO_METERS));
                }
            }
            else if (TRANSPORT_TASKS.Contains(taskDB.ID))
            {
                DrawingMaker.AddDrawing($"Target Zone {objectiveName}", DrawingType.Circle, waypointCoordinates, "Radius".ToKeyValuePair(500));
            }

            return(new Waypoint(objectiveName, waypointCoordinates, onGround, scriptIgnore));
        }
Пример #2
0
        private void GenerateSubTask(
            DCSMission mission,
            MissionTemplateRecord template,
            DBEntrySituation situationDB,
            MissionTemplateSubTask subTask,
            Coordinates coreCoordinates,
            DBEntryAirbase playerAirbase,
            List <SpawnPointType> preValidSpawns,
            DBEntryObjectiveTargetBehaviorLocation mainObjLocation,
            string[] featuresID,
            ref int objectiveIndex,
            ref List <Coordinates> objectiveCoordinatesList,
            ref List <Waypoint> waypoints,
            ref List <Waypoint> waypointList,
            ref List <UnitFamily> objectiveTargetUnitFamilies
            )
        {
            var extraSettings = new List <KeyValuePair <string, object> >();
            DBEntryObjectiveTarget         targetDB;
            DBEntryObjectiveTargetBehavior targetBehaviorDB;
            DBEntryObjectiveTask           taskDB;

            ObjectiveOption[] objectiveOptions;

            GetSubTaskData(subTask, out targetDB, out targetBehaviorDB, out taskDB, out objectiveOptions);

            preValidSpawns.AddRange(targetDB.ValidSpawnPoints);
            if (preValidSpawns.Contains(SpawnPointType.Sea) && preValidSpawns.Any(x => LAND_SPAWNS.Contains(x)))
            {
                throw new BriefingRoomException("Cannot Mix Land and Sea Objectives. Check Sub Objective targets");
            }
            var         luaUnit = targetBehaviorDB.UnitLua[(int)targetDB.UnitCategory];
            Coordinates objectiveCoordinates = GetNearestSpawnCoordinates(template, coreCoordinates, targetDB);

            // Spawn target on airbase
            var unitCount = targetDB.UnitCount[(int)subTask.TargetCount].GetValue();
            var objectiveTargetUnitFamily = Toolbox.RandomFrom(targetDB.UnitFamilies);

            if (AIRBASE_LOCATIONS.Contains(targetBehaviorDB.Location) && !AIRBASE_LOCATIONS.Contains(mainObjLocation))
            {
                throw new BriefingRoomException("Spawning on airbase is not a valid Sub Objective unless main objective is also spawning on airbase.");
            }

            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;
            }


            extraSettings.Add("GroupX2".ToKeyValuePair(destinationPoint.X));
            extraSettings.Add("GroupY2".ToKeyValuePair(destinationPoint.Y));

            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 = GenerateSubTaskWaypoint(subTask, unitCoordinates, $"{objectiveName} Pickup", template, true);
                waypoints.Add(cargoWaypoint);
                waypointList.Add(cargoWaypoint);
                if (taskDB.isEscort())
                {
                    extraSettings.Remove("GroupX2".ToKeyValuePair(destinationPoint.X));
                    extraSettings.Remove("GroupY2".ToKeyValuePair(destinationPoint.Y));
                    extraSettings.Remove("GroupX2".ToKeyValuePair(objectiveCoordinates.X));
                    extraSettings.Add("GroupY2".ToKeyValuePair(objectiveCoordinates.Y));
                    groupFlags |= UnitMakerGroupFlags.RadioAircraftSpawn;
                }
            }

            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 = GenerateSubTaskWaypoint(subTask, objectiveCoordinates, objectiveName, template);

            waypoints.Add(waypoint);
            waypointList.Add(waypoint);
            objectiveTargetUnitFamilies.Add(objectiveTargetUnitFamily);
        }