Added "report status" wingman command

This commit is contained in:
Ambroise Garel 2025-07-24 11:20:41 +02:00
parent e0e935450a
commit d3849d1561
2 changed files with 124 additions and 6 deletions

View File

@ -98,6 +98,11 @@ Library.radioMessages = {
"Pushing up to formation.", "Pushing up to formation.",
"Visual, sliding back into position." "Visual, sliding back into position."
}, },
pilotWingmanReportStatus = {
"Flight, checking in.\n\n$1",
"Flight, reporting.\n\n$1",
"Flight, status report.\n\n$1",
},
atcSafeLanding = { "Be advised: $1 is wheels down at $2 and clear of runway.", "All aircraft, $1 has landed at $2 and vacated active. Runway is open for next inbound.", "Traffic, $1 is on deck at $2 and heading to parking. Runway clear.", "All flights, $1 just rolled out at $2 and cleared the active.", "Heads up, $1 landed at $2 and moving to the ramp. Runway available for next approach." }, atcSafeLanding = { "Be advised: $1 is wheels down at $2 and clear of runway.", "All aircraft, $1 has landed at $2 and vacated active. Runway is open for next inbound.", "Traffic, $1 is on deck at $2 and heading to parking. Runway clear.", "All flights, $1 just rolled out at $2 and cleared the active.", "Heads up, $1 landed at $2 and moving to the ramp. Runway available for next approach." },
atcSafeLandingPlayer = { "$1, wheels on deck, welcome back. You may taxi to the parking area.", "$1, good copy on landing. Exit when able, proceed to the parking area.", "$1, touchdown confirmed. Continue to parking.", "$1, welcome home. Clear of runway and taxi to parking area.", "$1, nice landing. Taxi to parking when ready." }, atcSafeLandingPlayer = { "$1, wheels on deck, welcome back. You may taxi to the parking area.", "$1, good copy on landing. Exit when able, proceed to the parking area.", "$1, touchdown confirmed. Continue to parking.", "$1, welcome home. Clear of runway and taxi to parking area.", "$1, nice landing. Taxi to parking when ready." },
@ -237,6 +242,13 @@ Library.radioMessages = {
"Flight, tighten it up.", "Flight, tighten it up.",
"Flight, rejoin tactical." "Flight, rejoin tactical."
}, },
playerFlightReportStatus = {
"Flight, confirm you're set.",
"Flight, how are you looking?",
"Flight, report in.",
"Flight, status check.",
"Flight, talk me through your state."
},
playerJTACSmoke = { playerJTACSmoke = {
"$1, request smoke on objective $2, over.", "$1, request smoke on objective $2, over.",
"$1, mark objective $2 with smoke, how copy?", "$1, mark objective $2 with smoke, how copy?",

View File

@ -24,6 +24,12 @@ do
return wingmenGroup return wingmenGroup
end end
local function getWingmenCallsign()
local wingmenGroup = getWingmenGroup()
if not wingmenGroup then return "Wingmen" end
return wingmenGroup:getUnit(1):getCallsign()
end
local function isValidTarget(detectedTarget, attributes) local function isValidTarget(detectedTarget, attributes)
attributes = attributes or {} attributes = attributes or {}
if not detectedTarget then return false end if not detectedTarget then return false end
@ -41,15 +47,21 @@ do
local function getDetectedTargets(attributes) local function getDetectedTargets(attributes)
local wingmenGroup = getWingmenGroup() local wingmenGroup = getWingmenGroup()
trigger.action.outText("A", 1)
if not wingmenGroup then return {} end if not wingmenGroup then return {} end
trigger.action.outText("B", 1)
local detectedTargets = {} local detectedTargets = {}
for _,u in ipairs(wingmenGroup:getUnits()) do for _,u in ipairs(wingmenGroup:getUnits()) do
trigger.action.outText("C", 1)
local ctrl = u:getController() local ctrl = u:getController()
if ctrl then if ctrl then
local targets = ctrl:getDetectedTargets(Controller.Detection.VISUAL, Controller.Detection.OPTIC, Controller.Detection.RADAR, Controller.Detection.RWR, Controller.Detection.IRST) trigger.action.outText("D", 1)
local targets = ctrl:getDetectedTargets() -- Controller.Detection.VISUAL, Controller.Detection.OPTIC, Controller.Detection.RADAR, Controller.Detection.RWR, Controller.Detection.IRST)
for _,t in ipairs(targets) do for _,t in ipairs(targets) do
trigger.action.outText("E", 1)
if isValidTarget(t, attributes) then if isValidTarget(t, attributes) then
trigger.action.outText("F", 1)
table.insert(detectedTargets, t.object) table.insert(detectedTargets, t.object)
end end
end end
@ -126,6 +138,53 @@ do
wingmenCtrl:setTask(taskTable) wingmenCtrl:setTask(taskTable)
end end
local function doWingmenCommandOrbit()
local player = world:getPlayer()
if not player then return end
TUM.radio.playForAll("playerFlightOrbit", nil, player:getCallsign(), false)
local wingmenGroup = getWingmenGroup()
if not wingmenGroup then return end
local wingmenCtrl = wingmenGroup:getController()
if not wingmenCtrl then return end
local taskTable = {
id = "Orbit",
params = {
pattern = "Circle",
point = DCSEx.math.vec3ToVec2(player:getPoint()),
altitude = player:getPoint().y
}
}
wingmenCtrl:setTask(taskTable)
TUM.radio.playForAll("pilotWingmanOrbit", nil, getWingmenCallsign(), true)
end
local function doWingmenCommandRejoin()
local player = world:getPlayer()
if not player then return end
TUM.radio.playForAll("playerFlightRejoin", nil, player:getCallsign(), false)
local wingmenGroup = getWingmenGroup()
if not wingmenGroup then return end
local wingmenCtrl = wingmenGroup:getController()
if not wingmenCtrl then return end
local taskTable = {
id = "Follow",
params = {
groupId = DCSEx.dcs.getObjectIDAsNumber(player:getGroup()),
pos = { x = -100, y = 0, z = -100 },
lastWptIndexFlag = false,
lastWptIndex = -1
}
}
wingmenCtrl:setTask(taskTable)
TUM.radio.playForAll("pilotWingmanRejoin", nil, getWingmenCallsign(), true)
end
local function doWingmenOrderEngage(orderID) local function doWingmenOrderEngage(orderID)
end end
@ -143,6 +202,46 @@ do
trigger.action.outText(reportText, 5) trigger.action.outText(reportText, 5)
end end
local function doWingmenCommandReportStatus(sponatenousReport)
sponatenousReport = sponatenousReport or false
local player = world:getPlayer()
if not player then return end
if not sponatenousReport then
TUM.radio.playForAll("playerFlightReportStatus", nil, player:getCallsign(), false)
end
local wingmenGroup = getWingmenGroup()
if not wingmenGroup then return end
local statusMsg = ""
for i,u in ipairs(wingmenGroup:getUnits()) do
statusMsg = statusMsg..u:getCallsign():upper()
if u:getLife() >= u:getLife0() then
statusMsg = statusMsg.."\n- No damage sustained"
else
statusMsg = statusMsg.."\n- Aircraft suffered damage"
end
statusMsg = statusMsg.."\n- BRAA from you: "..DCSEx.dcs.getBRAA(u:getPoint(), DCSEx.math.vec3ToVec2(player:getPoint()), true)
statusMsg = statusMsg.."\n- Armament: "
local ammo = u:getAmmo()
if #ammo == 0 then
statusMsg = statusMsg.."None"
else
for j,a in ipairs(ammo) do
if a.count and a.desc and (a.desc.displayName or a.desc.typeName) then
local ammoName = a.desc.displayName or a.desc.typeName
if j > 1 then statusMsg = statusMsg..", " end
statusMsg = statusMsg..tostring(a.count).."x "..ammoName
end
end
end
if i < wingmenGroup:getSize() then statusMsg = statusMsg.."\n\n" end
end
TUM.radio.playForAll("pilotWingmanReportStatus", { statusMsg }, getWingmenCallsign(), not sponatenousReport)
end
local function createWingmen() local function createWingmen()
TUM.supportWingmen.removeAll() -- Destroy all pre-existing wingmen TUM.supportWingmen.removeAll() -- Destroy all pre-existing wingmen
TUM.log("Creating wingmen...") TUM.log("Creating wingmen...")
@ -178,6 +277,7 @@ do
callsign = wingmanCallsign, callsign = wingmanCallsign,
callsignOffset = 1, callsignOffset = 1,
silenced = true, silenced = true,
skill = "Excellent",
taskFollow = DCSEx.dcs.getObjectIDAsNumber(player:getGroup()), taskFollow = DCSEx.dcs.getObjectIDAsNumber(player:getGroup()),
unlimitedFuel = true unlimitedFuel = true
} }
@ -187,16 +287,19 @@ do
TUM.log("Failed to spawn AI wingmen", TUM.logLevel.WARNING) TUM.log("Failed to spawn AI wingmen", TUM.logLevel.WARNING)
return return
end end
wingmenGroupID = groupInfo.groupID
TUM.log("Spawned AI wingmen") TUM.log("Spawned AI wingmen")
TUM.radio.playForAll("pilotWingmanRejoin", nil, "WINGMEN", true) TUM.radio.playForAll("pilotWingmanRejoin", nil, getWingmenCallsign(), true)
wingmenGroupID = groupInfo.groupID
end end
function TUM.supportWingmen.removeAll() function TUM.supportWingmen.removeAll()
if wingmenGroupID then TUM.log("Removing all wingmen...") end if not wingmenGroupID then return end
TUM.log("Removing all wingmen...")
DCSEx.world.destroyGroupByID(wingmenGroupID) DCSEx.world.destroyGroupByID(wingmenGroupID)
-- TODO: delayed "returned to base" message from wingmen?
wingmenGroupID = nil wingmenGroupID = nil
end end
@ -207,9 +310,12 @@ do
local rootPath = missionCommands.addSubMenu("Flight") local rootPath = missionCommands.addSubMenu("Flight")
missionCommands.addCommand("Engage bandits", rootPath, doWingmenOrder, TUM.supportWingmen.orderID.ENGAGE_BANDITS) missionCommands.addCommand("Engage bandits", rootPath, doWingmenOrder, TUM.supportWingmen.orderID.ENGAGE_BANDITS)
missionCommands.addCommand("Engage air defense", rootPath, doWingmenOrder, TUM.supportWingmen.orderID.ENGAGE_BANDITS)
missionCommands.addCommand("Engage ground targets", rootPath, doWingmenOrder, TUM.supportWingmen.orderID.ENGAGE_BANDITS)
missionCommands.addCommand("Report targets", rootPath, doWingmenCommandReportTargets, nil) missionCommands.addCommand("Report targets", rootPath, doWingmenCommandReportTargets, nil)
missionCommands.addCommand("Orbit", rootPath, doWingmenOrder, TUM.supportWingmen.orderID.ORBIT) missionCommands.addCommand("Report status", rootPath, doWingmenCommandReportStatus, false)
missionCommands.addCommand("Rejoin", rootPath, doWingmenOrder, TUM.supportWingmen.orderID.REJOIN) missionCommands.addCommand("Orbit", rootPath, doWingmenCommandOrbit, nil)
missionCommands.addCommand("Rejoin", rootPath, doWingmenCommandRejoin, nil)
end end
------------------------------------- -------------------------------------