This commit is contained in:
Frank
2020-04-22 18:06:18 +02:00
parent d2629263c3
commit 7c07df19bf
8 changed files with 18178 additions and 73 deletions
+1 -1
View File
@@ -663,7 +663,7 @@ function SCORE:onbeforeSave(From, Event, To, path, filename)
-- Check default path.
if path==nil and not lfs then
self:E(self.lid.."WARNING: lfs not desanitized. Results will be saved in DCS installation root directory rather than your \"Saved Games\DCS\" folder.")
self:E(self.lid.."WARNING: lfs not desanitized. Results will be saved in DCS installation root directory rather than your \"Saved Games/DCS\" folder.")
end
return true
+11 -2
View File
@@ -1396,17 +1396,26 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
-- Set asset flightgroup.
asset.flightgroup=flightgroup
-- Get the SQUADRON of the asset.
local squadron=self:GetSquadronOfAsset(asset)
-- Set default TACAN channel.
local Tacan=squadron:GetTACAN()
if Tacan then
flightgroup:SetTACAN(Tacan)
flightgroup:SetDefaultTACAN(Tacan)
end
-- Set radio frequency and modulation
local radioFreq, radioModu=squadron:GetRadio()
if radioFreq then
flightgroup:SetDefaultRadio(radioFreq, radioModu)
end
-- Not requested any more.
asset.requested=nil
-- Get Mission (if any).
local mission=self:GetMissionByID(request.assignment)
local mission=self:GetMissionByID(request.assignment)
-- Add mission to flightgroup queue.
if mission then
+55 -52
View File
@@ -1691,7 +1691,7 @@ AIRBOSS.MenuF10Root=nil
--- Airboss class version.
-- @field #string version
AIRBOSS.version="1.1.1"
AIRBOSS.version="1.1.2"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
@@ -1880,6 +1880,9 @@ function AIRBOSS:New(carriername, alias)
-- Default recovery case. This sets self.defaultcase and self.case. Default Case I.
self:SetRecoveryCase()
-- Set time the turn starts before the window opens.
self:SetRecoveryTurnTime()
-- Set holding offset to 0 degrees. This set self.defaultoffset and self.holdingoffset.
self:SetHoldingOffsetAngle()
@@ -2433,6 +2436,15 @@ function AIRBOSS:AddRecoveryWindow(starttime, stoptime, case, holdingoffset, tur
-- Absolute mission time in seconds.
local Tnow=timer.getAbsTime()
if starttime and type(starttime)=="number" then
starttime=UTILS.SecondsToClock(starttime)
end
if stoptime and type(stoptime)=="number" then
stoptime=UTILS.SecondsToClock(stoptime)
end
-- Input or now.
starttime=starttime or UTILS.SecondsToClock(Tnow)
@@ -2598,6 +2610,15 @@ function AIRBOSS:DeleteRecoveryWindow(window, delay)
end
end
--- Set time before carrier turns and recovery window opens.
-- @param #AIRBOSS self
-- @param #number interval Time interval in seconds. Default 600 sec.
-- @return #AIRBOSS self
function AIRBOSS:SetRecoveryTurnTime(interval)
self.dTturn=interval or 600
return self
end
--- Set time interval for updating queues and other stuff.
-- @param #AIRBOSS self
-- @param #number interval Time interval in seconds. Default 30 sec.
@@ -3226,6 +3247,23 @@ function AIRBOSS:SetDebugModeOFF()
return self
end
--- Get next time the carrier will start recovering aircraft.
-- @param #AIRBOSS self
-- @param #boolean InSeconds If true, abs. mission time seconds is returned. Default is a clock #string.
-- @return #number Start time in abs. seconds.
-- @return #number Stop time in abs. seconds.
function AIRBOSS:GetNextRecoveryTime(InSeconds)
if self.recoverywindow then
if InSeconds then
return UTILS.SecondsToClock(self.recoverywindow.START), UTILS.SecondsToClock(self.recverywindow.STOP)
else
return self.recoverywindow.START, self.recverywindow.STOP
end
else
return InSeconds and -1,-1 or "?", "?"
end
end
--- Check if carrier is recovering aircraft.
-- @param #AIRBOSS self
-- @return #boolean If true, time slot for recovery is open.
@@ -3782,7 +3820,7 @@ function AIRBOSS:_CheckRecoveryTimes()
self:RecoveryCase(nextwindow.CASE, nextwindow.OFFSET)
-- Check if time is less than 5 minutes.
if nextwindow.WIND and nextwindow.START-time<5*60 and not self.turnintowind then
if nextwindow.WIND and nextwindow.START-time<self.dTturn and not self.turnintowind then
-- Check that wind is blowing from a direction > 5° different from the current heading.
local hdg=self:GetHeading()
@@ -3805,7 +3843,7 @@ function AIRBOSS:_CheckRecoveryTimes()
self:T(self.lid..string.format("Heading=%03d°, Wind=%03d° %.1f kts, Delta=%03d° ==> U-turn=%s", hdg, wind,UTILS.MpsToKnots(vwind), delta, tostring(uturn)))
-- Time into the wind 1 day or if longer recovery time + the 5 min early.
local t=math.max(nextwindow.STOP-nextwindow.START+300, 60*60*24)
local t=math.max(nextwindow.STOP-nextwindow.START+self.dTturn, 60*60*24)
-- Recovery wind on deck in knots.
local v=UTILS.KnotsToMps(nextwindow.SPEED)
@@ -5964,7 +6002,6 @@ function AIRBOSS:_ScanCarrierZone()
end
end
-- Find new flights that are inside CCA.
for groupname,_group in pairs(insideCCA) do
local group=_group --Wrapper.Group#GROUP
@@ -5978,66 +6015,32 @@ function AIRBOSS:_ScanCarrierZone()
-- Create a new flight group
if knownflight then
-- Debug output.
self:T2(self.lid..string.format("Known flight group %s of type %s in CCA.", groupname, actype))
-- Check if flight is AI and if we want to handle it at all.
if knownflight.ai and self.handleai then
-- Defines if AI group should be handled by the airboss.
local iscarriersquad=true
local putintomarshal=false
-- Check if AI group is part of the group set if a set was defined.
if self.squadsetAI then
local group=self.squadsetAI:FindGroup(groupname)
if group then
iscarriersquad=true
-- Get flight group.
local flight=_DATABASE:GetFlightGroup(groupname)
if flight and flight:IsInBound() and flight.destbase:GetName()==self.carrier:GetName() then
if flight:IsHelo() then
else
iscarriersquad=false
end
end
-- Check if group was explicitly excluded.
if self.excludesetAI then
local group=self.excludesetAI:FindGroup(groupname)
if group then
iscarriersquad=false
putintomarshal=true
end
flight.airboss=self
end
-- Get distance to carrier.
local dist=knownflight.group:GetCoordinate():Get2DDistance(self:GetCoordinate())
-- Close in distance. Is >0 if AC comes closer wrt to first detected distance d0.
local closein=knownflight.dist0-dist
-- Debug info.
self:T3(self.lid..string.format("Known AI flight group %s closed in by %.1f NM", knownflight.groupname, UTILS.MetersToNM(closein)))
-- Is this group the tanker?
local istanker=self.tanker and self.tanker.tanker:GetName()==groupname
-- Is this group the AWACS?
local isawacs=self.awacs and self.awacs.tanker:GetName()==groupname
-- Send tanker to marshal stack?
local tanker2marshal = istanker and self.tanker:IsReturning() and self.tanker.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100 and self.tanker.recovery==true
-- Send AWACS to marhsal stack?
local awacs2marshal = isawacs and self.awacs:IsReturning() and self.awacs.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100 and self.awacs.recovery==true
-- Put flight into Marshal.
local putintomarshal=closein>UTILS.NMToMeters(5) and knownflight.flag==-100 and iscarriersquad and (not istanker) and (not isawacs)
-- Send AI flight to marshal stack if group closes in more than 5 and has initial flag value.
if putintomarshal or tanker2marshal or awacs2marshal then
-- Send AI flight to marshal stack.
if putintomarshal then
-- Get the next free stack for current recovery case.
local stack=self:_GetFreeStack(knownflight.ai)
-- Repawn.
local respawn=self.respawnAI --or tanker2marshal
local respawn=self.respawnAI
if stack then
@@ -6056,8 +6059,9 @@ function AIRBOSS:_ScanCarrierZone()
-- Break the loop to not have all flights at once! Spams the message screen.
break
end -- Closed in or tanker/AWACS
end -- AI
end -- Closed in or tanker/AWACS
end
else
@@ -6070,7 +6074,6 @@ function AIRBOSS:_ScanCarrierZone()
end
-- Find flights that are not in CCA.
local remove={}
for _,_flight in pairs(self.flights) do
File diff suppressed because it is too large Load Diff
+8 -9
View File
@@ -86,10 +86,10 @@
--
-- @field #table enrouteTasks Mission enroute tasks.
--
-- @field #number missionFreq Mission radio frequency in MHz.
-- @field #number missionModu Mission radio modulation (0=AM and 1=FM).
-- @field #number missionTacanChannel Mission TACAN channel.
-- @field #number missionTacanMorse Mission TACAN morse code.
-- @field #number radioFreq Mission radio frequency in MHz.
-- @field #number radioModu Mission radio modulation (0=AM and 1=FM).
-- @field #number tacanChannel Mission TACAN channel.
-- @field #number tacanMorse Mission TACAN morse code.
--
-- @field #number missionRepeated Number of times mission was repeated.
-- @field #number missionRepeatMax Number of times mission is repeated if failed.
@@ -1214,8 +1214,8 @@ end
-- @return #AUFTRAG self
function AUFTRAG:SetRadio(Frequency, Modulation)
self.missionFreq=Frequency
self.missionModu=Modulation or 0
self.radioFreq=Frequency
self.radioModu=Modulation or 0
return self
end
@@ -1227,8 +1227,8 @@ end
-- @return #AUFTRAG self
function AUFTRAG:SetTACAN(Channel, Morse)
self.missionTacanChannel=Channel
self.missionTacanMorse=Morse or "XXX"
self.tacanChannel=Channel
self.tacanMorse=Morse or "XXX"
return self
end
@@ -2694,7 +2694,6 @@ function AUFTRAG:GetDCSMissionTask()
-- FAC Mission --
-----------------
-- TODO
local DCStask=CONTROLLABLE.TaskFAC_AttackGroup(nil, self.engageTarget.Target, self.engageWeaponType, self.facDesignation, self.facDatalink, self.facFrequency, self.facModulation, CallsignName, CallsignNumber)
table.insert(DCStasks, DCStask)
@@ -31,7 +31,7 @@
-- @field #table Qholding Queue of aircraft waiting for landing permission.
-- @field #table Qlanding Queue of aircraft currently on final approach.
-- @field #table Qtaxiinb Queue of aircraft taxiing to parking after landing.
-- @field #table Qarrived Queue of aircraft that have arrived at their parking spot after landing
-- @field #table Qarrived Queue of aircraft that have arrived at their parking spot after landing.
-- @field #table Qparking Queue of aircraft parking and waiting for taxi & takeoff clearance.
-- @field #table Qtaxiout Queue of aircraft taxiing from parking to runway for takeoff.
-- @field #table Qreadyto Queue of aircraft ready for takeoff. Only human players.
+47 -8
View File
@@ -1668,6 +1668,15 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
end
---
-- Airboss Helo
---
if self.ishelo and self.airboss and self:IsHolding() then
if self.airboss:IsRecovering() or self:IsFuelCritical() then
self:ClearToLand()
end
end
-- Next check in ~30 seconds.
if not self:IsStopped() then
@@ -2833,6 +2842,8 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
self:I(self.lid..string.format("RTB: event=%s: %s --> %s", Event, From, To))
self.destbase=airbase
-- Defaults:
SpeedTo=SpeedTo or UTILS.KmphToKnots(self.speedmax*0.75)
SpeedHold=SpeedHold or (self.ishelo and 80 or 250)
@@ -2887,12 +2898,17 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
-- Set holding flag to 0=false.
self.flaghold:Set(0)
local holdtime=5*60
if fc or self.airboss then
holdtime=nil
end
-- Task fuction when reached holding point.
local TaskArrived=self.group:TaskFunction("FLIGHTGROUP._ReachedHolding", self)
-- Orbit until flaghold=1 (true) but max 5 min if no FC is giving the landing clearance.
local TaskOrbit=self.group:TaskOrbit(p0, nil, UTILS.KnotsToMps(SpeedHold), p1)
local TaskLand=self.group:TaskCondition(nil, self.flaghold.UserFlagName, 1, nil, fc and nil or 5*60)
local TaskLand=self.group:TaskCondition(nil, self.flaghold.UserFlagName, 1, nil, holdtime)
local TaskHold=self.group:TaskControlled(TaskOrbit, TaskLand)
local TaskKlar=self.group:TaskFunction("FLIGHTGROUP._ClearedToLand", self) -- Once the holding flag becomes true, set trigger FLIGHTLANDING, i.e. set flight STATUS to LANDING.
@@ -2964,7 +2980,7 @@ end
-- @param Core.Point#COORDINATE Coord Coordinate where to orbit. Default current position.
-- @param #number Altitude Altitude in feet. Default 10000 ft.
-- @param #number Speed Speed in knots. Default 250 kts.
function FLIGHTGROUP:onafterWait(From, Event, To, Coord, Altitude, Speed)
function FLIGHTGROUP:onbeforeWait(From, Event, To, Coord, Altitude, Speed)
local allowed=true
local Tsuspend=nil
@@ -3108,6 +3124,29 @@ function FLIGHTGROUP:onafterHolding(From, Event, To)
self:_UpdateMenu()
end
elseif self.airboss then
if self.ishelo then
local carrierpos=self.airboss:GetCoordinate()
local carrierheading=self.airboss:GetHeading()
local Distance=UTILS.NMToMeters(5)
local Angle=carrierheading+90
local altitude=math.random(12, 25)*100
local oc=carrierpos:Translate(Distance,Angle):SetAltitude(altitude, true)
-- Orbit until flaghold=1 (true) but max 5 min if no FC is giving the landing clearance.
local TaskOrbit=self.group:TaskOrbit(oc, nil, UTILS.KnotsToMps(50))
local TaskLand=self.group:TaskCondition(nil, self.flaghold.UserFlagName, 1)
local TaskHold=self.group:TaskControlled(TaskOrbit, TaskLand)
local TaskKlar=self.group:TaskFunction("FLIGHTGROUP._ClearedToLand", self) -- Once the holding flag becomes true, set trigger FLIGHTLANDING, i.e. set flight STATUS to LANDING.
local DCSTask=self.group:TaskCombo({TaskOrbit, TaskHold, TaskKlar})
self:SetTask(DCSTask)
end
end
end
@@ -3911,12 +3950,12 @@ function FLIGHTGROUP:RouteToMission(mission, delay)
self:SetOptionROT(mission.optionROT)
end
-- Radio
if mission.missionFreq then
self:SwitchRadioOn(mission.missionFreq, mission.missionModu)
if mission.radioFreq then
self:SwitchRadioOn(mission.radioFreq, mission.radioModu)
end
-- TACAN
if mission.missionTacanChannel then
self:SwitchTACANOn(mission.missionTacanChannel, mission.missionTacanMorse)
if mission.tacanChannel then
self:SwitchTACANOn(mission.tacanChannel, mission.tacanMorse)
end
end
end
@@ -5925,12 +5964,12 @@ end
--- Set default Radio frequency and modulation.
-- @param #FLIGHTGROUP self
-- @param #number Frequency Radio frequency in MHz. Default 305 MHz.
-- @param #number Frequency Radio frequency in MHz. Default 251 MHz.
-- @param #number Modulation Radio modulation. Default `radio.Modulation.AM`.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetDefaultRadio(Frequency, Modulation)
self.radioFreqDefault=Frequency or 305
self.radioFreqDefault=Frequency or 251
self.radioModuDefault=Modulation or radio.modulation.AM
self.radioOn=false
+22
View File
@@ -40,6 +40,8 @@
-- @field #number TACANmin TACAN min channel.
-- @field #number TACANmax TACAN max channel.
-- @field #table TACANused Table of used TACAN channels.
-- @field #number radioFreq Radio frequency in MHz the squad uses.
-- @field #number radioModu Radio modulation the squad uses.
-- @extends Core.Fsm#FSM
--- Be surprised!
@@ -228,6 +230,18 @@ function SQUADRON:SetSkill(Skill)
return self
end
--- Set radio frequency and modulation the squad uses.
-- @param #SQUADRON self
-- @param #number Frequency Radio frequency in MHz. Default 251 MHz.
-- @param #number Modulation Radio modulation. Default 0=AM.
-- @usage mysquadron:SetSkill(AI.Skill.EXCELLENT)
-- @return #SQUADRON self
function SQUADRON:SetRadio(Frequency, Modulation)
self.radioFreq=Frequency or 251
self.radioModu=Modulation or radio.modulation.AM
return self
end
--- Set mission types this squadron is able to perform.
-- @param #SQUADRON self
-- @param #table MissionTypes Table of mission types. Can also be passed as a #string if only one type.
@@ -388,6 +402,14 @@ function SQUADRON:DelAsset(Asset)
return self
end
--- Get radio frequency and modulation.
-- @param #SQUADRON self
-- @return #number Radio frequency in MHz.
-- @return #number Radio Modulation (0=AM, 1=FM).
function SQUADRON:GetRadio()
return self.radioFreq, self.radioModu
end
--- Create a callsign for the asset.
-- @param #SQUADRON self
-- @param Ops.AirWing#AIRWING.SquadronAsset Asset The airwing asset.