Merge branch 'FF/Ops' into FF/OpsDev

This commit is contained in:
Frank 2023-10-13 21:33:33 +02:00
commit 068465a8f2
10 changed files with 616 additions and 65 deletions

View File

@ -52,7 +52,7 @@
-- ===
--
-- ### Author: **FlightControl**
-- ### Contributions:
-- ### Contributions: **Applevangelist**
--
-- ===
--
@ -371,7 +371,9 @@ function MESSAGE:ToCoalition( CoalitionSide, Settings )
trigger.action.outTextForCoalition( CoalitionSide, self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
end
end
self.CoalitionSide = CoalitionSide
return self
end
@ -454,3 +456,154 @@ function MESSAGE:ToLogIf( Condition )
end
return self
end
_MESSAGESRS = {}
--- Set up MESSAGE generally to allow Text-To-Speech via SRS and TTS functions.
-- @param #string PathToSRS Path to SRS Folder, defaults to "C:\\\\Program Files\\\\DCS-SimpleRadio-Standalone".
-- @param #number Port Port number of SRS, defaults to 5002.
-- @param #string PathToCredentials (optional) Path to credentials file for e.g. Google.
-- @param #number Frequency Frequency in MHz. Can also be given as a #table of frequencies.
-- @param #number Modulation Modulation, i.e. radio.modulation.AM or radio.modulation.FM. Can also be given as a #table of modulations.
-- @param #string Gender (optional) Gender, i.e. "male" or "female", defaults to "male".
-- @param #string Culture (optional) Culture, e.g. "en-US", defaults to "en-GB"
-- @param #string Voice (optional) Voice. Will override gender and culture settings, e.g. MSRS.Voices.Microsoft.Hazel or MSRS.Voices.Google.Standard.de_DE_Standard_D. Hint on Microsoft voices - working voices are limited to Hedda, Hazel, David, Zira and Hortense. **Must** be installed on your Desktop or Server!
-- @param #number Coalition (optional) Coalition, can be coalition.side.RED, coalition.side.BLUE or coalition.side.NEUTRAL. Defaults to coalition.side.NEUTRAL.
-- @param #number Volume (optional) Volume, can be between 0.0 and 1.0 (loudest).
-- @param #string Label (optional) Label, defaults to "MESSAGE" or the Message Category set.
-- @param Core.Point#COORDINATE Coordinate (optional) Coordinate this messages originates from.
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
--
function MESSAGE.SetMSRS(PathToSRS,Port,PathToCredentials,Frequency,Modulation,Gender,Culture,Voice,Coalition,Volume,Label,Coordinate)
local path = PathToSRS or "C:\\Program Files\\DCS-SimpleRadio-Standalone"
_MESSAGESRS.MSRS = MSRS:New(path,Frequency,Modulation,Volume)
_MESSAGESRS.MSRS:SetCoalition(Coalition)
_MESSAGESRS.MSRS:SetCoordinate(Coordinate)
_MESSAGESRS.MSRS:SetCulture(Culture)
_MESSAGESRS.MSRS:SetFrequencies(Frequency)
_MESSAGESRS.MSRS:SetGender(Gender)
_MESSAGESRS.MSRS:SetGoogle(PathToCredentials)
_MESSAGESRS.MSRS:SetLabel(Label or "MESSAGE")
_MESSAGESRS.MSRS:SetModulations(Modulation)
_MESSAGESRS.MSRS:SetPath(PathToSRS)
_MESSAGESRS.MSRS:SetPort(Port)
_MESSAGESRS.MSRS:SetVolume(Volume)
_MESSAGESRS.MSRS:SetVoice(Voice)
_MESSAGESRS.SRSQ = MSRSQUEUE:New(Label or "MESSAGE")
end
--- Sends a message via SRS.
-- @param #MESSAGE self
-- @param #number frequency (optional) Frequency in MHz. Can also be given as a #table of frequencies. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #number modulation (optional) Modulation, i.e. radio.modulation.AM or radio.modulation.FM. Can also be given as a #table of modulations. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #string gender (optional) Gender, i.e. "male" or "female". Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string culture (optional) Culture, e.g. "en-US. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string voice (optional) Voice. Will override gender and culture settings. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #number coalition (optional) Coalition, can be coalition.side.RED, coalition.side.BLUE or coalition.side.NEUTRAL. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #number volume (optional) Volume, can be between 0.0 and 1.0 (loudest). Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param Core.Point#COORDINATE coordinate (optional) Coordinate this messages originates from. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @return #MESSAGE self
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRS()
--
function MESSAGE:ToSRS(frequency,modulation,gender,culture,voice,coalition,volume,coordinate)
if _MESSAGESRS.SRSQ then
_MESSAGESRS.MSRS:SetLabel(self.MessageCategory or _MESSAGESRS.MSRS.Label or "MESSAGE")
if gender then
_MESSAGESRS.MSRS:SetGender(gender)
end
if coalition then
_MESSAGESRS.MSRS:SetCoalition(coalition)
end
if culture then
_MESSAGESRS.MSRS:SetCulture(culture)
end
if volume then
_MESSAGESRS.MSRS:SetVolume(volume)
end
if coordinate then
_MESSAGESRS.MSRS:SetCoordinate(coordinate)
end
if voice then
_MESSAGESRS.MSRS:SetVoice(voice)
end
_MESSAGESRS.SRSQ:NewTransmission(self.MessageText,nil,_MESSAGESRS.MSRS,nil,1,nil,nil,nil,frequency,modulation)
end
return self
end
--- Sends a message via SRS on the blue coalition side.
-- @param #MESSAGE self
-- @param #number frequency (optional) Frequency in MHz. Can also be given as a #table of frequencies. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #number modulation (optional) Modulation, i.e. radio.modulation.AM or radio.modulation.FM. Can also be given as a #table of modulations. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #string gender (optional) Gender, i.e. "male" or "female". Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string culture (optional) Culture, e.g. "en-US. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string voice (optional) Voice. Will override gender and culture settings. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #number volume (optional) Volume, can be between 0.0 and 1.0 (loudest). Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param Core.Point#COORDINATE coordinate (optional) Coordinate this messages originates from. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @return #MESSAGE self
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.BLUE)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSBlue()
--
function MESSAGE:ToSRSBlue(frequency,modulation,gender,culture,voice,volume,coordinate)
self:ToSRS(frequency,modulation,gender,culture,voice,coalition.side.BLUE,volume,coordinate)
return self
end
--- Sends a message via SRS on the red coalition side.
-- @param #MESSAGE self
-- @param #number frequency (optional) Frequency in MHz. Can also be given as a #table of frequencies. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #number modulation (optional) Modulation, i.e. radio.modulation.AM or radio.modulation.FM. Can also be given as a #table of modulations. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #string gender (optional) Gender, i.e. "male" or "female". Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string culture (optional) Culture, e.g. "en-US. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string voice (optional) Voice. Will override gender and culture settings. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #number volume (optional) Volume, can be between 0.0 and 1.0 (loudest). Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param Core.Point#COORDINATE coordinate (optional) Coordinate this messages originates from. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @return #MESSAGE self
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.RED)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSRed()
--
function MESSAGE:ToSRSRed(frequency,modulation,gender,culture,voice,volume,coordinate)
self:ToSRS(frequency,modulation,gender,culture,voice,coalition.side.RED,volume,coordinate)
return self
end
--- Sends a message via SRS to all - via the neutral coalition side.
-- @param #MESSAGE self
-- @param #number frequency (optional) Frequency in MHz. Can also be given as a #table of frequencies. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #number modulation (optional) Modulation, i.e. radio.modulation.AM or radio.modulation.FM. Can also be given as a #table of modulations. Only needed if you want to override defaults set with `MESSAGE.SetMSRS()` for this one setting.
-- @param #string gender (optional) Gender, i.e. "male" or "female". Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string culture (optional) Culture, e.g. "en-US. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #string voice (optional) Voice. Will override gender and culture settings. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param #number volume (optional) Volume, can be between 0.0 and 1.0 (loudest). Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @param Core.Point#COORDINATE coordinate (optional) Coordinate this messages originates from. Only needed if you want to change defaults set with `MESSAGE.SetMSRS()`.
-- @return #MESSAGE self
-- @usage
-- -- Mind the dot here, not using the colon this time around!
-- -- Needed once only
-- MESSAGE.SetMSRS("D:\\Program Files\\DCS-SimpleRadio-Standalone",5012,nil,127,radio.modulation.FM,"female","en-US",nil,coalition.side.NEUTRAL)
-- -- later on in your code
-- MESSAGE:New("Test message!",15,"SPAWN"):ToSRSAll()
--
function MESSAGE:ToSRSAll(frequency,modulation,gender,culture,voice,volume,coordinate)
self:ToSRS(frequency,modulation,gender,culture,voice,coalition.side.NEUTRAL,volume,coordinate)
return self
end

