From 8c44cf8fca29171aabc7af7c2bf152247d0485f8 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Fri, 6 Oct 2023 11:31:35 +0200 Subject: [PATCH] #EasyGCICAP * Added Recon Patrol points --- Moose Development/Moose/Ops/AirWing.lua | 88 +++++++++++- Moose Development/Moose/Ops/Auftrag.lua | 14 +- Moose Development/Moose/Ops/EasyGCICAP.lua | 156 +++++++++++++++++---- 3 files changed, 226 insertions(+), 32 deletions(-) diff --git a/Moose Development/Moose/Ops/AirWing.lua b/Moose Development/Moose/Ops/AirWing.lua index 4cfbe36a7..ed166e23d 100644 --- a/Moose Development/Moose/Ops/AirWing.lua +++ b/Moose Development/Moose/Ops/AirWing.lua @@ -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 diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 46b957dd7..b501813c8 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -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 diff --git a/Moose Development/Moose/Ops/EasyGCICAP.lua b/Moose Development/Moose/Ops/EasyGCICAP.lua index 5891b12de..248318fe7 100644 --- a/Moose Development/Moose/Ops/EasyGCICAP.lua +++ b/Moose Development/Moose/Ops/EasyGCICAP.lua @@ -56,6 +56,7 @@ -- @field #table ManagedCP -- @field #table ManagedTK -- @field #table ManagedEWR +-- @field #table ManagedREC -- @field #number MaxAliveMissions -- @field #boolean debug -- @field #number repeatsonfailure @@ -197,6 +198,7 @@ EASYGCICAP = { ManagedCP = {}, ManagedTK = {}, ManagedEWR = {}, + ManagedREC = {}, MaxAliveMissions = 8, debug = false, engagerange = 50, @@ -218,6 +220,7 @@ EASYGCICAP = { -- @field #string Livery -- @field #boolean Tanker -- @field #boolean AWACS +-- @field #boolean RECON -- @field #number Frequency -- @field #number Modulation -- @field #number TACAN @@ -475,14 +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) - CAP_Wing:SetNumberAWACS(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() @@ -500,13 +511,17 @@ function EASYGCICAP:_AddAirwing(Airbasename, Alias) flightgroup:SetDespawnAfterHolding() flightgroup:SetDestinationbase(AIRBASE:FindByName(Airbasename)) flightgroup:GetGroup():CommandEPLRS(true,5) - if Mission.type ~= AUFTRAG.Type.TANKER and Mission.type ~= AUFTRAG.Type.AWACS then + 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 then + 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) + flightgroup:GetGroup():SetCommandInvisible(true) + end + if Mission.type == AUFTRAG.Type.RECON then + flightgroup:SetDetection(true) end end flightgroup:GetGroup():OptionROTEvadeFire() @@ -555,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 @@ -662,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 @@ -705,6 +742,8 @@ function EASYGCICAP:_CreateSquads() 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 @@ -739,6 +778,34 @@ function EASYGCICAP:AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames, return self end +--- 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! +-- @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. +-- @return #EASYGCICAP self +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 + EntrySQ.SquadName = SquadName + EntrySQ.AirbaseName = AirbaseName + EntrySQ.AirFrames = AirFrames or 20 + 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. @@ -838,6 +905,37 @@ function EASYGCICAP:_AddSquadron(TemplateName, SquadName, AirbaseName, AirFrames return self end +--- (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! +-- @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. +-- @return #EASYGCICAP self +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.RECON}) + --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) + + 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. @@ -1095,6 +1193,7 @@ function EASYGCICAP:onafterStart(From,Event,To) self:_SetCAPPatrolPoints() self:_SetTankerPatrolPoints() self:_SetAwacsPatrolPoints() + self:_SetReconPatrolPoints() self:__Status(-10) return self end @@ -1134,11 +1233,13 @@ function EASYGCICAP:onafterStatus(From,Event,To) 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 @@ -1147,9 +1248,10 @@ function EASYGCICAP:onafterStatus(From,Event,To) 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.."\Missions: "..capmission+interceptmission - text = text.."\ - CAP: "..capmission - text = text.."\ - Intercept: "..interceptmission + 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)