Merge branch 'develop' into FF/Ops

This commit is contained in:
Frank 2023-07-26 16:11:27 +02:00
commit 7e2233d8c7
7 changed files with 421 additions and 91 deletions

View File

@ -147,8 +147,8 @@
-- @image Escorting.JPG
--- @type AI_ESCORT
---
-- @type AI_ESCORT
-- @extends AI.AI_Formation#AI_FORMATION
@ -168,11 +168,14 @@
--
-- -- First find the GROUP object and the CLIENT object.
-- local EscortUnit = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
-- local EscortGroup = SET_GROUP:New():FilterPrefixes("Escort"):FilterOnce() -- The the group name of the escorts contains "Escort".
--
-- -- Now use these 2 objects to construct the new EscortPlanes object.
-- EscortPlanes = AI_ESCORT:New( EscortUnit, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
--
-- EscortPlanes:MenusAirplanes() -- create menus for airplanes
-- EscortPlanes:__Start(2)
--
--
-- @field #AI_ESCORT
AI_ESCORT = {
ClassName = "AI_ESCORT",
@ -189,7 +192,7 @@ AI_ESCORT = {
TaskPoints = {}
}
--- @field Functional.Detection#DETECTION_AREAS
-- @field Functional.Detection#DETECTION_AREAS
AI_ESCORT.Detection = nil
--- MENUPARAM type
@ -211,10 +214,14 @@ AI_ESCORT.Detection = nil
--
-- -- First find the GROUP object and the CLIENT object.
-- local EscortUnit = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
-- local EscortGroup = SET_GROUP:New():FilterPrefixes("Escort"):FilterOnce() -- The the group name of the escorts contains "Escort".
--
-- -- Now use these 2 objects to construct the new EscortPlanes object.
-- EscortPlanes = AI_ESCORT:New( EscortUnit, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
-- EscortPlanes:MenusAirplanes() -- create menus for airplanes
-- EscortPlanes:__Start(2)
--
--
function AI_ESCORT:New( EscortUnit, EscortGroupSet, EscortName, EscortBriefing )
local self = BASE:Inherit( self, AI_FORMATION:New( EscortUnit, EscortGroupSet, EscortName, EscortBriefing ) ) -- #AI_ESCORT
@ -227,10 +234,17 @@ function AI_ESCORT:New( EscortUnit, EscortGroupSet, EscortName, EscortBriefing )
self.EscortGroupSet = EscortGroupSet
self.EscortGroupSet:SetSomeIteratorLimit( 8 )
self.EscortBriefing = EscortBriefing
self.Menu = {}
self.Menu.HoldAtEscortPosition = self.Menu.HoldAtEscortPosition or {}
self.Menu.HoldAtLeaderPosition = self.Menu.HoldAtLeaderPosition or {}
self.Menu.Flare = self.Menu.Flare or {}
self.Menu.Smoke = self.Menu.Smoke or {}
self.Menu.Targets = self.Menu.Targets or {}
self.Menu.ROE = self.Menu.ROE or {}
self.Menu.ROT = self.Menu.ROT or {}
-- if not EscortBriefing then
-- EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " ..
@ -250,7 +264,7 @@ function AI_ESCORT:New( EscortUnit, EscortGroupSet, EscortName, EscortBriefing )
EscortGroupSet:ForEachGroup(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
-- Set EscortGroup known at EscortUnit.
if not self.PlayerUnit._EscortGroups then
@ -325,14 +339,14 @@ function AI_ESCORT:_InitEscortRoute( EscortGroup )
end
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Core.Set#SET_GROUP EscortGroupSet
function AI_ESCORT:onafterStart( EscortGroupSet )
self:F()
EscortGroupSet:ForEachGroup(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
EscortGroup:WayPointInitialize()
@ -370,7 +384,7 @@ function AI_ESCORT:onafterStart( EscortGroupSet )
self:_InitFlightMenus()
self.EscortGroupSet:ForSomeGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
self:_InitEscortMenus( EscortGroup )
@ -378,7 +392,7 @@ function AI_ESCORT:onafterStart( EscortGroupSet )
self:SetFlightModeFormation( EscortGroup )
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Core.Event#EVENTDATA EventData
function EscortGroup:OnEventDeadOrCrash( EventData )
self:F( { "EventDead", EventData } )
@ -394,14 +408,14 @@ function AI_ESCORT:onafterStart( EscortGroupSet )
end
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Core.Set#SET_GROUP EscortGroupSet
function AI_ESCORT:onafterStop( EscortGroupSet )
self:F()
EscortGroupSet:ForEachGroup(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
EscortGroup:WayPointInitialize()
@ -550,7 +564,7 @@ function AI_ESCORT:SetFlightMenuFormation( Formation )
local MenuFlightFormationID = MENU_GROUP_COMMAND:New( self.PlayerGroup, Formation, FlightMenuFormation,
function ( self, Formation, ... )
self.EscortGroupSet:ForSomeGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup, self, Formation, Arguments )
if EscortGroup:IsAir() then
self:E({FormationID=FormationID})
@ -764,7 +778,7 @@ end
function AI_ESCORT:SetFlightMenuHoldAtEscortPosition()
for _, MenuHoldAtEscortPosition in pairs( self.Menu.HoldAtEscortPosition ) do
for _, MenuHoldAtEscortPosition in pairs( self.Menu.HoldAtEscortPosition or {} ) do
local FlightMenuReportNavigation = MENU_GROUP:New( self.PlayerGroup, "Navigation", self.FlightMenu )
local FlightMenuHoldPosition = MENU_GROUP_COMMAND
@ -785,7 +799,7 @@ end
function AI_ESCORT:SetEscortMenuHoldAtEscortPosition( EscortGroup )
for _, HoldAtEscortPosition in pairs( self.Menu.HoldAtEscortPosition ) do
for _, HoldAtEscortPosition in pairs( self.Menu.HoldAtEscortPosition or {}) do
if EscortGroup:IsAir() then
local EscortGroupName = EscortGroup:GetName()
local EscortMenuReportNavigation = MENU_GROUP:New( self.PlayerGroup, "Navigation", EscortGroup.EscortMenu )
@ -853,7 +867,7 @@ end
function AI_ESCORT:SetFlightMenuHoldAtLeaderPosition()
for _, MenuHoldAtLeaderPosition in pairs( self.Menu.HoldAtLeaderPosition ) do
for _, MenuHoldAtLeaderPosition in pairs( self.Menu.HoldAtLeaderPosition or {}) do
local FlightMenuReportNavigation = MENU_GROUP:New( self.PlayerGroup, "Navigation", self.FlightMenu )
local FlightMenuHoldAtLeaderPosition = MENU_GROUP_COMMAND
@ -874,7 +888,7 @@ end
function AI_ESCORT:SetEscortMenuHoldAtLeaderPosition( EscortGroup )
for _, HoldAtLeaderPosition in pairs( self.Menu.HoldAtLeaderPosition ) do
for _, HoldAtLeaderPosition in pairs( self.Menu.HoldAtLeaderPosition or {}) do
if EscortGroup:IsAir() then
local EscortGroupName = EscortGroup:GetName()
@ -999,7 +1013,7 @@ end
function AI_ESCORT:SetFlightMenuFlare()
for _, MenuFlare in pairs( self.Menu.Flare) do
for _, MenuFlare in pairs( self.Menu.Flare or {}) do
local FlightMenuReportNavigation = MENU_GROUP:New( self.PlayerGroup, "Navigation", self.FlightMenu )
local FlightMenuFlare = MENU_GROUP:New( self.PlayerGroup, MenuFlare.MenuText, FlightMenuReportNavigation )
@ -1014,7 +1028,7 @@ end
function AI_ESCORT:SetEscortMenuFlare( EscortGroup )
for _, MenuFlare in pairs( self.Menu.Flare) do
for _, MenuFlare in pairs( self.Menu.Flare or {}) do
if EscortGroup:IsAir() then
local EscortGroupName = EscortGroup:GetName()
@ -1059,7 +1073,7 @@ end
function AI_ESCORT:SetFlightMenuSmoke()
for _, MenuSmoke in pairs( self.Menu.Smoke) do
for _, MenuSmoke in pairs( self.Menu.Smoke or {}) do
local FlightMenuReportNavigation = MENU_GROUP:New( self.PlayerGroup, "Navigation", self.FlightMenu )
local FlightMenuSmoke = MENU_GROUP:New( self.PlayerGroup, MenuSmoke.MenuText, FlightMenuReportNavigation )
@ -1076,7 +1090,7 @@ end
function AI_ESCORT:SetEscortMenuSmoke( EscortGroup )
for _, MenuSmoke in pairs( self.Menu.Smoke) do
for _, MenuSmoke in pairs( self.Menu.Smoke or {}) do
if EscortGroup:IsAir() then
local EscortGroupName = EscortGroup:GetName()
@ -1169,7 +1183,7 @@ function AI_ESCORT:SetFlightMenuTargets()
local FlightMenuAttackNearbyAir = MENU_GROUP_COMMAND:New( self.PlayerGroup, "Attack nearest airborne targets", self.FlightMenuAttack, AI_ESCORT._FlightAttackNearestTarget, self, self.__Enum.ReportType.Air ):SetTag( "Attack" )
local FlightMenuAttackNearbyGround = MENU_GROUP_COMMAND:New( self.PlayerGroup, "Attack nearest ground targets", self.FlightMenuAttack, AI_ESCORT._FlightAttackNearestTarget, self, self.__Enum.ReportType.Ground ):SetTag( "Attack" )
for _, MenuTargets in pairs( self.Menu.Targets) do
for _, MenuTargets in pairs( self.Menu.Targets or {}) do
MenuTargets.FlightReportTargetsScheduler = SCHEDULER:New( self, self._FlightReportTargetsScheduler, {}, MenuTargets.Interval, MenuTargets.Interval )
end
@ -1179,7 +1193,7 @@ end
function AI_ESCORT:SetEscortMenuTargets( EscortGroup )
for _, MenuTargets in pairs( self.Menu.Targets) do
for _, MenuTargets in pairs( self.Menu.Targets or {} or {}) do
if EscortGroup:IsAir() then
local EscortGroupName = EscortGroup:GetName()
--local EscortMenuReportTargets = MENU_GROUP:New( self.PlayerGroup, "Report targets", EscortGroup.EscortMenu )
@ -1231,7 +1245,7 @@ function AI_ESCORT:MenuAssistedAttack()
self:F()
self.EscortGroupSet:ForSomeGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if not EscortGroup:IsAir() then
-- Request assistance from other escorts.
@ -1246,7 +1260,7 @@ end
function AI_ESCORT:SetFlightMenuROE()
for _, MenuROE in pairs( self.Menu.ROE) do
for _, MenuROE in pairs( self.Menu.ROE or {}) do
local FlightMenuROE = MENU_GROUP:New( self.PlayerGroup, "Rule Of Engagement", self.FlightMenu )
local FlightMenuROEHoldFire = MENU_GROUP_COMMAND:New( self.PlayerGroup, "Hold fire", FlightMenuROE, AI_ESCORT._FlightROEHoldFire, self, "Holding weapons!" )
@ -1261,7 +1275,7 @@ end
function AI_ESCORT:SetEscortMenuROE( EscortGroup )
for _, MenuROE in pairs( self.Menu.ROE) do
for _, MenuROE in pairs( self.Menu.ROE or {}) do
if EscortGroup:IsAir() then
local EscortGroupName = EscortGroup:GetName()
@ -1302,7 +1316,7 @@ end
function AI_ESCORT:SetFlightMenuROT()
for _, MenuROT in pairs( self.Menu.ROT) do
for _, MenuROT in pairs( self.Menu.ROT or {}) do
local FlightMenuROT = MENU_GROUP:New( self.PlayerGroup, "Reaction On Threat", self.FlightMenu )
local FlightMenuROTNoReaction = MENU_GROUP_COMMAND:New( self.PlayerGroup, "Fight until death", FlightMenuROT, AI_ESCORT._FlightROTNoReaction, self, "Fighting until death!" )
@ -1317,7 +1331,7 @@ end
function AI_ESCORT:SetEscortMenuROT( EscortGroup )
for _, MenuROT in pairs( self.Menu.ROT) do
for _, MenuROT in pairs( self.Menu.ROT or {}) do
if EscortGroup:IsAir() then
local EscortGroupName = EscortGroup:GetName()
@ -1375,7 +1389,7 @@ function AI_ESCORT:SetEscortMenuResumeMission( EscortGroup )
end
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Wrapper.Group#GROUP OrbitGroup
-- @param Wrapper.Group#GROUP EscortGroup
-- @param #number OrbitHeight
@ -1419,7 +1433,7 @@ function AI_ESCORT:_HoldPosition( OrbitGroup, EscortGroup, OrbitHeight, OrbitSec
end
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Wrapper.Group#GROUP OrbitGroup
-- @param #number OrbitHeight
-- @param #number OrbitSeconds
@ -1428,7 +1442,7 @@ function AI_ESCORT:_FlightHoldPosition( OrbitGroup, OrbitHeight, OrbitSeconds )
local EscortUnit = self.PlayerUnit
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup, OrbitGroup )
if EscortGroup:IsAir() then
if OrbitGroup == nil then
@ -1456,7 +1470,7 @@ end
function AI_ESCORT:_FlightJoinUp()
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_JoinUp( EscortGroup )
@ -1483,7 +1497,7 @@ end
function AI_ESCORT:_FlightFormationTrail( XStart, XSpace, YStart )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_EscortFormationTrail( EscortGroup, XStart, XSpace, YStart )
@ -1510,7 +1524,7 @@ end
function AI_ESCORT:_FlightFormationStack( XStart, XSpace, YStart, YSpace )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_EscortFormationStack( EscortGroup, XStart, XSpace, YStart, YSpace )
@ -1533,7 +1547,7 @@ end
function AI_ESCORT:_FlightFlare( Color, Message )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_Flare( EscortGroup, Color, Message )
@ -1556,7 +1570,7 @@ end
function AI_ESCORT:_FlightSmoke( Color, Message )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_Smoke( EscortGroup, Color, Message )
@ -1587,7 +1601,7 @@ end
function AI_ESCORT:_FlightSwitchReportNearbyTargets( ReportTargets )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_EscortSwitchReportNearbyTargets( EscortGroup, ReportTargets )
@ -1679,7 +1693,7 @@ function AI_ESCORT:_ScanTargets( ScanDuration )
end
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
-- @param #AI_ESCORT self
function AI_ESCORT.___Resume( EscortGroup, self )
@ -1701,7 +1715,7 @@ function AI_ESCORT.___Resume( EscortGroup, self )
end
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Wrapper.Group#GROUP EscortGroup
-- @param #number WayPoint
function AI_ESCORT:_ResumeMission( EscortGroup, WayPoint )
@ -1723,7 +1737,7 @@ function AI_ESCORT:_ResumeMission( EscortGroup, WayPoint )
end
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Wrapper.Group#GROUP EscortGroup The escort group that will attack the detected item.
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
function AI_ESCORT:_AttackTarget( EscortGroup, DetectedItem )
@ -1743,7 +1757,7 @@ function AI_ESCORT:_AttackTarget( EscortGroup, DetectedItem )
local AttackUnitTasks = {}
DetectedSet:ForEachUnit(
--- @param Wrapper.Unit#UNIT DetectedUnit
-- @param Wrapper.Unit#UNIT DetectedUnit
function( DetectedUnit, Tasks )
if DetectedUnit:IsAlive() then
AttackUnitTasks[#AttackUnitTasks+1] = EscortGroup:TaskAttackUnit( DetectedUnit )
@ -1767,7 +1781,7 @@ function AI_ESCORT:_AttackTarget( EscortGroup, DetectedItem )
local Tasks = {}
DetectedSet:ForEachUnit(
--- @param Wrapper.Unit#UNIT DetectedUnit
-- @param Wrapper.Unit#UNIT DetectedUnit
function( DetectedUnit, Tasks )
if DetectedUnit:IsAlive() then
Tasks[#Tasks+1] = EscortGroup:TaskFireAtPoint( DetectedUnit:GetVec2(), 50 )
@ -1795,7 +1809,7 @@ end
function AI_ESCORT:_FlightAttackTarget( DetectedItem )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
-- @param Core.Group#GROUP EscortGroup
function( EscortGroup, DetectedItem )
if EscortGroup:IsAir() then
self:_AttackTarget( EscortGroup, DetectedItem )
@ -1842,7 +1856,7 @@ end
---
--- @param #AI_ESCORT self
-- @param #AI_ESCORT self
-- @param Wrapper.Group#GROUP EscortGroup The escort group that will attack the detected item.
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
function AI_ESCORT:_AssistTarget( EscortGroup, DetectedItem )
@ -1854,7 +1868,7 @@ function AI_ESCORT:_AssistTarget( EscortGroup, DetectedItem )
local Tasks = {}
DetectedSet:ForEachUnit(
--- @param Wrapper.Unit#UNIT DetectedUnit
-- @param Wrapper.Unit#UNIT DetectedUnit
function( DetectedUnit, Tasks )
if DetectedUnit:IsAlive() then
Tasks[#Tasks+1] = EscortGroup:TaskFireAtPoint( DetectedUnit:GetVec2(), 50 )
@ -1881,7 +1895,7 @@ end
function AI_ESCORT:_FlightROEHoldFire( EscortROEMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROE( EscortGroup, EscortGroup.OptionROEHoldFire, EscortROEMessage )
end
@ -1890,7 +1904,7 @@ end
function AI_ESCORT:_FlightROEOpenFire( EscortROEMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROE( EscortGroup, EscortGroup.OptionROEOpenFire, EscortROEMessage )
end
@ -1899,7 +1913,7 @@ end
function AI_ESCORT:_FlightROEReturnFire( EscortROEMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROE( EscortGroup, EscortGroup.OptionROEReturnFire, EscortROEMessage )
end
@ -1908,7 +1922,7 @@ end
function AI_ESCORT:_FlightROEWeaponFree( EscortROEMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROE( EscortGroup, EscortGroup.OptionROEWeaponFree, EscortROEMessage )
end
@ -1924,7 +1938,7 @@ end
function AI_ESCORT:_FlightROTNoReaction( EscortROTMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROT( EscortGroup, EscortGroup.OptionROTNoReaction, EscortROTMessage )
end
@ -1933,7 +1947,7 @@ end
function AI_ESCORT:_FlightROTPassiveDefense( EscortROTMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROT( EscortGroup, EscortGroup.OptionROTPassiveDefense, EscortROTMessage )
end
@ -1942,7 +1956,7 @@ end
function AI_ESCORT:_FlightROTEvadeFire( EscortROTMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROT( EscortGroup, EscortGroup.OptionROTEvadeFire, EscortROTMessage )
end
@ -1951,7 +1965,7 @@ end
function AI_ESCORT:_FlightROTVertical( EscortROTMessage )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Wrapper.Group#GROUP EscortGroup
-- @param Wrapper.Group#GROUP EscortGroup
function( EscortGroup )
self:_ROT( EscortGroup, EscortGroup.OptionROTVertical, EscortROTMessage )
end
@ -2178,5 +2192,3 @@ function AI_ESCORT:_FlightReportTargetsScheduler()
return false
end

View File

@ -381,7 +381,7 @@ end
CLIENTMENUMANAGER = {
ClassName = "CLIENTMENUMANAGER",
lid = "",
version = "0.1.0",
version = "0.1.1",
name = nil,
clientset = nil,
menutree = {},
@ -670,7 +670,7 @@ end
--- Remove the entry and all entries below the given entry from the client's F10 menus.
-- @param #CLIENTMENUMANAGER self
-- @param #CLIENTMENU Entry The entry to remove
-- @param Wrapper.Client#CLIENT Client (optional) If given, make this change only for this client. In this case the generic structure will not be touched.
-- @param Wrapper.Client#CLIENT Client (optional) If given, make this change only for this client.
-- @return #CLIENTMENUMANAGER self
function CLIENTMENUMANAGER:DeleteF10Entry(Entry,Client)
self:T(self.lid.."DeleteF10Entry")
@ -783,3 +783,4 @@ end
-- End ClientMenu
--
----------------------------------------------------------------------------------------------------------------

View File

@ -419,6 +419,8 @@ ATIS.RunwayM2T = {
TheChannel = -10,
Syria = 5,
MarianaIslands = 2,
Falklands = 12,
Sinai = 5,
}
--- Whether ICAO phraseology is used for ATIS broadcasts.
@ -430,6 +432,8 @@ ATIS.RunwayM2T = {
-- @field #boolean TheChannel true.
-- @field #boolean Syria true.
-- @field #boolean MarianaIslands true.
-- @field #boolean Falklands true.
-- @field #boolean Sinai true.
ATIS.ICAOPhraseology = {
Caucasus = true,
Nevada = false,
@ -437,7 +441,9 @@ ATIS.ICAOPhraseology = {
PersianGulf = true,
TheChannel = true,
Syria = true,
MarianaIslands = true
MarianaIslands = true,
Falklands = true,
Sinai = true,
}
--- Nav point data.
@ -1272,7 +1278,8 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function ATIS:onafterStart( From, Event, To )
self:I("Airbase category is "..self.airbase:GetAirbaseCategory())
-- Check that this is an airdrome.
if self.airbase:GetAirbaseCategory() == Airbase.Category.SHIP then
self:E( self.lid .. string.format( "ERROR: Cannot start ATIS for airbase %s! Only AIRDROMES are supported but NOT SHIPS.", self.airbasename ) )
@ -1823,7 +1830,10 @@ function ATIS:onafterBroadcast( From, Event, To )
-- Airbase name
subtitle = string.format( "%s", self.airbasename )
if (not self.ATISforFARPs) and self.airbasename:find( "AFB" ) == nil and self.airbasename:find( "Airport" ) == nil and self.airbasename:find( "Airstrip" ) == nil and self.airbasename:find( "airfield" ) == nil and self.airbasename:find( "AB" ) == nil then
if (not self.ATISforFARPs) and self.airbasename:find( "AFB" ) == nil and self.airbasename:find( "Airport" ) == nil
and self.airbasename:find( "Airstrip" ) == nil and self.airbasename:find( "airfield" ) == nil and self.airbasename:find( "AB" ) == nil
and self.airbasename:find( "Field" ) == nil
then
subtitle = subtitle .. " Airport"
end
if not self.useSRS then

View File

@ -17,7 +17,7 @@
-- ===
--
-- ### Author: **applevangelist**
-- @date Last Update December 2022
-- @date Last Update July 2023
-- @module Ops.AWACS
-- @image OPS_AWACS.jpg
@ -63,6 +63,7 @@ do
-- @field Utilities.FiFo#FIFO RadioQueue
-- @field Utilities.FiFo#FIFO PrioRadioQueue
-- @field Utilities.FiFo#FIFO CAPAirwings
-- @field Utilities.FiFo#FIFO TacticalQueue
-- @field #number AwacsTimeOnStation
-- @field #number AwacsTimeStamp
-- @field #number EscortsTimeOnStation
@ -113,6 +114,13 @@ do
-- @field Wrapper.Group#GROUP GCIGroup EWR group object for GCI ops
-- @field #string locale Localization
-- @field #boolean IncludeHelicopters
-- @field #boolean TacticalMenu
-- @field #table TacticalFrequencies
-- @field #table TacticalSubscribers
-- @field #number TacticalBaseFreq
-- @field #number TacticalIncrFreq
-- @field #number TacticalModulation
-- @field #number TacticalInterval
-- @extends Core.Fsm#FSM
@ -499,7 +507,7 @@ do
-- @field #AWACS
AWACS = {
ClassName = "AWACS", -- #string
version = "0.2.55", -- #string
version = "0.2.57", -- #string
lid = "", -- #string
coalition = coalition.side.BLUE, -- #number
coalitiontxt = "blue", -- #string
@ -532,6 +540,7 @@ AWACS = {
ContactsAO = {}, -- Utilities.FiFo#FIFO
RadioQueue = {}, -- Utilities.FiFo#FIFO
PrioRadioQueue = {}, -- Utilities.FiFo#FIFO
TacticalQueue = {}, -- Utilities.FiFo#FIFO
AwacsTimeOnStation = 4,
AwacsTimeStamp = 0,
EscortsTimeOnStation = 4,
@ -587,6 +596,13 @@ AWACS = {
GCIGroup = nil,
locale = "en",
IncludeHelicopters = false,
TacticalMenu = false,
TacticalFrequencies = {},
TacticalSubscribers = {},
TacticalBaseFreq = 130,
TacticalIncrFreq = 0.5,
TacticalModulation = radio.modulation.AM,
TacticalInterval = 120,
}
---
@ -917,7 +933,7 @@ AWACS.TaskStatus = {
--@field #boolean FromAI
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO-List 0.2.52
-- TODO-List 0.2.53
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--
-- DONE - WIP - Player tasking, VID
@ -1110,6 +1126,7 @@ function AWACS:New(Name,AirWing,Coalition,AirbaseName,AwacsOrbit,OpsZone,Station
self.Volume = 1.0
self.RadioQueue = FIFO:New() -- Utilities.FiFo#FIFO
self.PrioRadioQueue = FIFO:New() -- Utilities.FiFo#FIFO
self.TacticalQueue = FIFO:New() -- Utilities.FiFo#FIFO
self.maxspeakentries = 3
self.GoogleTTSPadding = 1
self.WindowsTTSPadding = 2.5
@ -1180,6 +1197,15 @@ function AWACS:New(Name,AirWing,Coalition,AirbaseName,AwacsOrbit,OpsZone,Station
self.clientmenus = FIFO:New() -- Utilities.FiFo#FIFO
-- Tactical Menu
self.TacticalMenu = false
self.TacticalBaseFreq = 130
self.TacticalIncrFreq = 0.5
self.TacticalModulation = radio.modulation.AM
self.acticalFrequencies = {}
self.TacticalSubscribers = {}
self.TacticalInterval = 120
-- SET for Intel Detection
self.DetectionSet=SET_GROUP:New()
@ -1204,6 +1230,7 @@ function AWACS:New(Name,AirWing,Coalition,AirbaseName,AwacsOrbit,OpsZone,Station
self:AddTransition("*", "LostCluster", "*")
self:AddTransition("*", "LostContact", "*")
self:AddTransition("*", "CheckRadioQueue", "*")
self:AddTransition("*", "CheckTacticalQueue", "*")
self:AddTransition("*", "EscortShiftChange", "*")
self:AddTransition("*", "AwacsShiftChange", "*")
self:AddTransition("*", "FlightOnMission", "*")
@ -1354,6 +1381,142 @@ end
-- Functions
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- [User] Set the tactical information option, create 10 radio channels groups can subscribe and get Bogey Dope on a specific frequency automatically.
-- @param #AWACS self
-- @param #number BaseFreq Base Frequency to use, defaults to 130.
-- @param #number Increase Increase to use, defaults to 0.5, thus channels created are 130, 130.5, 131 .. etc.
-- @param #number Modulation Modulation to use, defaults to radio.modulation.AM.
-- @param #number Interval Seconds between each update call.
-- @param #number Number Number of Frequencies to create, can be 1..10.
-- @return #AWACS self
function AWACS:SetTacticalRadios(BaseFreq,Increase,Modulation,Interval,Number)
self:T(self.lid.."SetTacticalRadios")
self.TacticalMenu = true
self.TacticalBaseFreq = BaseFreq or 130
self.TacticalIncrFreq = Increase or 0.5
self.TacticalModulation = Modulation or radio.modulation.AM
self.TacticalInterval = Interval or 120
local number = Number or 10
if number < 1 then number = 1 end
if number > 10 then number = 10 end
for i=1,number do
local freq = self.TacticalBaseFreq + ((i-1)*self.TacticalIncrFreq)
self.TacticalFrequencies[freq] = freq
end
if self.AwacsSRS then
self.TacticalSRS = MSRS:New(self.PathToSRS,self.TacticalBaseFreq,self.TacticalModulation,self.Volume)
self.TacticalSRS:SetCoalition(self.coalition)
self.TacticalSRS:SetGender(self.Gender)
self.TacticalSRS:SetCulture(self.Culture)
self.TacticalSRS:SetVoice(self.Voice)
self.TacticalSRS:SetPort(self.Port)
self.TacticalSRS:SetLabel("AWACS")
if self.PathToGoogleKey then
self.TacticalSRS:SetGoogle(self.PathToGoogleKey)
end
self.TacticalSRSQ = MSRSQUEUE:New("Tactical AWACS")
end
return self
end
--- TODO
-- [Internal] _RefreshMenuNonSubscribed
-- @param #AWACS self
-- @return #AWACS self
function AWACS:_RefreshMenuNonSubscribed()
self:T(self.lid.."_RefreshMenuNonSubscribed")
local aliveset = self.clientset:GetAliveSet()
for _,_group in pairs(aliveset) do
-- go through set and re-build the sub-menu
local grp = _group -- Wrapper.Client#CLIENT
local Group = grp:GetGroup()
local gname = nil
if Group and Group:IsAlive() then
gname = Group:GetName()
self:T(gname)
end
local menustr = self.clientmenus:ReadByID(gname)
local menu = menustr.tactical -- Core.Menu#MENU_GROUP
if not self.TacticalSubscribers[gname] and menu then
menu:RemoveSubMenus()
for _,_freq in UTILS.spairs(self.TacticalFrequencies) do
local modu = UTILS.GetModulationName(self.TacticalModulation)
local text = string.format("Subscribe to %.3f %s",_freq,modu)
local entry = MENU_GROUP_COMMAND:New(Group,text,menu,self._SubScribeTactRadio,self,Group,_freq)
end
end
end
return self
end
--- [Internal] _UnsubScribeTactRadio
-- @param #AWACS self
-- @param Wrapper.Group#GROUP Group
-- @return #AWACS self
function AWACS:_UnsubScribeTactRadio(Group)
self:T(self.lid.."_UnsubScribeTactRadio")
local text = ""
local textScreen = ""
local GID, Outcome = self:_GetManagedGrpID(Group)
local gcallsign = self:_GetCallSign(Group,GID) or "Ghost 1"
local gname = Group:GetName() or "unknown"
if Outcome and self.TacticalSubscribers[gname] then
-- Pilot is checked in
local Freq = self.TacticalSubscribers[gname]
self.TacticalFrequencies[Freq] = Freq
self.TacticalSubscribers[gname] = nil
local modu = self.TacticalModulation == 0 and "AM" or "FM"
text = string.format("%s, %s, switch back to AWACS main frequency!",gcallsign,self.callsigntxt)
self:_NewRadioEntry(text,text,GID,true,true,true,false,true)
self:_RefreshMenuNonSubscribed()
elseif self.AwacsFG then
-- no, unknown
local nocheckin = self.gettext:GetEntry("NOTCHECKEDIN",self.locale)
text = string.format(nocheckin,self:_GetCallSign(Group,GID) or "Ghost 1", self.callsigntxt)
self:_NewRadioEntry(text,text,GID,Outcome,true,true,false)
end
return self
end
--- [Internal] _SubScribeTactRadio
-- @param #AWACS self
-- @param Wrapper.Group#GROUP Group
-- @param #number Frequency
-- @return #AWACS self
function AWACS:_SubScribeTactRadio(Group,Frequency)
self:T(self.lid.."_SubScribeTactRadio")
local text = ""
local textScreen = ""
local GID, Outcome = self:_GetManagedGrpID(Group)
local gcallsign = self:_GetCallSign(Group,GID) or "Ghost 1"
local gname = Group:GetName() or "unknown"
if Outcome then
-- Pilot is checked in
self.TacticalSubscribers[gname] = Frequency
self.TacticalFrequencies[Frequency] = nil
local modu = self.TacticalModulation == 0 and "AM" or "FM"
text = string.format("%s, %s, switch to %.3f %s for tactical information!",gcallsign,self.callsigntxt,Frequency,modu)
self:_NewRadioEntry(text,text,GID,true,true,true,false,true)
local menustr = self.clientmenus:ReadByID(gname)
local menu = menustr.tactical -- Core.Menu#MENU_GROUP
if menu then
menu:RemoveSubMenus()
local text = string.format("Unsubscribe %.3f %s",Frequency,modu)
local entry = MENU_GROUP_COMMAND:New(Group,text,menu,self._UnsubScribeTactRadio,self,Group)
end
elseif self.AwacsFG then
-- no, unknown
local nocheckin = self.gettext:GetEntry("NOTCHECKEDIN",self.locale)
text = string.format(nocheckin,self:_GetCallSign(Group,GID) or "Ghost 1", self.callsigntxt)
self:_NewRadioEntry(text,text,GID,Outcome,true,true,false)
end
return self
end
--- [Internal] Init localization
-- @param #AWACS self
-- @return #AWACS self
@ -1426,8 +1589,9 @@ end
-- @param #boolean IsNew New
-- @param #boolean FromAI From AI
-- @param #boolean IsPrio Priority entry
-- @param #boolean Tactical Is for tactical info
-- @return #AWACS self
function AWACS:_NewRadioEntry(TextTTS, TextScreen,GID,IsGroup,ToScreen,IsNew,FromAI,IsPrio)
function AWACS:_NewRadioEntry(TextTTS, TextScreen,GID,IsGroup,ToScreen,IsNew,FromAI,IsPrio,Tactical)
self:T(self.lid.."_NewRadioEntry")
local RadioEntry = {} -- #AWACS.RadioEntry
RadioEntry.IsNew = IsNew
@ -1438,7 +1602,9 @@ function AWACS:_NewRadioEntry(TextTTS, TextScreen,GID,IsGroup,ToScreen,IsNew,Fro
RadioEntry.Duration = STTS.getSpeechTime(TextTTS,0.95,false) or 8
RadioEntry.FromAI = FromAI
RadioEntry.IsGroup = IsGroup
if IsPrio then
if Tactical then
self.TacticalQueue:Push(RadioEntry)
elseif IsPrio then
self.PrioRadioQueue:Push(RadioEntry)
else
self.RadioQueue:Push(RadioEntry)
@ -1618,7 +1784,7 @@ function AWACS:_EventHandler(EventData)
if WeaponDesc.category == 1 then
Type = "Missile"
-- AAM
local guidance = WeaponDesc.guidance -- IR=2, Radar Active=3, Radar Semi Active=4, Radar Passive = 5
local guidance = WeaponDesc.guidance or 4 -- IR=2, Radar Active=3, Radar Semi Active=4, Radar Passive = 5
if guidance == 2 then
warndist = 10
elseif guidance == 3 then
@ -2689,8 +2855,9 @@ end
-- @param #AWACS self
-- @param #string Callsign Callsign to address
-- @param #number GID GroupID for comms
-- @param #boolean Tactical Is for tactical info
-- @return #AWACS self
function AWACS:_CreateBogeyDope(Callsign,GID)
function AWACS:_CreateBogeyDope(Callsign,GID,Tactical)
self:T(self.lid.."_CreateBogeyDope for "..Callsign.." GID "..GID)
local managedgroup = self.ManagedGrps[GID] -- #AWACS.ManagedGroup
@ -2716,7 +2883,7 @@ function AWACS:_CreateBogeyDope(Callsign,GID)
local tag = contact.TargetGroupNaming
local reportingname = contact.ReportingName
-- DONE - add tag
self:_AnnounceContact(contact,false,group,true,tag,false,reportingname)
self:_AnnounceContact(contact,false,group,true,tag,false,reportingname,Tactical)
end
end
@ -2841,8 +3008,9 @@ end
--- [Internal] AWACS Menu for Bogey Dope
-- @param #AWACS self
-- @param Wrapper.Group#GROUP Group Group to use
-- @param #boolean Tactical Check for tactical info
-- @return #AWACS self
function AWACS:_BogeyDope(Group)
function AWACS:_BogeyDope(Group,Tactical)
self:T(self.lid.."_BogeyDope")
local text = ""
local textScreen = ""
@ -2853,8 +3021,7 @@ function AWACS:_BogeyDope(Group)
-- no intel yet!
local clean = self.gettext:GetEntry("CLEAN",self.locale)
text = string.format(clean,self:_GetCallSign(Group,GID) or "Ghost 1", self.callsigntxt)
self:_NewRadioEntry(text,text,0,false,true,true,false,true)
self:_NewRadioEntry(text,text,0,false,true,true,false,true,Tactical)
return self
end
@ -2896,7 +3063,7 @@ function AWACS:_BogeyDope(Group)
local clean = self.gettext:GetEntry("CLEAN",self.locale)
text = string.format(clean,self:_GetCallSign(Group,GID) or "Ghost 1", self.callsigntxt)
self:_NewRadioEntry(text,textScreen,GID,Outcome,Outcome,true,false,true)
self:_NewRadioEntry(text,textScreen,GID,Outcome,Outcome,true,false,true,Tactical)
else
@ -2915,9 +3082,9 @@ function AWACS:_BogeyDope(Group)
textScreen = string.format("%s%d %s.\n",textScreen,contactsAO,groupstxt)
end
self:_NewRadioEntry(text,textScreen,GID,Outcome,true,true,false,true)
self:_NewRadioEntry(text,textScreen,GID,Outcome,true,true,false,true,Tactical)
self:_CreateBogeyDope(self:_GetCallSign(Group,GID) or "Ghost 1",GID)
self:_CreateBogeyDope(self:_GetCallSign(Group,GID) or "Ghost 1",GID,Tactical)
end
end
@ -2925,7 +3092,7 @@ function AWACS:_BogeyDope(Group)
-- no, unknown
local nocheckin = self.gettext:GetEntry("NOTCHECKEDIN",self.locale)
text = string.format(nocheckin,self:_GetCallSign(Group,GID) or "Ghost 1", self.callsigntxt)
self:_NewRadioEntry(text,text,GID,Outcome,true,true,false)
self:_NewRadioEntry(text,text,GID,Outcome,true,true,false,Tactical)
end
return self
@ -3528,11 +3695,17 @@ function AWACS:_CheckOut(Group,GID,dead)
local managedgroup = self.ManagedGrps[GID] -- #AWACS.ManagedGroup
local Stack = managedgroup.AnchorStackNo
local Angels = managedgroup.AnchorStackAngels
local GroupName = managedgroup.GroupName
-- remove menus
if managedgroup.IsPlayer then
if self.clientmenus:HasUniqueID(managedgroup.GroupName) then
local menus = self.clientmenus:PullByID(managedgroup.GroupName) --#AWACS.MenuStructure
if self.clientmenus:HasUniqueID(GroupName) then
local menus = self.clientmenus:PullByID(GroupName) --#AWACS.MenuStructure
menus.basemenu:Remove()
if self.TacticalSubscribers[GroupName] then
local Freq = self.TacticalSubscribers[GroupName]
self.TacticalFrequencies[Freq] = Freq
self.TacticalSubscribers[GroupName] = nil
end
end
end
-- delete open tasks
@ -3614,6 +3787,22 @@ function AWACS:_SetClientMenus()
local friendly = MENU_GROUP_COMMAND:New(cgrp,"Friendly",vid,self._VID,self,cgrp,AWACS.IFF.FRIENDLY)
end
local tactical
if self.TacticalMenu then
tactical = MENU_GROUP:New(cgrp,"Tactical Radio",basemenu)
if self.TacticalSubscribers[cgrpname] then
-- unsubscribe
local entry = MENU_GROUP_COMMAND:New(cgrp,"Unsubscribe",tactical,self._UnsubScribeTactRadio,self,cgrp)
else
-- subscribe
for _,_freq in UTILS.spairs(self.TacticalFrequencies) do
local modu = UTILS.GetModulationName(self.TacticalModulation)
local text = string.format("Subscribe to %.3f %s",_freq,modu)
local entry = MENU_GROUP_COMMAND:New(cgrp,text,tactical,self._SubScribeTactRadio,self,cgrp,_freq)
end
end
end
local ainfo = MENU_GROUP_COMMAND:New(cgrp,"Awacs Info",basemenu,self._ShowAwacsInfo,self,cgrp)
local checkout = MENU_GROUP_COMMAND:New(cgrp,"Check Out",basemenu,self._CheckOut,self,cgrp)
@ -3631,6 +3820,7 @@ function AWACS:_SetClientMenus()
unable = unable,
abort = abort,
commit=commit,
tactical=tactical,
}
self.clientmenus:PullByID(cgrpname)
self.clientmenus:Push(menus,cgrpname)
@ -4812,8 +5002,9 @@ end
-- @param #string Tag Tag name for this contact. Alpha, Brave, Charlie ...
-- @param #boolean IsPopup This is a pop-up group
-- @param #string ReportingName The NATO code reporting name for the contact, e.g. "Foxbat". "Bogey" if unknown.
-- @param #boolean Tactical
-- @return #AWACS self
function AWACS:_AnnounceContact(Contact,IsNew,Group,IsBogeyDope,Tag,IsPopup,ReportingName)
function AWACS:_AnnounceContact(Contact,IsNew,Group,IsBogeyDope,Tag,IsPopup,ReportingName,Tactical)
self:T(self.lid.."_AnnounceContact")
-- do we have a group to talk to?
local tag = ""
@ -4940,7 +5131,7 @@ function AWACS:_AnnounceContact(Contact,IsNew,Group,IsBogeyDope,Tag,IsPopup,Repo
BRAText = string.gsub(BRAText,"BRA","brah")
local prio = IsNew or IsBogeyDope
self:_NewRadioEntry(BRAText,TextScreen,GID,isGroup,true,IsNew,false,prio)
self:_NewRadioEntry(BRAText,TextScreen,GID,isGroup,true,IsNew,false,prio,Tactical)
return self
end
@ -5328,6 +5519,15 @@ function AWACS:_MergedCall(GID)
local merge = self.gettext:GetEntry("MERGED",self.locale)
local text = string.format("%s. %s. %s.",self.callsigntxt,pilotcallsign,merge)
self:_NewRadioEntry(text,text,GID,true,self.debug,true,false,true)
if GID and GID ~= 0 then
local managedgroup = self.ManagedGrps[GID] -- #AWACS.ManagedGroup
if managedgroup and managedgroup.Group and managedgroup.Group:IsAlive() then
local name = managedgroup.GroupName
if self.TacticalSubscribers[name] then
self:_NewRadioEntry(text,text,GID,true,self.debug,true,false,true,true)
end
end
end
return self
end
@ -5703,6 +5903,10 @@ function AWACS:onafterStart(From, Event, To)
self:__Started(-5)
end
if self.TacticalMenu then
self:__CheckTacticalQueue(55)
end
self:__Status(-30)
return self
end
@ -6316,6 +6520,77 @@ function AWACS:onafterLostCluster(From,Event,To,Cluster,Mission)
return self
end
--- [Internal] onafterCheckTacticalQueue
-- @param #AWACS self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #AWACS self
function AWACS:onafterCheckTacticalQueue(From,Event,To)
self:T({From, Event, To})
-- do we have messages queued?
if self.clientset:CountAlive() == 0 then
self:T(self.lid.."No player connected.")
self:__CheckTacticalQueue(-5)
return self
end
for _name,_freq in pairs(self.TacticalSubscribers) do
local Group = nil
if _name then
Group = GROUP:FindByName(_name)
end
if Group and Group:IsAlive() then
self:_BogeyDope(Group,true)
end
end
if (self.TacticalQueue:IsNotEmpty()) then
while self.TacticalQueue:Count() > 0 do
local RadioEntry = self.TacticalQueue:Pull() -- #AWACS.RadioEntry
self:T({RadioEntry})
local frequency = self.TacticalBaseFreq
if RadioEntry.GroupID and RadioEntry.GroupID ~= 0 then
local managedgroup = self.ManagedGrps[RadioEntry.GroupID] -- #AWACS.ManagedGroup
if managedgroup and managedgroup.Group and managedgroup.Group:IsAlive() then
local name = managedgroup.GroupName
frequency = self.TacticalSubscribers[name]
end
end
-- AI AWACS Speaking
local gtext = RadioEntry.TextTTS
if self.PathToGoogleKey then
gtext = string.format("<speak><prosody rate='medium'>%s</prosody></speak>",gtext)
end
self.TacticalSRSQ:NewTransmission(gtext,nil,self.TacticalSRS,nil,0.5,nil,nil,nil,frequency,self.TacticalModulation,nil,nil,nil,nil,nil)
self:T(RadioEntry.TextTTS)
if RadioEntry.ToScreen and RadioEntry.TextScreen and (not self.SuppressScreenOutput) then
if RadioEntry.GroupID and RadioEntry.GroupID ~= 0 then
local managedgroup = self.ManagedGrps[RadioEntry.GroupID] -- #AWACS.ManagedGroup
if managedgroup and managedgroup.Group and managedgroup.Group:IsAlive() then
MESSAGE:New(RadioEntry.TextScreen,20,"AWACS"):ToGroup(managedgroup.Group)
self:T(RadioEntry.TextScreen)
end
else
MESSAGE:New(RadioEntry.TextScreen,20,"AWACS"):ToCoalition(self.coalition)
end
end
end
end -- end while
if self:Is("Running") then
self:__CheckTacticalQueue(-self.TacticalInterval)
end
return self
end
--- [Internal] onafterCheckRadioQueue
-- @param #AWACS self
-- @param #string From

View File

@ -4206,11 +4206,13 @@ function FLIGHTGROUP:GetClosestAirbase()
local coord=group:GetCoordinate()
local coalition=self:GetCoalition()
local airbase=coord:GetClosestAirbase() --(nil, coalition)
return airbase
if coord then
local airbase=coord:GetClosestAirbase() --(nil, coalition)
return airbase
else
return nil
end
else
return nil

View File

@ -98,7 +98,7 @@ PLAYERTASK = {
--- PLAYERTASK class version.
-- @field #string version
PLAYERTASK.version="0.1.17"
PLAYERTASK.version="0.1.18"
--- Generic task condition.
-- @type PLAYERTASK.Condition
@ -1008,6 +1008,7 @@ do
-- @field Core.ClientMenu#CLIENTMENUMANAGER ActiveTaskMenuTemplate
-- @field Core.ClientMenu#CLIENTMENU ActiveTopMenu
-- @field Core.ClientMenu#CLIENTMENU ActiveInfoMenu
-- @field Core.ClientMenu#CLIENTMENU MenuNoTask
-- @extends Core.Fsm#FSM
---
@ -1336,6 +1337,7 @@ PLAYERTASKCONTROLLER = {
InfoHasCoordinate = false,
UseTypeNames = false,
Scoring = nil,
MenuNoTask = nil,
}
---
@ -3469,6 +3471,19 @@ function PLAYERTASKCONTROLLER:_UpdateJoinMenuTemplate()
local actinfomenu = self.ActiveInfoMenu
--local entrynumbers = {}
--local existingentries = {}
if self.TaskQueue:Count() == 0 and self.MenuNoTask == nil then
local menunotasks = self.gettext:GetEntry("MENUNOTASKS",self.locale)
self.MenuNoTask = controller:NewEntry(menunotasks,self.JoinMenu)
controller:AddEntry(self.MenuNoTask)
end
if self.TaskQueue:Count() > 0 and self.MenuNoTask ~= nil then
controller:DeleteGenericEntry(self.MenuNoTask)
controller:DeleteF10Entry(self.MenuNoTask)
self.MenuNoTask = nil
end
local maxn = self.menuitemlimit
-- Generate task type menu items
for _type,_ in pairs(taskpertype) do
@ -3641,8 +3656,13 @@ function PLAYERTASKCONTROLLER:_CreateJoinMenuTemplate()
self.JoinInfoMenu = JoinTaskMenuTemplate:NewEntry(menutaskinfo,self.JoinTopMenu)
end
if self.TaskQueue:Count() == 0 then
JoinTaskMenuTemplate:NewEntry(menunotasks,self.JoinMenu)
if self.TaskQueue:Count() == 0 and self.MenuNoTask == nil then
self.MenuNoTask = JoinTaskMenuTemplate:NewEntry(menunotasks,self.JoinMenu)
end
if self.TaskQueue:Count() > 0 and self.MenuNoTask ~= nil then
JoinTaskMenuTemplate:DeleteGenericEntry(self.MenuNoTask)
self.MenuNoTask = nil
end
self.JoinTaskMenuTemplate = JoinTaskMenuTemplate

View File

@ -11,7 +11,7 @@
-- @module Wrapper.Airbase
-- @image Wrapper_Airbase.JPG
---
-- @type AIRBASE
-- @field #string ClassName Name of the class, i.e. "AIRBASE".
-- @field #table CategoryName Names of airbase categories.
@ -548,6 +548,8 @@ AIRBASE.Syria={
-- * AIRBASE.MarianaIslands.Saipan_Intl
-- * AIRBASE.MarianaIslands.Tinian_Intl
-- * AIRBASE.MarianaIslands.Olf_Orote
-- * AIRBASE.MarianaIslands.Pagan_Airstrip
-- * AIRBASE.MarianaIslands.North_West_Field
--
-- @field MarianaIslands
AIRBASE.MarianaIslands = {
@ -557,6 +559,8 @@ AIRBASE.MarianaIslands = {
["Saipan_Intl"] = "Saipan Intl",
["Tinian_Intl"] = "Tinian Intl",
["Olf_Orote"] = "Olf Orote",
["Pagan_Airstrip"] = "Pagan Airstrip",
["North_West_Field"] = "North West Field",
}
--- Airbases of the South Atlantic map:
@ -787,7 +791,13 @@ function AIRBASE:Register(AirbaseName)
-- Category.
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
-- H2 is bugged
--if self.AirbaseName == "H4" and self.descriptors == nil then
--self:E("***** H4 on Syria map is currently bugged!")
--return nil
--end
-- Set category.
if self.category==Airbase.Category.AIRDROME then
self.isAirdrome=true