View File

@ -6052,7 +6052,29 @@ do -- SET_ZONE
return self
end
--- Get the average aggregated coordinate of this set of zones.
-- @param #SET_ZONE self
-- @return Core.Point#COORDINATE
function SET_ZONE:GetAverageCoordinate()
local x,y,z = 0,0,0
local count = 0
for _,_zone in pairs(self.Set) do
local zone=_zone --Core.Zone#ZONE
local vec3 = zone:GetVec3()
x = x + vec3.x
y = y + vec3.y
z = z + vec3.z
count = count + 1
end
if count > 1 then
x = x/count
y = y/count
z = z/count
end
local coord = COORDINATE:New(x,y,z)
return coord
end
--- Private function.
-- @param #SET_ZONE self

View File

@ -113,14 +113,9 @@
-- -- Start missile trainer.
-- fox:Start()
--
-- # Fine Tuning
--
-- Todo!
--
-- # Special Events
--
-- Todo!
-- # Notes
--
-- The script needs to be running before you enter an airplane slot. If FOX is not available to you, go back to observers and then join a slot again.
--
-- @field #FOX
FOX = {

View File

@ -50,6 +50,11 @@
-- * **100 meter**: Destroys the missile when the distance to the aircraft is below or equal to 100 meter.
-- * **150 meter**: Destroys the missile when the distance to the aircraft is below or equal to 150 meter.
-- * **200 meter**: Destroys the missile when the distance to the aircraft is below or equal to 200 meter.
--
-- # Developer Note
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE.
-- Therefore, this class is considered to be deprecated and superseded by the [Functional.Fox](https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Functional.Fox.html) class, which provides the same functionality.
--
-- ===
--
@ -101,7 +106,7 @@
-- # Developer Note
--
-- Note while this class still works, it is no longer supported as the original author stopped active development of MOOSE.
-- Therefore, this class is considered to be deprecated and superseded by the @{Functional.Fox#FOX} class, which provides the same functionality.
-- Therefore, this class is considered to be deprecated and superseded by the [Functional.Fox](https://flightcontrol-master.github.io/MOOSE_DOCS_DEVELOP/Documentation/Functional.Fox.html) class, which provides the same functionality.
--
-- @field #MISSILETRAINER
MISSILETRAINER = {

View File

@ -253,8 +253,7 @@
-- # Sound Files
--
-- More than 180 individual sound files have been created using a text-to-speech program. All ATIS information is given with en-US accent.
--
-- Check out the pinned messages in the Moose discord #ops-atis channel.
-- You can find the sound files [here](https://github.com/FlightControl-Master/MOOSE_SOUND/releases). Also check out the pinned messages in the Moose discord #ops-atis channel.
--
-- To include the files, open the mission (.miz) file with, *e.g.*, 7-zip. Then just drag-n-drop the file into the miz.
--

View File

@ -34,14 +34,17 @@
-- @field Core.Set#SET_ZONE zonesetCAP Set of CAP zones.
-- @field Core.Set#SET_ZONE zonesetTANKER Set of TANKER zones.
-- @field Core.Set#SET_ZONE zonesetAWACS Set of AWACS zones.
-- @field Core.Set#SET_ZONE zonesetRECON Set of RECON zones.
-- @field #number nflightsCAP Number of CAP flights constantly in the air.
-- @field #number nflightsAWACS Number of AWACS flights constantly in the air.
-- @field #number nflightsTANKERboom Number of TANKER flights with BOOM constantly in the air.
-- @field #number nflightsTANKERprobe Number of TANKER flights with PROBE constantly in the air.
-- @field #number nflightsRescueHelo Number of Rescue helo flights constantly in the air.
-- @field #number nflightsRecon Number of Recon flights constantly in the air.
-- @field #table pointsCAP Table of CAP points.
-- @field #table pointsTANKER Table of Tanker points.
-- @field #table pointsAWACS Table of AWACS points.
-- @field #table pointsRecon Table of RECON points.
-- @field #boolean markpoints Display markers on the F10 map.
-- @field Ops.Airboss#AIRBOSS airboss Airboss attached to this wing.
--
@ -123,6 +126,7 @@ AIRWING = {
pointsCAP = {},
pointsTANKER = {},
pointsAWACS = {},
pointsRecon = {},
markpoints = false,
}
@ -175,7 +179,7 @@ AIRWING = {
--- AIRWING class version.
-- @field #string version
AIRWING.version="0.9.2"
AIRWING.version="0.9.3"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list
@ -219,6 +223,7 @@ function AIRWING:New(warehousename, airwingname)
-- Defaults:
self.nflightsCAP=0
self.nflightsAWACS=0
self.nflightsRecon=0
self.nflightsTANKERboom=0
self.nflightsTANKERprobe=0
self.nflightsRecoveryTanker=0
@ -734,6 +739,15 @@ function AIRWING:SetNumberAWACS(n)
return self
end
--- Set number of RECON flights constantly in the air.
-- @param #AIRWING self
-- @param #number n Number of flights. Default 1.
-- @return #AIRWING self
function AIRWING:SetNumberRecon(n)
self.nflightsRecon=n or 1
return self
end
--- Set number of Rescue helo flights constantly in the air.
-- @param #AIRWING self
-- @param #number n Number of flights. Default 1.
@ -819,6 +833,23 @@ function AIRWING:AddPatrolPointCAP(Coordinate, Altitude, Speed, Heading, LegLeng
return self
end
--- Add a patrol Point for RECON missions.
-- @param #AIRWING self
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point.
-- @param #number Altitude Orbit altitude in feet.
-- @param #number Speed Orbit speed in knots.
-- @param #number Heading Heading in degrees.
-- @param #number LegLength Length of race-track orbit in NM.
-- @return #AIRWING self
function AIRWING:AddPatrolPointRecon(Coordinate, Altitude, Speed, Heading, LegLength)
local patrolpoint=self:NewPatrolPoint("RECON", Coordinate, Altitude, Speed, Heading, LegLength)
table.insert(self.pointsRecon, patrolpoint)
return self
end
--- Add a patrol Point for TANKER missions.
-- @param #AIRWING self
-- @param Core.Point#COORDINATE Coordinate Coordinate of the patrol point.
@ -971,6 +1002,9 @@ function AIRWING:onafterStatus(From, Event, To)
-- Check Rescue Helo missions.
self:CheckRescuhelo()
-- Check Recon missions.
self:CheckRECON()
----------------
-- Transport ---
----------------
@ -1111,6 +1145,58 @@ function AIRWING:CheckCAP()
return self
end
--- Check how many RECON missions are assigned and add number of missing missions.
-- @param #AIRWING self
-- @return #AIRWING self
function AIRWING:CheckRECON()
local Ncap=0 --self:CountMissionsInQueue({AUFTRAG.Type.GCICAP, AUFTRAG.Type.INTERCEPT})
-- Count CAP missions.
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
if mission:IsNotOver() and mission.type==AUFTRAG.Type.RECON and mission.patroldata then
Ncap=Ncap+1
end
end
--self:I(self.lid.."Number of active RECON Missions: "..Ncap)
for i=1,self.nflightsRecon-Ncap do
--self:I(self.lid.."Creating RECON Missions: "..i)
local patrol=self:_GetPatrolData(self.pointsRecon)
local altitude=patrol.altitude --+1000*patrol.noccupied
local ZoneSet = SET_ZONE:New()
local Zone = ZONE_RADIUS:New(self.alias.." Recon "..math.random(1,10000),patrol.coord:GetVec2(),UTILS.NMToMeters(patrol.leg/2))
ZoneSet:AddZone(Zone)
if self.Debug then
Zone:DrawZone(self.coalition,{0,0,1},Alpha,FillColor,FillAlpha,2,true)
end
local missionRECON=AUFTRAG:NewRECON(ZoneSet,patrol.speed,patrol.altitude,true)
missionRECON.patroldata=patrol
missionRECON.categories={AUFTRAG.Category.AIRCRAFT}
patrol.noccupied=patrol.noccupied+1
if self.markpoints then AIRWING.UpdatePatrolPointMarker(patrol) end
self:AddMission(missionRECON)
end
return self
end
--- Check how many TANKER missions are assigned and add number of missing missions.
-- @param #AIRWING self
-- @return #AIRWING self

View File

@ -1339,9 +1339,9 @@ function AUFTRAG:NewCAP(ZoneCAP, Altitude, Speed, Coordinate, Heading, Leg, Targ
return mission
end
--- **[AIR]** Create a CAP mission on a group.
--- **[AIR]** Create a CAP mission over a (moving) group.
-- @param #AUFTRAG self
-- @param Wrapper.Group#GROUP Grp.
-- @param Wrapper.Group#GROUP Grp The grp to perform the CAP over.
-- @param #number Altitude Orbit altitude in feet. Default is 6,000 ft.
-- @param #number Speed Orbit speed in knots. Default 250 KIAS.
-- @param #number RelHeading Relative heading [0, 360) of race-track pattern in degrees wrt heading of the carrier. Default is heading of the carrier.
@ -2229,7 +2229,9 @@ function AUFTRAG:NewRECON(ZoneSet, Speed, Altitude, Adinfinitum, Randomly, Forma
local mission=AUFTRAG:New(AUFTRAG.Type.RECON)
mission:_TargetFromObject(ZoneSet)
mission.missionZoneSet = ZoneSet
mission.missionTask=mission:GetMissionTaskforMissionType(AUFTRAG.Type.RECON)
mission.optionROE=ENUMS.ROE.WeaponHold
@ -2669,7 +2671,7 @@ function AUFTRAG:NewAUTO(EngageGroup)
elseif auftrag==AUFTRAG.Type.ORBIT then
mission=AUFTRAG:NewORBIT(Coordinate,Altitude,Speed,Heading,Leg)
elseif auftrag==AUFTRAG.Type.RECON then
-- Not implemented yet.
mission=AUFTRAG:NewRECON(ZoneSet,Speed,Altitude,Adinfinitum,Randomly,Formation)
elseif auftrag==AUFTRAG.Type.RESCUEHELO then
mission=AUFTRAG:NewRESCUEHELO(Carrier)
elseif auftrag==AUFTRAG.Type.SEAD then
@ -5362,6 +5364,10 @@ function AUFTRAG:GetTargetCoordinate()
-- Special case where we defined a
return self.transportPickup
elseif self.missionZoneSet and self.type == AUFTRAG.Type.RECON then
return self.missionZoneSet:GetAverageCoordinate()
elseif self.engageTarget then

View File

@ -61,6 +61,8 @@
-- You need to load an .ogg soundfile for the pilot\'s beacons into the mission, e.g. "beacon.ogg", use a once trigger, "sound to country" for that.
-- Create a late-activated single infantry unit as template in the mission editor and name it e.g. "Downed Pilot".
--
-- Example sound files are here: [Moose Sound](https://github.com/FlightControl-Master/MOOSE_SOUND/tree/master/CTLD%20CSAR)
--
-- ## 1. Basic Setup
--
-- A basic setup example is the following:

View File

@ -616,6 +616,8 @@ do
-- You need to load an .ogg soundfile for the pilot\'s beacons into the mission, e.g. "beacon.ogg", use a once trigger, "sound to country" for that.
-- Create the late-activated troops, vehicles, that will make up your deployable forces.
--
-- Example sound files are here: [Moose Sound](https://github.com/FlightControl-Master/MOOSE_SOUND/tree/master/CTLD%20CSAR)
--
-- ## 1. Basic Setup
--
-- ## 1.1 Create and start a CTLD instance

View File

@ -55,12 +55,15 @@
-- @field #table ManagedSQ
-- @field #table ManagedCP
-- @field #table ManagedTK
-- @field #table ManagedEWR
-- @field #table ManagedREC
-- @field #number MaxAliveMissions
-- @field #boolean debug
-- @field #number repeatsonfailure
-- @field Core.Set#SET_ZONE GoZoneSet
-- @field Core.Set#SET_ZONE NoGoZoneSet
-- @field #boolean Monitor
-- @field #boolean TankerInvisible
-- @extends Core.Fsm#FSM
--- *“Airspeed, altitude, and brains. Two are always needed to successfully complete the flight.”* -- Unknown.
@ -137,8 +140,15 @@
-- -- **Note** If you need different tanker types, i.e. Boom and Drogue, set them up at different AirWings!
-- -- Add a tanker point
-- mywing:AddPatrolPointTanker(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone Tanker"):GetCoordinate(),20000,280,270,50)
-- -- Add a tanker squad
-- mywing:AddTankerSquadron("Blue Tanker","Tanker Ops Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.EXCELLENT,602)
-- -- Add an AWACS squad - Radio 251 AM, TACAN 51Y
-- mywing:AddTankerSquadron("Blue Tanker","Tanker Ops Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.EXCELLENT,602,nil,251,radio.modulation.AM,51)
--
-- ### Add an AWACS (optional)
--
-- -- Add an AWACS point
-- mywing:AddPatrolPointAwacs(AIRBASE.Caucasus.Kutaisi,ZONE:FindByName("Blue Zone AWACS"):GetCoordinate(),25000,300,270,50)
-- -- Add a tanker squad - Radio 251 AM, TACAN 51Y
-- mywing:AddAWACSSquadron("Blue AWACS","AWACS Ops Kutaisi",AIRBASE.Caucasus.Kutaisi,20,AI.Skill.AVERAGE,702,nil,271,radio.modulation.AM)
--
-- # Fine-Tuning
--
@ -153,8 +163,14 @@
-- * @{#EASYGCICAP.SetDefaultMissionRange}: Set how many NM the planes can go from the home base, defaults to 100.
-- * @{#EASYGCICAP.SetDefaultNumberAlter5Standby}: Set how many planes will be spawned on cold standby (Alert5), default 2.
-- * @{#EASYGCICAP.SetDefaultEngageRange}: Set max engage range for CAP flights if they detect intruders, defaults to 50.
-- * @{#EASYGCICAP.SetMaxAliveMissions}: Set max parallel missions can be done (CAP+GCI+Alert5+Tanker), defaults to 6.
-- * @{#EASYGCICAP.SetMaxAliveMissions}: Set max parallel missions can be done (CAP+GCI+Alert5+Tanker+AWACS), defaults to 8.
-- * @{#EASYGCICAP.SetDefaultRepeatOnFailure}: Set max repeats on failure for intercepting/killing intruders, defaults to 3.
-- * @{#EASYGCICAP.SetTankerAndAWACSInvisible}: Set Tanker and AWACS to be invisible to enemy AI eyes. Is set to `true` by default.
--
-- ## Debug and Monitor
--
-- mywing.debug = true -- log information
-- mywing.Monitor = true -- show some statistics on screen
--
--
-- @field #EASYGCICAP
@ -181,13 +197,16 @@ EASYGCICAP = {
ManagedSQ = {},
ManagedCP = {},
ManagedTK = {},
MaxAliveMissions = 6,
ManagedEWR = {},
ManagedREC = {},
MaxAliveMissions = 8,
debug = false,
engagerange = 50,
repeatsonfailure = 3,
GoZoneSet = nil,
NoGoZoneSet = nil,
Monitor = false,
TankerInvisible = true,
}
--- Internal Squadron data type
@ -200,6 +219,11 @@ EASYGCICAP = {
-- @field #string Modex
-- @field #string Livery
-- @field #boolean Tanker
-- @field #boolean AWACS
-- @field #boolean RECON
-- @field #number Frequency
-- @field #number Modulation
-- @field #number TACAN
--- Internal Wing data type
-- @type EASYGCICAP.Wing
@ -218,7 +242,7 @@ EASYGCICAP = {
--- EASYGCICAP class version.
-- @field #string version
EASYGCICAP.version="0.0.7"
EASYGCICAP.version="0.0.8"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@ -260,10 +284,11 @@ function EASYGCICAP:New(Alias, AirbaseName, Coalition, EWRName)
self.capgrouping = 2
self.missionrange = 100
self.noaltert5 = 2
self.MaxAliveMissions = 6
self.MaxAliveMissions = 8
self.engagerange = 50
self.repeatsonfailure = 3
self.Monitor = false
self.TankerInvisible = true
-- Set some string id for output to DCS.log file.
self.lid=string.format("EASYGCICAP %s | ", self.alias)
@ -289,13 +314,23 @@ end
-------------------------------------------------------------------------
--- Set Tanker and AWACS to be invisible to enemy AI eyes
-- @param #EASYGCICAP self
-- @param #boolean Switch Set to true or false, by default this is set to true already
-- @return #EASYGCICAP self
function EASYGCICAP:SetTankerAndAWACSInvisible(Switch)
self:T(self.lid.."SetTankerAndAWACSInvisible")
self.TankerInvisible = Switch
return self
end
--- Set Maximum of alive missions to stop airplanes spamming the map
-- @param #EASYGCICAP self
-- @param #number Maxiumum Maxmimum number of parallel missions allowed. Count is Cap-Missions + Intercept-Missions + Alert5-Missionsm default is 6
-- @return #EASYGCICAP self
function EASYGCICAP:SetMaxAliveMissions(Maxiumum)
self:T(self.lid.."SetDefaultResurrection")
self.MaxAliveMissions = Maxiumum or 6
self.MaxAliveMissions = Maxiumum or 8
return self
end
@ -443,13 +478,22 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
-- Create Airwing
local CAP_Wing = AIRWING:New(Airbasename,Alias)
CAP_Wing:SetVerbosityLevel(3)
CAP_Wing:SetReportOff()
CAP_Wing:SetMarker(false)
CAP_Wing:SetAirbase(AIRBASE:FindByName(Airbasename))
CAP_Wing:SetRespawnAfterDestroyed()
CAP_Wing:SetNumberCAP(self.capgrouping)
CAP_Wing:SetNumberTankerBoom(1)
CAP_Wing:SetNumberTankerProbe(1)
if #self.ManagedTK > 0 then
CAP_Wing:SetNumberTankerBoom(1)
CAP_Wing:SetNumberTankerProbe(1)
end
if #self.ManagedAW > 0 then
CAP_Wing:SetNumberAWACS(1)
end
if #self.ManagedREC > 0 then
CAP_Wing:SetNumberRecon(1)
end
--local PatrolCoordinateKutaisi = ZONE:New(CapZoneName):GetCoordinate()
--CAP_Wing:AddPatrolPointCAP(PatrolCoordinateKutaisi,self.capalt,UTILS.KnotsToAltKIAS(self.capspeed,self.capalt),self.capdir,self.capleg)
CAP_Wing:SetTakeoffHot()
@ -459,20 +503,33 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias)
local Intel = self.Intel
local TankerInvisible = self.TankerInvisible
function CAP_Wing:OnAfterFlightOnMission(From, Event, To, Flightgroup, Mission)
local flightgroup = Flightgroup -- Ops.FlightGroup#FLIGHTGROUP
--flightgroup:SetDespawnAfterLanding()
flightgroup:SetDespawnAfterHolding()
flightgroup:SetDestinationbase(AIRBASE:FindByName(Airbasename))
flightgroup:GetGroup():CommandEPLRS(true,5)
flightgroup:SetEngageDetectedOn(self.engagerange,{"Air"},self.GoZoneSet,self.NoGoZoneSet)
flightgroup:GetGroup():OptionROTEvadeFire()
flightgroup:SetOutOfAAMRTB()
if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS and Mission.type ~= AUFTRAG.Type.RECON then
flightgroup:SetDetection(true)
flightgroup:SetEngageDetectedOn(self.engagerange,{"Air"},self.GoZoneSet,self.NoGoZoneSet)
flightgroup:SetOutOfAAMRTB()
end
if Mission.type == AUFTRAG.Type.TANKER or Mission.type == AUFTRAG.Type.AWACS or Mission.type == AUFTRAG.Type.RECON then
if TankerInvisible then
flightgroup:GetGroup():SetCommandInvisible(true)
end
if Mission.type == AUFTRAG.Type.RECON then
flightgroup:SetDetection(true)
end
end
flightgroup:GetGroup():OptionROTEvadeFire()
flightgroup:SetFuelLowRTB(true)
Intel:AddAgent(flightgroup)
--function flightgroup:OnAfterHolding(From,Event,To)
--self:ClearToLand(5)
--end
function flightgroup:OnAfterHolding(From,Event,To)
self:ClearToLand(5)
end
end
@ -513,6 +570,31 @@ function EASYGCICAP:AddPatrolPointCAP(AirbaseName,Coordinate,Altitude,Speed,Head
return self
end
--- Add a RECON patrol point to a Wing
-- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate.
-- @param #number Altitude Defaults to 25000 feet.
-- @param #number Speed Defaults to 300 knots.
-- @param #number Heading Defaults to 90 degrees (East).
-- @param #number LegLength Defaults to 15 NM.
-- @return #EASYGCICAP self
function EASYGCICAP:AddPatrolPointRecon(AirbaseName,Coordinate,Altitude,Speed,Heading,LegLength)
self:T(self.lid.."AddPatrolPointRecon "..Coordinate:ToStringLLDDM())
local EntryCAP = {} -- #EASYGCICAP.CapPoint
EntryCAP.AirbaseName = AirbaseName
EntryCAP.Coordinate = Coordinate
EntryCAP.Altitude = Altitude or 25000
EntryCAP.Speed = Speed or 300
EntryCAP.Heading = Heading or 90
EntryCAP.LegLength = LegLength or 15
self.ManagedREC[#self.ManagedREC+1] = EntryCAP
if self.debug then
local mark = MARKER:New(Coordinate,self.lid.."Patrol Point Recon"):ToAll()
end
return self
end
--- Add a TANKER patrol point to a Wing
-- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase
@ -538,6 +620,31 @@ function EASYGCICAP:AddPatrolPointTanker(AirbaseName,Coordinate,Altitude,Speed,H
return self
end
--- Add an AWACS patrol point to a Wing
-- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate.
-- @param #number Altitude Defaults to 25000 feet.
-- @param #number Speed Defaults to 300 knots.
-- @param #number Heading Defaults to 90 degrees (East).
-- @param #number LegLength Defaults to 15 NM.
-- @return #EASYGCICAP self
function EASYGCICAP:AddPatrolPointAwacs(AirbaseName,Coordinate,Altitude,Speed,Heading,LegLength)
self:T(self.lid.."AddPatrolPointAwacs "..Coordinate:ToStringLLDDM())
local EntryCAP = {} -- #EASYGCICAP.CapPoint
EntryCAP.AirbaseName = AirbaseName
EntryCAP.Coordinate = Coordinate
EntryCAP.Altitude = Altitude or 25000
EntryCAP.Speed = Speed or 300
EntryCAP.Heading = Heading or 90
EntryCAP.LegLength = LegLength or 15
self.ManagedEWR[#self.ManagedEWR+1] = EntryCAP
if self.debug then
local mark = MARKER:New(Coordinate,self.lid.."Patrol Point AWACS"):ToAll()
end
return self
end
--- (Internal) Set actual Tanker Points from the list
-- @param #EASYGCICAP self
-- @return #EASYGCICAP self
@ -557,6 +664,25 @@ function EASYGCICAP:_SetTankerPatrolPoints()
return self
end
--- (Internal) Set actual Awacs Points from the list
-- @param #EASYGCICAP self
-- @return #EASYGCICAP self
function EASYGCICAP:_SetAwacsPatrolPoints()
self:T(self.lid.."_SetAwacsPatrolPoints")
for _,_data in pairs(self.ManagedEWR) do
local data = _data --#EASYGCICAP.CapPoint
local Wing = self.wings[data.AirbaseName][1] -- Ops.AirWing#AIRWING
local Coordinate = data.Coordinate
local Altitude = data.Altitude
local Speed = data.Speed
local Heading = data.Heading
local LegLength = data.LegLength
Wing:AddPatrolPointAWACS(Coordinate,Altitude,Speed,Heading,LegLength)
end
return self
end
--- (Internal) Set actual PatrolPoints from the list
-- @param #EASYGCICAP self
-- @return #EASYGCICAP self
@ -576,25 +702,22 @@ function EASYGCICAP:_SetCAPPatrolPoints()
return self
end
--- (Internal) Add a CAP patrol point to a Wing
--- (Internal) Set actual PatrolPoints from the list
-- @param #EASYGCICAP self
-- @param #string AirbaseName Name of the Wing's airbase
-- @param Core.Point#COORDINATE Coordinate.
-- @param #number Altitude Defaults to 25000 feet.
-- @param #number Speed Defaults to 300 knots.
-- @param #number Heading Defaults to 90 degrees (East).
-- @param #number LegLength Defaults to 15 NM.
-- @return #EASYGCICAP self
function EASYGCICAP:_AddPatrolPointCAP(AirbaseName,Coordinate,Altitude,Speed,Heading,LegLength)
self:T(self.lid.."_AddPatrolPointCAP")
local airbasename = AirbaseName or self.airbasename
local coordinate = Coordinate
local Altitude = Altitude or 25000
local Speed = Speed or 300
local Heading = Heading or 90
local LegLength = LegLength or 15
local wing = self.wings[airbasename][1] -- Ops.AirWing#AIRWING
wing:AddPatrolPointCAP(coordinate,Altitude,Speed,Heading,LegLength)
-- @return #EASYGCICAP self
function EASYGCICAP:_SetReconPatrolPoints()
self:T(self.lid.."_SetReconPatrolPoints")
for _,_data in pairs(self.ManagedREC) do
local data = _data --#EASYGCICAP.CapPoint
local Wing = self.wings[data.AirbaseName][1] -- Ops.AirWing#AIRWING
local Coordinate = data.Coordinate
local Altitude = data.Altitude
local Speed = data.Speed
local Heading = data.Heading
local LegLength = data.LegLength
Wing:AddPatrolPointRecon(Coordinate,Altitude,Speed,Heading,LegLength)
end
return self
end
@ -612,8 +735,15 @@ function EASYGCICAP:_CreateSquads()
local Skill = squad.Skill
local Modex = squad.Modex
local Livery = squad.Livery
local Frequeny = squad.Frequency
local Modulation = squad.Modulation
local TACAN = squad.TACAN
if squad.Tanker then
self:_AddTankerSquadron(TemplateName,SquadName,AirbaseName,AirFrames,Skill,Modex,Livery)
self:_AddTankerSquadron(TemplateName,SquadName,AirbaseName,AirFrames,Skill,Modex,Livery,Frequeny,Modulation,TACAN)
elseif squad.AWACS then
self:_AddAWACSSquadron(TemplateName,SquadName,AirbaseName,AirFrames,Skill,Modex,Livery,Frequeny,Modulation)
elseif squad.RECON then
self:_AddReconSquadron(TemplateName,SquadName,AirbaseName,AirFrames,Skill,Modex,Livery)
else
self:_AddSquadron(TemplateName,SquadName,AirbaseName,AirFrames,Skill,Modex,Livery)
end
@ -648,7 +778,7 @@ function EASYGCICAP:AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames,
return self
end
--- Add a Tanker Squadron to an Airwing of the manager
--- Add a Recon Squadron to an Airwing of the manager
-- @param #EASYGCICAP self
-- @param #string TemplateName Name of the group template.
-- @param #string SquadName Squadron name - must be unique!
@ -658,8 +788,8 @@ end
-- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used.
-- @return #EASYGCICAP self
function EASYGCICAP:AddTankerSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery)
self:T(self.lid.."AddTankerSquadron "..SquadName)
function EASYGCICAP:AddReconSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery)
self:T(self.lid.."AddReconSquadron "..SquadName)
-- Add Squadron Data
local EntrySQ = {} -- #EASYGCICAP.Squad
EntrySQ.TemplateName = TemplateName
@ -669,6 +799,40 @@ function EASYGCICAP:AddTankerSquadron(TemplateName, SquadName, AirbaseName, AirF
EntrySQ.Skill = Skill or AI.Skill.AVERAGE
EntrySQ.Modex = Modex or 402
EntrySQ.Livery = Livery
EntrySQ.RECON = true
self.ManagedSQ[SquadName] = EntrySQ
return self
end
--- Add a Tanker Squadron to an Airwing of the manager
-- @param #EASYGCICAP self
-- @param #string TemplateName Name of the group template.
-- @param #string SquadName Squadron name - must be unique!
-- @param #string AirbaseName Name of the airbase the airwing resides on, e.g. AIRBASE.Caucasus.Kutaisi
-- @param #number AirFrames Number of available airframes, e.g. 20.
-- @param #string Skill(optional) Skill level, e.g. AI.Skill.AVERAGE
-- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used.
-- @param #number Frequency (optional) Radio Frequency to be used.
-- @param #number Modulation (optional) Radio Modulation to be used, e.g. radio.modulation.AM or radio.modulation.FM
-- @param #number TACAN (optional) TACAN channel, e.g. 71, resulting in Channel 71Y
-- @return #EASYGCICAP self
function EASYGCICAP:AddTankerSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery, Frequency, Modulation, TACAN)
self:T(self.lid.."AddTankerSquadron "..SquadName)
-- Add Squadron Data
local EntrySQ = {} -- #EASYGCICAP.Squad
EntrySQ.TemplateName = TemplateName
EntrySQ.SquadName = SquadName
EntrySQ.AirbaseName = AirbaseName
EntrySQ.AirFrames = AirFrames or 20
EntrySQ.Skill = Skill or AI.Skill.AVERAGE
EntrySQ.Modex = Modex or 602
EntrySQ.Livery = Livery
EntrySQ.Frequency = Frequency
EntrySQ.Modulation = Livery
EntrySQ.TACAN = TACAN
EntrySQ.Tanker = true
self.ManagedSQ[SquadName] = EntrySQ
@ -676,6 +840,38 @@ function EASYGCICAP:AddTankerSquadron(TemplateName, SquadName, AirbaseName, AirF
return self
end
--- Add an AWACS Squadron to an Airwing of the manager
-- @param #EASYGCICAP self
-- @param #string TemplateName Name of the group template.
-- @param #string SquadName Squadron name - must be unique!
-- @param #string AirbaseName Name of the airbase the airwing resides on, e.g. AIRBASE.Caucasus.Kutaisi
-- @param #number AirFrames Number of available airframes, e.g. 20.
-- @param #string Skill(optional) Skill level, e.g. AI.Skill.AVERAGE
-- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used.
-- @param #number Frequency (optional) Radio Frequency to be used.
-- @param #number Modulation (optional) Radio Modulation to be used, e.g. radio.modulation.AM or radio.modulation.FM
-- @return #EASYGCICAP self
function EASYGCICAP:AddAWACSSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery, Frequency, Modulation)
self:T(self.lid.."AddAWACSSquadron "..SquadName)
-- Add Squadron Data
local EntrySQ = {} -- #EASYGCICAP.Squad
EntrySQ.TemplateName = TemplateName
EntrySQ.SquadName = SquadName
EntrySQ.AirbaseName = AirbaseName
EntrySQ.AirFrames = AirFrames or 20
EntrySQ.Skill = Skill or AI.Skill.AVERAGE
EntrySQ.Modex = Modex or 702
EntrySQ.Livery = Livery
EntrySQ.Frequency = Frequency
EntrySQ.Modulation = Livery
EntrySQ.AWACS = true
self.ManagedSQ[SquadName] = EntrySQ
return self
end
--- (Internal) Add a Squadron to an Airwing of the manager
-- @param #EASYGCICAP self
-- @param #string TemplateName Name of the group template.
@ -685,8 +881,10 @@ end
-- @param #string Skill(optional) Skill level, e.g. AI.Skill.AVERAGE
-- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used.
-- @param #number Frequency (optional) Radio Frequency to be used.
-- @param #number Modulation (optional) Radio Modulation to be used, e.g. radio.modulation.AM or radio.modulation.FM
-- @return #EASYGCICAP self
function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery)
function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery, Frequency, Modulation)
self:T(self.lid.."_AddSquadron "..SquadName)
-- Add Squadrons
local Squadron_One = SQUADRON:New(TemplateName,AirFrames,SquadName)
@ -707,7 +905,7 @@ function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames
return self
end
--- (Internal) Add a Tanker Squadron to an Airwing of the manager
--- (Internal) Add a Recon Squadron to an Airwing of the manager
-- @param #EASYGCICAP self
-- @param #string TemplateName Name of the group template.
-- @param #string SquadName Squadron name - must be unique!
@ -717,11 +915,11 @@ end
-- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used.
-- @return #EASYGCICAP self
function EASYGCICAP:_AddTankerSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery)
self:T(self.lid.."_AddTankerSquadron "..SquadName)
function EASYGCICAP:_AddReconSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery)
self:T(self.lid.."_AddReconSquadron "..SquadName)
-- Add Squadrons
local Squadron_One = SQUADRON:New(TemplateName,AirFrames,SquadName)
Squadron_One:AddMissionCapability({AUFTRAG.Type.TANKER})
Squadron_One:AddMissionCapability({AUFTRAG.Type.RECON})
--Squadron_One:SetFuelLowRefuel(true)
Squadron_One:SetFuelLowThreshold(0.3)
Squadron_One:SetTurnoverTime(10,20)
@ -732,12 +930,81 @@ function EASYGCICAP:_AddTankerSquadron(TemplateName, SquadName, AirbaseName, Air
local wing = self.wings[AirbaseName][1] -- Ops.AirWing#AIRWING
wing:AddSquadron(Squadron_One)
wing:NewPayload(TemplateName,-1,{AUFTRAG.Type.RECON},75)
return self
end
--- (Internal) Add a Tanker Squadron to an Airwing of the manager
-- @param #EASYGCICAP self
-- @param #string TemplateName Name of the group template.
-- @param #string SquadName Squadron name - must be unique!
-- @param #string AirbaseName Name of the airbase the airwing resides on, e.g. AIRBASE.Caucasus.Kutaisi
-- @param #number AirFrames Number of available airframes, e.g. 20.
-- @param #string Skill(optional) Skill level, e.g. AI.Skill.AVERAGE
-- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used.
-- @param #number Frequency (optional) Radio frequency of the Tanker
-- @param #number Modulation (Optional) Radio modulation of the Tanker
-- @param #number TACAN (Optional) TACAN Channel to be used, will always be an "Y" channel
-- @return #EASYGCICAP self
function EASYGCICAP:_AddTankerSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery, Frequency, Modulation, TACAN)
self:T(self.lid.."_AddTankerSquadron "..SquadName)
-- Add Squadrons
local Squadron_One = SQUADRON:New(TemplateName,AirFrames,SquadName)
Squadron_One:AddMissionCapability({AUFTRAG.Type.TANKER})
--Squadron_One:SetFuelLowRefuel(true)
Squadron_One:SetFuelLowThreshold(0.3)
Squadron_One:SetTurnoverTime(10,20)
Squadron_One:SetModex(Modex)
Squadron_One:SetLivery(Livery)
Squadron_One:SetSkill(Skill or AI.Skill.AVERAGE)
Squadron_One:SetMissionRange(self.missionrange)
Squadron_One:SetRadio(Frequency,Modulation)
Squadron_One:AddTacanChannel(TACAN,TACAN)
local wing = self.wings[AirbaseName][1] -- Ops.AirWing#AIRWING
wing:AddSquadron(Squadron_One)
wing:NewPayload(TemplateName,-1,{AUFTRAG.Type.TANKER},75)
return self
end
--- (Internal) Add a AWACS Squadron to an Airwing of the manager
-- @param #EASYGCICAP self
-- @param #string TemplateName Name of the group template.
-- @param #string SquadName Squadron name - must be unique!
-- @param #string AirbaseName Name of the airbase the airwing resides on, e.g. AIRBASE.Caucasus.Kutaisi
-- @param #number AirFrames Number of available airframes, e.g. 20.
-- @param #string Skill(optional) Skill level, e.g. AI.Skill.AVERAGE
-- @param #string Modex (optional) Modex to be used,e.g. 402.
-- @param #string Livery (optional) Livery name to be used.
-- @param #number Frequency (optional) Radio frequency of the AWACS
-- @param #number Modulation (Optional) Radio modulation of the AWACS
-- @return #EASYGCICAP self
function EASYGCICAP:_AddAWACSSquadron(TemplateName, SquadName, AirbaseName, AirFrames, Skill, Modex, Livery, Frequency, Modulation)
self:T(self.lid.."_AddAWACSSquadron "..SquadName)
-- Add Squadrons
local Squadron_One = SQUADRON:New(TemplateName,AirFrames,SquadName)
Squadron_One:AddMissionCapability({AUFTRAG.Type.AWACS})
--Squadron_One:SetFuelLowRefuel(true)
Squadron_One:SetFuelLowThreshold(0.3)
Squadron_One:SetTurnoverTime(10,20)
Squadron_One:SetModex(Modex)
Squadron_One:SetLivery(Livery)
Squadron_One:SetSkill(Skill or AI.Skill.AVERAGE)
Squadron_One:SetMissionRange(self.missionrange)
Squadron_One:SetRadio(Frequency,Modulation)
local wing = self.wings[AirbaseName][1] -- Ops.AirWing#AIRWING
wing:AddSquadron(Squadron_One)
wing:NewPayload(TemplateName,-1,{AUFTRAG.Type.AWACS},75)
return self
end
--- Add a zone to the accepted zones set.
-- @param #EASYGCICAP self
-- @param Core.Zone#ZONE_BASE Zone
@ -809,7 +1076,12 @@ function EASYGCICAP:_StartIntel()
local clustersize = self:ClusterCountUnits(Cluster) or 1
local wingsize = math.abs(overhead * (clustersize+1))
if wingsize > maxsize then wingsize = maxsize end
if (not Cluster.mission) and (wingsize > 0) then
-- existing mission, and if so - done?
local retrymission = true
if Cluster.mission and (not Cluster.mission:IsOver()) then
retrymission = false
end
if (retrymission) and (wingsize >= 1) then
MESSAGE:New(string.format("**** %s Interceptors need wingsize %d", UTILS.GetCoalitionName(self.coalition), wingsize),15,"CAPGCI"):ToAllIf(self.debug):ToLog()
for _,_data in pairs (wings) do
local airwing = _data[1] -- Ops.AirWing#AIRWING
@ -920,6 +1192,8 @@ function EASYGCICAP:onafterStart(From,Event,To)
self:_CreateSquads()
self:_SetCAPPatrolPoints()
self:_SetTankerPatrolPoints()
self:_SetAwacsPatrolPoints()
self:_SetReconPatrolPoints()
self:__Status(-10)
return self
end
@ -957,20 +1231,27 @@ function EASYGCICAP:onafterStatus(From,Event,To)
local caps = counttable(self.ManagedCP)
local assets = 0
local instock = 0
local capmission = 0
local interceptmission = 0
local reconmission = 0
for _,_wing in pairs(self.wings) do
local count = _wing[1]:CountAssetsOnMission(MissionTypes,Cohort)
local count2 = _wing[1]:CountAssets(true,MissionTypes,Attributes)
capmission = capmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.GCICAP})
interceptmission = interceptmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.INTERCEPT})
reconmission = reconmission + _wing[1]:CountMissionsInQueue({AUFTRAG.Type.RECON})
assets = assets + count
instock = instock + count2
end
if self.debug then
self:I(self.lid.."Wings: "..wings.." | Squads: "..squads.." | CapPoints: "..caps.." | Assets on Mission: "..assets.." | Assets in Stock: "..instock)
end
if self.Monitor then
local threatcount = #self.Intel.Clusters or 0
local text = "GCICAP "..self.alias
text = text.."\nWings: "..wings.."\nSquads: "..squads.."\nCapPoints: "..caps.."\nAssets on Mission: "..assets.."\nAssets in Stock: "..instock
text = text.."\nThreats:"..threatcount
text = text.."\nThreats: "..threatcount
text = text.."\nMissions: "..capmission+interceptmission
text = text.."\n - CAP: "..capmission
text = text.."\n - Intercept: "..interceptmission
text = text.."\n - Recon: "..reconmission
MESSAGE:New(text,15,"GCICAP"):ToAll():ToLogIf(self.debug)
end
self:__Status(30)