mirror of
https://github.com/akaAgar/the-universal-mission-for-dcs-world.git
synced 2025-11-25 19:31:01 +00:00
Added "strike buildings", "attack infantry" and "attack MANPADS" commands
This commit is contained in:
parent
7b03e7f753
commit
f46b3d31b0
@ -90,17 +90,18 @@ do
|
||||
|
||||
-- Ground -- (radioTargetName must be singular)
|
||||
engageSubPath = missionCommands.addSubMenu("Ground", engagePath)
|
||||
missionCommands.addCommand("Any ground", engageSubPath, radioCommandEngage, { attributes = {"Tanks", "Trucks", "Artillery", "IFV", "APC"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "ground" })
|
||||
missionCommands.addCommand("Any vehicles", engageSubPath, radioCommandEngage, { attributes = {"Tanks", "Trucks", "Artillery", "IFV", "APC"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "ground" })
|
||||
missionCommands.addCommand("Armor", engageSubPath, radioCommandEngage, { attributes = {"Tanks", "IFV", "APC"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "armor" })
|
||||
missionCommands.addCommand("Artillery", engageSubPath, radioCommandEngage, { attributes = {"Artillery"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "artillery" })
|
||||
missionCommands.addCommand("Trucks", engageSubPath, radioCommandEngage, { attributes = {"Trucks"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "unarmed" })
|
||||
missionCommands.addCommand("Infantry", engageSubPath, radioCommandEngage, { attributes = {"Infantry"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "infantry" })
|
||||
missionCommands.addCommand("Trucks", engageSubPath, radioCommandEngage, { attributes = {"Trucks"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "truck" })
|
||||
|
||||
-- Air defense -- (radioTargetName must be singular)
|
||||
engageSubPath = missionCommands.addSubMenu("Air defense", engagePath)
|
||||
missionCommands.addCommand("Any air defense", engageSubPath, radioCommandEngage, { attributes = { "Air Defence" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "air defense" })
|
||||
missionCommands.addCommand("AAA", engageSubPath, radioCommandEngage, { attributes = { "AAA" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "AAA" })
|
||||
if not isWW2 then
|
||||
missionCommands.addCommand("MANPADS", engageSubPath, radioCommandEngage, { attributes = { "SR SAM", "IR Guided SAM" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "MANPADS" })
|
||||
missionCommands.addCommand("MANPADS", engageSubPath, radioCommandEngage, { attributes = { "MANPADS" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "MANPADS" })
|
||||
missionCommands.addCommand("Short range SAMs", engageSubPath, radioCommandEngage, { attributes = { "SR SAM", "IR Guided SAM" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "SHORAD" })
|
||||
missionCommands.addCommand("Long-range SAMs", engageSubPath, radioCommandEngage, { attributes = { "LR SAM", "MR SAM" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "HIMAD" })
|
||||
end
|
||||
@ -110,6 +111,9 @@ do
|
||||
missionCommands.addCommand("Any ship", engageSubPath, radioCommandEngage, { attributes = nil, category = Group.Category.SHIP, radioMessageSuffix = "Ships", radioTargetName = "ships" })
|
||||
missionCommands.addCommand("Armed ships", engageSubPath, radioCommandEngage, { attributes = { "Armed ships" }, category = Group.Category.SHIP, radioMessageSuffix = "Ships", radioTargetName = "armed ships" })
|
||||
missionCommands.addCommand("Cargo ships", engageSubPath, radioCommandEngage, { attributes = { "Unarmed ships" }, category = Group.Category.SHIP, radioMessageSuffix = "Ships", radioTargetName = "cargo ships" })
|
||||
|
||||
-- Structures
|
||||
missionCommands.addCommand("Structures", engagePath, radioCommandEngage, { attributes = nil, category = "strike", radioMessageSuffix = "Strike", radioTargetName = "building" })
|
||||
------------------------------------------------------
|
||||
|
||||
-- missionCommands.addCommand("Go to map marker "..TUM.wingmenTasking.DEFAULT_MARKER_TEXT:upper(), rootPath, radioCommandGoToMapMarker, nil)
|
||||
|
||||
@ -11,7 +11,8 @@ do
|
||||
local mapMarkerMissingWarningAlreadyDisplayed = false -- Was the "map marker missing" warning already displayed during the mission?
|
||||
local targetPointMapMarker = nil
|
||||
|
||||
local currentTargetedGroupID = nil
|
||||
local currentTargetIDorPoint = nil -- ID for groups/statics, point2 for scenery objects
|
||||
local currentTargetType = nil
|
||||
|
||||
local function allowWeaponUse(wingmenCtrl, allowUse)
|
||||
allowUse = allowUse or false
|
||||
@ -20,6 +21,76 @@ do
|
||||
wingmenCtrl:setOption(AI.Option.Air.id.PROHIBIT_AG, not allowUse)
|
||||
end
|
||||
|
||||
local function doCommandEngageStrikeTargets()
|
||||
-- Not a strike mission, so no strike targets
|
||||
if TUM.settings.getValue(TUM.settings.id.TASKING) ~= DCSEx.enums.taskFamily.STRIKE then return nil end
|
||||
|
||||
local wingmenCtrl = TUM.wingmen.getController()
|
||||
if not wingmenCtrl then return nil end
|
||||
|
||||
local wingmenPosition = DCSEx.world.getGroupCenter(TUM.wingmen.getGroup())
|
||||
|
||||
-- Look for nearest strike target
|
||||
local nearestDistance = 9999999999
|
||||
local nearestTarget = nil
|
||||
local nearestTargetType = nil
|
||||
|
||||
for i=1,TUM.objectives.getCount() do
|
||||
local obj = TUM.objectives.getObjective(i)
|
||||
if obj and not obj.completed then
|
||||
-- TODO: check distance
|
||||
local objectiveDB = Library.tasks[obj.taskID]
|
||||
if objectiveDB.targetFamilies and #objectiveDB.targetFamilies > 0 then
|
||||
allowWeaponUse(wingmenCtrl, true)
|
||||
|
||||
local distanceFromTarget = DCSEx.math.getDistance2D(wingmenPosition, obj.point2)
|
||||
|
||||
if distanceFromTarget < nearestDistance then -- TODO: distanceFromTarget < maxSearchDist
|
||||
if objectiveDB.targetFamilies[1] == DCSEx.enums.unitFamily.STATIC_SCENERY then
|
||||
nearestDistance = distanceFromTarget
|
||||
nearestTargetType = "scenery"
|
||||
nearestTarget = obj.point2
|
||||
elseif obj.unitsID and #obj.unitsID >= 1 then
|
||||
nearestDistance = distanceFromTarget
|
||||
nearestTargetType = "static"
|
||||
nearestTarget = obj.unitsID[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not nearestTarget or not nearestTargetType then return nil end
|
||||
|
||||
if nearestTargetType == "static" then
|
||||
currentTargetType = nearestTargetType
|
||||
currentTargetIDorPoint = nearestTarget
|
||||
local taskTable = {
|
||||
id = "AttackUnit",
|
||||
params = {
|
||||
groupAttack = true,
|
||||
unitId = nearestTarget,
|
||||
}
|
||||
}
|
||||
wingmenCtrl:setTask(taskTable)
|
||||
return DCSEx.world.getStaticObjectByID(nearestTarget):getPoint()
|
||||
elseif nearestTargetType == "scenery" then
|
||||
currentTargetType = nearestTargetType
|
||||
currentTargetIDorPoint = nearestTarget
|
||||
local taskTable = {
|
||||
id = "AttackMapObject",
|
||||
params = {
|
||||
groupAttack = true,
|
||||
point = nearestTarget,
|
||||
}
|
||||
}
|
||||
wingmenCtrl:setTask(taskTable)
|
||||
return DCSEx.math.vec2ToVec3(nearestTarget, "land")
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local function getOrbitTaskTable(point2)
|
||||
return {
|
||||
id = "Orbit",
|
||||
@ -53,7 +124,17 @@ do
|
||||
local wingmenCtrl = TUM.wingmen.getController()
|
||||
if not wingmenCtrl then return end
|
||||
|
||||
allowWeaponUse(wingmenCtrl, true)
|
||||
-- Strike targets are handled differently
|
||||
if groupCategory == "strike" then
|
||||
local targetPoint3 = doCommandEngageStrikeTargets()
|
||||
|
||||
if targetPoint3 then
|
||||
TUM.radio.playForAll("pilotWingmanEngageStrike", { TUM.wingmen.getFirstWingmanNumber(), DCSEx.dcs.getBRAA(targetPoint3, DCSEx.world.getGroupCenter(TUM.wingmen.getGroup()), false) }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
else
|
||||
TUM.radio.playForAll("pilotWingmanEngageNoTarget", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local detectedContacts = TUM.wingmenContacts.getContacts(groupCategory)
|
||||
local validTargets = {}
|
||||
@ -80,34 +161,47 @@ do
|
||||
end
|
||||
|
||||
if #validTargets == 0 then
|
||||
TUM.radio.playForAll("pilotWingmanEngageNoTarget", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), true)
|
||||
TUM.radio.playForAll("pilotWingmanEngageNoTarget", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
return
|
||||
end
|
||||
|
||||
local wingmenPosition = DCSEx.world.getGroupCenter(TUM.wingmen.getGroup())
|
||||
|
||||
|
||||
validTargets = DCSEx.dcs.getNearestObjects(wingmenPosition, validTargets, 1)
|
||||
local target = validTargets[1]
|
||||
currentTargetedGroupID = DCSEx.dcs.getGroupIDAsNumber(target:getGroup())
|
||||
currentTargetIDorPoint = DCSEx.dcs.getGroupIDAsNumber(target:getGroup())
|
||||
currentTargetType = "group"
|
||||
|
||||
-- If target is tough, make everyone attack it. Else, only one aircraft attack to save ammo
|
||||
local allWingmenShouldAttack = false
|
||||
if target:hasAttribute("Heavy armed ships") then
|
||||
allWingmenShouldAttack = true
|
||||
elseif (target:hasAttribute("MR SAM") or target:hasAttribute("MR SAM")) and target:hasAttribute("SAM TR") then
|
||||
allWingmenShouldAttack = true
|
||||
end
|
||||
|
||||
local taskTable = {
|
||||
id = "AttackGroup",
|
||||
params = {
|
||||
groupId = currentTargetedGroupID,
|
||||
groupAttack = allWingmenShouldAttack,
|
||||
groupId = currentTargetIDorPoint,
|
||||
}
|
||||
}
|
||||
allowWeaponUse(wingmenCtrl, true)
|
||||
wingmenCtrl:setTask(taskTable)
|
||||
-- wingmenCtrl:pushTask(getRejoinTaskTable()) -- Makes sure wingmen rejoin with the player after attack
|
||||
|
||||
local targetBRAA = ""
|
||||
local targetInfo = nil
|
||||
local messageSuffix = nil
|
||||
if target:inAir() then
|
||||
messageSuffix = "Air"
|
||||
targetInfo = Library.objectNames.getGeneric(target)..", "
|
||||
targetInfo = targetInfo..DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, true)
|
||||
targetInfo = Library.objectNames.getGeneric(target)
|
||||
targetBRAA = targetInfo..DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, true)
|
||||
else
|
||||
messageSuffix = "Surface"
|
||||
targetInfo = Library.objectNames.getGeneric(target)..", "
|
||||
targetInfo = targetInfo..DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, false)
|
||||
targetInfo = Library.objectNames.getGeneric(target)
|
||||
targetBRAA = targetInfo..DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, false)
|
||||
end
|
||||
|
||||
-- Mark the last targeted point in debug mode
|
||||
@ -120,7 +214,7 @@ do
|
||||
trigger.action.markToAll(targetPointMapMarker, "Last wingmen attack point", target:getPoint(), true)
|
||||
end
|
||||
|
||||
TUM.radio.playForAll("pilotWingmanEngage"..messageSuffix, { TUM.wingmen.getFirstWingmanNumber(), targetInfo }, TUM.wingmen.getFirstWingmanCallsign(), true)
|
||||
TUM.radio.playForAll("pilotWingmanEngage"..messageSuffix, { TUM.wingmen.getFirstWingmanNumber(), targetInfo, targetBRAA }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
end
|
||||
|
||||
function TUM.wingmenTasking.commandGoToMapMarker(markerText, delayRadioAnswer)
|
||||
@ -137,16 +231,16 @@ do
|
||||
local wingmenCtrl = TUM.wingmen.getController()
|
||||
if not wingmenCtrl then return end
|
||||
|
||||
allowWeaponUse(wingmenCtrl, false)
|
||||
|
||||
if not mapMarker then
|
||||
-- TUM.radio.playForAll("pilotWingmanGoToMarkerNoMarker", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), true)
|
||||
-- TUM.radio.playForAll("pilotWingmanGoToMarkerNoMarker", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
return
|
||||
end
|
||||
|
||||
currentTargetedGroupID = nil
|
||||
currentTargetIDorPoint = nil
|
||||
allowWeaponUse(wingmenCtrl, false)
|
||||
wingmenCtrl:setTask(getOrbitTaskTable(DCSEx.math.vec3ToVec2(mapMarker.pos)))
|
||||
-- TUM.radio.playForAll("pilotWingmanGoToMarker", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), true)
|
||||
-- TUM.radio.playForAll("pilotWingmanGoToMarker", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
end
|
||||
|
||||
function TUM.wingmenTasking.commandOrbit(delayRadioAnswer)
|
||||
@ -158,7 +252,7 @@ do
|
||||
|
||||
allowWeaponUse(wingmenCtrl, false)
|
||||
|
||||
currentTargetedGroupID = nil
|
||||
currentTargetIDorPoint = nil
|
||||
wingmenCtrl:setTask(getOrbitTaskTable(DCSEx.world.getGroupCenter(TUM.wingmen.getGroup())))
|
||||
TUM.radio.playForAll("pilotWingmanOrbit", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
end
|
||||
@ -174,9 +268,8 @@ do
|
||||
local wingmenCtrl = TUM.wingmen.getController()
|
||||
if not wingmenCtrl then return end
|
||||
|
||||
currentTargetIDorPoint = nil
|
||||
allowWeaponUse(wingmenCtrl, false)
|
||||
|
||||
currentTargetedGroupID = nil
|
||||
wingmenCtrl:setTask(getRejoinTaskTable(formationDistance))
|
||||
if not silent then
|
||||
TUM.radio.playForAll("pilotWingmanRejoin", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
@ -192,7 +285,7 @@ do
|
||||
|
||||
if not reportString then
|
||||
if noReportIfNoContacts then return false end
|
||||
TUM.radio.playForAll("pilotWingmanReportContactsNoJoy", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), true)
|
||||
TUM.radio.playForAll("pilotWingmanReportContactsNoJoy", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
return true
|
||||
else
|
||||
TUM.radio.playForAll("pilotWingmanReportContacts", { TUM.wingmen.getFirstWingmanNumber(), reportString }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer)
|
||||
@ -242,12 +335,26 @@ do
|
||||
-- Called on every mission update tick (every 10-20 seconds)
|
||||
----------------------------------------------------------
|
||||
function TUM.wingmenTasking.onClockTick()
|
||||
-- Targeted group is dead? Mark group as nil and rejoin leader
|
||||
if currentTargetedGroupID then
|
||||
local tgtGroup = DCSEx.world.getGroupByID(currentTargetedGroupID)
|
||||
if not currentTargetIDorPoint then return end
|
||||
|
||||
-- Targeted object is dead? Mark currentTargetID as nil and rejoin leader
|
||||
if currentTargetType == "group" then
|
||||
local tgtGroup = DCSEx.world.getGroupByID(currentTargetIDorPoint)
|
||||
if not tgtGroup or tgtGroup:getSize() == 0 then
|
||||
TUM.wingmenTasking.commandRejoin(nil, false)
|
||||
tgtGroup = nil
|
||||
currentTargetIDorPoint = nil
|
||||
end
|
||||
elseif currentTargetType == "static" then
|
||||
local tgtStatic = DCSEx.world.getStaticObjectByID(currentTargetIDorPoint)
|
||||
if not tgtStatic then
|
||||
TUM.wingmenTasking.commandRejoin(nil, false)
|
||||
currentTargetIDorPoint = nil
|
||||
end
|
||||
elseif currentTargetType == "scenery" then
|
||||
local sceneriesInZone = DCSEx.world.getSceneriesInZone(currentTargetIDorPoint, 5)
|
||||
if not sceneriesInZone or #sceneriesInZone == 0 or sceneriesInZone[1]:getLife() < 1 then
|
||||
TUM.wingmenTasking.commandRejoin(nil, false)
|
||||
currentTargetIDorPoint = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user