From 4f1ad38eeb212473fb9811dd7abff0f8f6abdd7f Mon Sep 17 00:00:00 2001 From: Ambroise Garel <47314805+akaAgar@users.noreply.github.com> Date: Tue, 16 Sep 2025 12:16:58 +0200 Subject: [PATCH] Added "airbase strike" OCA mission objective --- Database/Tasks/OCAAirbase.lua | 26 +++++++++++++++++++ Script/The Universal Mission/Objectives.lua | 8 +++++- .../The Universal Mission/ObjectivesMaker.lua | 19 +++++++++++++- Script/The Universal Mission/SupportJTAC.lua | 2 +- 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 Database/Tasks/OCAAirbase.lua diff --git a/Database/Tasks/OCAAirbase.lua b/Database/Tasks/OCAAirbase.lua new file mode 100644 index 0000000..24afc21 --- /dev/null +++ b/Database/Tasks/OCAAirbase.lua @@ -0,0 +1,26 @@ +Library.tasks.ocaAirbase = { + taskFamily = DCSEx.enums.taskFamily.OCA, + description = + { + briefing = { + "Neutralizing this enemy airbase will eliminate their ability to conduct sustained air sorties and restore local air superiority.", + "Taking out this airbase will disrupt their logistics and sortie tempo, buying time for our ground forces to consolidate.", + "This airbase is the hub of enemy reconnaissance and close air support—removing it reduces battlefield intelligence and strike pressure.", + "Outlasting enemy air campaign requires degrading that facility's operational capacity to prevent rotational sorties.", + "Disabling this node of their air network constrains their command-and-control reach and limits coordinated strikes." + }, + short = "Destroy enemy airbase", + }, + conditions = { + difficultyMinimum = 0, + eras = {}, + }, + completionEvent = DCSEx.enums.taskEvent.DESTROY, + flags = { DCSEx.enums.taskFlag.ALLOW_JTAC, DCSEx.enums.taskFlag.AIRBASE_TARGET }, + minimumDistance = DCSEx.converter.nmToMeters(10.0), + safeRadius = 100, + surfaceType = land.SurfaceType.LAND, + targetCount = { 1, 1 }, + targetFamilies = { DCSEx.enums.unitFamily.STATIC_SCENERY }, + waypointInaccuracy = 0.0 +} diff --git a/Script/The Universal Mission/Objectives.lua b/Script/The Universal Mission/Objectives.lua index 091d9a3..0467977 100644 --- a/Script/The Universal Mission/Objectives.lua +++ b/Script/The Universal Mission/Objectives.lua @@ -174,7 +174,13 @@ do if event.id ~= world.event.S_EVENT_DEAD and event.id ~= world.event.S_EVENT_UNIT_LOST then return end if not event.initiator then return end - if objectives[index].isSceneryTarget then + if objectives[index].isAirbaseTarget then + if Object.getCategory(event.initiator) == Object.Category.BASE then + if DCSEx.math.isSamePoint(event.initiator:getPoint(), objectives[index].point3) then + timer.scheduleFunction(markObjectiveAsComplete, index, timer.getTime() + 3) + end + end + elseif objectives[index].isSceneryTarget then if Object.getCategory(event.initiator) == Object.Category.SCENERY then if DCSEx.math.isSamePoint(event.initiator:getPoint(), objectives[index].point3) then timer.scheduleFunction(markObjectiveAsComplete, index, timer.getTime() + 3) diff --git a/Script/The Universal Mission/ObjectivesMaker.lua b/Script/The Universal Mission/ObjectivesMaker.lua index 9146b48..b4f2d30 100644 --- a/Script/The Universal Mission/ObjectivesMaker.lua +++ b/Script/The Universal Mission/ObjectivesMaker.lua @@ -53,6 +53,7 @@ do local spawnPoint2 = nil local spawnPoint3 = nil + local isAirbaseTarget = false local isSceneryTarget = false if DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.SCENERY_TARGET) then @@ -66,6 +67,21 @@ do spawnPoint3 = DCSEx.table.deepCopy(pickedScenery:getPoint()) spawnPoint2 = DCSEx.math.vec3ToVec2(spawnPoint3) isSceneryTarget = true + elseif DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.AIRBASE_TARGET) then + local validAirbases = {} + for _,ab in ipairs(coalition.getAirbases(TUM.settings.getEnemyCoalition())) do + if DCSEx.zones.isPointInside(zone, ab:getPoint()) then + table.insert(validAirbases, ab) + end + end + if #validAirbases == 0 then + TUM.log("Failed to find a valid airbase to use as target.", TUM.logger.logLevel.WARNING) + return nil + end + local pickedAirbase = DCSEx.table.getRandom(validAirbases) + spawnPoint3 = DCSEx.table.deepCopy(pickedAirbase:getPoint()) + spawnPoint2 = DCSEx.math.vec3ToVec2(spawnPoint3) + isAirbaseTarget = true elseif objectiveDB.surfaceType == land.SurfaceType.WATER then spawnPoint2 = pickWaterPoint(zone) if not spawnPoint2 then @@ -89,6 +105,7 @@ do local objective = { completed = false, completedUnitsID = {}, + isAirbaseTarget = isAirbaseTarget, isSceneryTarget = isSceneryTarget, markerID = DCSEx.world.getNextMarkerID(), markerTextID = DCSEx.world.getNextMarkerID(), @@ -108,7 +125,7 @@ do objective.waypoint3 = DCSEx.math.vec2ToVec3(objective.waypoint2, "land") end - if not DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.SCENERY_TARGET) then + if not isAirbaseTarget and not isSceneryTarget then -- Check group options local groupOptions = {} if DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.MOVING) then diff --git a/Script/The Universal Mission/SupportJTAC.lua b/Script/The Universal Mission/SupportJTAC.lua index d4e70a0..449418d 100644 --- a/Script/The Universal Mission/SupportJTAC.lua +++ b/Script/The Universal Mission/SupportJTAC.lua @@ -60,7 +60,7 @@ do return end - if obj.isSceneryTarget then + if obj.isAirbaseTarget or obj.isSceneryTarget then TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "jtacSmokeOK", { jtacName[index], smokeColorName }, jtacName[index], true, spawnSmoke, { point3 = obj.point3, smokeColor = smokeColor }) else for _,id in ipairs(obj.unitsID) do