diff --git a/Script/The Universal Mission/WingmenMenu.lua b/Script/The Universal Mission/WingmenMenu.lua index 3b47ef8..8c48ff3 100644 --- a/Script/The Universal Mission/WingmenMenu.lua +++ b/Script/The Universal Mission/WingmenMenu.lua @@ -6,6 +6,15 @@ TUM.wingmenMenu = {} do + local function radioCommandChangeAltitude(args) + local player = world:getPlayer() + if not player then return end + + TUM.radio.playForAll("playerWingmanChangeAltitude", { args.altitudeText }, player:getCallsign(), false) + + TUM.wingmenTasking.commandChangeAltitude(args.altitudeFraction, true) + end + local function radioCommandCoverMe(args) local player = world:getPlayer() if not player then return end @@ -92,6 +101,8 @@ do engageSubPath = missionCommands.addSubMenu("Ground", engagePath) missionCommands.addCommand("Any ground 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("Armor (APCs only)", engageSubPath, radioCommandEngage, { attributes = {"IFV", "APC"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "armor" }) + missionCommands.addCommand("Armor (tanks only)", engageSubPath, radioCommandEngage, { attributes = {"Tanks"}, 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("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" }) @@ -121,6 +132,19 @@ do -- missionCommands.addCommand("Go to map marker "..TUM.wingmenTasking.DEFAULT_MARKER_TEXT:upper(), rootPath, radioCommandGoToMapMarker, nil) missionCommands.addCommand("Report contacts", rootPath, radioCommandReportContacts, nil) missionCommands.addCommand("Hold position", rootPath, radioCommandOrbit, nil) + + ------------------------------------------------------ + -- "Change altitude" submenu + ------------------------------------------------------ + local altitudePath = missionCommands.addSubMenu("Change altitude", rootPath) + local baseAltitude = DCSEx.converter.metersToFeet(Library.aircraft[world.getPlayer():getTypeName()].altitude) + local altitudeFactions = { 0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5 } + for _,f in ipairs(altitudeFactions) do + local altText = DCSEx.string.toStringThousandsSeparator(math.floor((baseAltitude * f) / 100) * 100).."ft" + if f == 0 then altText = "nap-of-the-earth" end + missionCommands.addCommand(DCSEx.string.firstToUpper(altText), altitudePath, radioCommandChangeAltitude, { altitudeFraction = f, altitudeText = altText }) + end + missionCommands.addCommand("Status report", rootPath, radioCommandReportStatus, nil) missionCommands.addCommand("Rejoin", rootPath, radioCommandRejoin, nil) end diff --git a/Script/The Universal Mission/WingmenTasking.lua b/Script/The Universal Mission/WingmenTasking.lua index 45214ba..fa5bfc5 100644 --- a/Script/The Universal Mission/WingmenTasking.lua +++ b/Script/The Universal Mission/WingmenTasking.lua @@ -16,6 +16,8 @@ do local currentTargetIDorPoint = nil -- ID for groups/statics, point2 for scenery objects local currentTargetType = nil + local cruiseAltitudeFraction = 1.0 -- Fraction of the default aircraft cruise altitude + local function allowWeaponUse(wingmenCtrl, allowAA, allowAG) allowAA = allowAA or false allowAG = allowAG or false @@ -24,6 +26,25 @@ do wingmenCtrl:setOption(AI.Option.Air.id.PROHIBIT_AG, not allowAG) end + local function getAltitude() + local player = world.getPlayer() + if not player then return 600 end -- Don't care about altitude if player's dead anyway + + local altitude = Library.aircraft[player:getTypeName()].altitude * cruiseAltitudeFraction + return altitude + end + + local function setWingmenAltitude(altitude) + local wingmenCtrl = TUM.wingmen.getController() + if not wingmenCtrl then return nil end + + altitude = altitude or getAltitude() + altitude = math.max(50, altitude) + altitude = altitude * DCSEx.math.randomFloat(0.98, 1.02) -- add a slight variation + + wingmenCtrl:setAltitude(altitude, true, AI.Task.AltitudeType.BARO) + 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 @@ -73,6 +94,7 @@ do } } allowWeaponUse(wingmenCtrl, false, true) + setWingmenAltitude() wingmenCtrl:setTask(taskTable) return DCSEx.world.getStaticObjectByID(nearestTarget):getPoint() elseif nearestTargetType == "scenery" then @@ -86,6 +108,7 @@ do } } allowWeaponUse(wingmenCtrl, false, true) + setWingmenAltitude() wingmenCtrl:setTask(taskTable) return DCSEx.math.vec2ToVec3(nearestTarget, "land") end @@ -93,25 +116,11 @@ do return nil end - local function getOrbitAltitude() - local player = world.getPlayer() - if not player then return 600 end - - local altitude = world.getPlayer():getPoint().y - - local aircraftType = player:getTypeName() - if Library.aircraft[aircraftType] and Library.aircraft[aircraftType].altitude then - altitude = math.max(altitude, Library.aircraft[aircraftType].altitude * 0.8) - end - - return altitude - end - local function getOrbitTaskTable(point2) return { id = "Orbit", params = { - altitude = getOrbitAltitude(), + altitude = getAltitude(), pattern = "Circle", point = point2, width = DCSEx.converter.nmToMeters(1.0) @@ -133,6 +142,20 @@ do } end + function TUM.wingmenTasking.commandChangeAltitude(altFraction, delayRadioAnswer) + cruiseAltitudeFraction = DCSEx.math.clamp(altFraction or 1.0, 0.0, 2.0) + local newAlt = getAltitude() + + local newAltStr = "nap-of-the-earth" + if altFraction > 0 then + newAltStr = DCSEx.string.toStringThousandsSeparator(math.floor(DCSEx.converter.metersToFeet(newAlt) / 100) * 100).."ft" + end + + setWingmenAltitude() + TUM.radio.playForAll("pilotWingmanChangeAltitude", { TUM.wingmen.getFirstWingmanNumber(), newAltStr }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) + return true + end + function TUM.wingmenTasking.commandEngage(groupCategory, targetAttributes, delayRadioAnswer) delayRadioAnswer = delayRadioAnswer or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer @@ -207,6 +230,7 @@ do local targetInAir = target:inAir() allowWeaponUse(wingmenCtrl, targetInAir, not targetInAir) + setWingmenAltitude() wingmenCtrl:setTask(taskTable) local targetBRAA = "distance unknown" @@ -214,11 +238,11 @@ do local messageSuffix = nil if targetInAir then messageSuffix = "Air" - targetInfo = Library.objectNames.get(target) -- Library.objectNames.getGeneric(target) + targetInfo = Library.objectNames.get(target) targetBRAA = DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, true) else messageSuffix = "Surface" - targetInfo = Library.objectNames.get(target) -- Library.objectNames.getGeneric(target) + targetInfo = Library.objectNames.getGeneric(target) targetBRAA = DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, false) end @@ -257,6 +281,7 @@ do currentTargetIDorPoint = nil allowWeaponUse(wingmenCtrl, false, false) + setWingmenAltitude() wingmenCtrl:setTask(getOrbitTaskTable(DCSEx.math.vec3ToVec2(mapMarker.pos))) -- TUM.radio.playForAll("pilotWingmanGoToMarker", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) @@ -272,6 +297,7 @@ do allowWeaponUse(wingmenCtrl, false, false) currentTargetIDorPoint = nil + setWingmenAltitude() wingmenCtrl:setTask(getOrbitTaskTable(DCSEx.world.getGroupCenter(TUM.wingmen.getGroup()))) TUM.radio.playForAll("pilotWingmanOrbit", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) @@ -292,6 +318,8 @@ do currentTargetIDorPoint = nil allowWeaponUse(wingmenCtrl, false, false) + -- setWingmenAltitude(player:getPoint().y) + setWingmenAltitude() wingmenCtrl:setTask(getRejoinTaskTable(formationDistance)) if not silent then local msgID = "pilotWingmanRejoin" @@ -389,4 +417,8 @@ do end end end + + function TUM.wingmenTasking.resetTaskingParameters() + cruiseAltitudeFraction = 1.0 + end end