AIRBOSS v1.0.9

- Case II/III marshal stacks are not collapsed.
- Fixed little bug that Charlie time cannot be calculated if no future recovery window is defined.
This commit is contained in:
Frank 2019-10-22 14:35:10 +02:00
parent fe2ef11f8d
commit 01dd3c93d2

View File

@ -1688,13 +1688,13 @@ AIRBOSS.MenuF10Root=nil
--- Airboss class version.
-- @field #string version
AIRBOSS.version="1.0.8"
AIRBOSS.version="1.0.9"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Handle tanker and AWACS. Put them into pattern.
-- DONE: Handle tanker and AWACS. Put them into pattern.
-- TODO: Handle cases where AI crashes on carrier deck ==> Clean up deck.
-- TODO: Player eject and crash debrief "gradings".
-- TODO: PWO during case 2/3.
@ -1955,7 +1955,7 @@ function AIRBOSS:New(carriername, alias)
-- Smoke zones.
if false then
local case=2
local case=3
self.holdingoffset=30
self:_GetZoneGroove():SmokeZone(SMOKECOLOR.Red, 5)
self:_GetZoneLineup():SmokeZone(SMOKECOLOR.Green, 5)
@ -1963,11 +1963,15 @@ function AIRBOSS:New(carriername, alias)
self:_GetZoneDirtyUp(case):SmokeZone(SMOKECOLOR.Orange, 45)
self:_GetZoneArcIn(case):SmokeZone(SMOKECOLOR.Blue, 45)
self:_GetZoneArcOut(case):SmokeZone(SMOKECOLOR.Blue, 45)
self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Red, 45)
self:_GetZonePlatform(case):SmokeZone(SMOKECOLOR.Blue, 45)
self:_GetZoneCorridor(case):SmokeZone(SMOKECOLOR.Green, 45)
self:_GetZoneHolding(case, 1):SmokeZone(SMOKECOLOR.White, 45)
self:_GetZoneHolding(case, 2):SmokeZone(SMOKECOLOR.White, 45)
self:_GetZoneInitial(case):SmokeZone(SMOKECOLOR.Orange, 45)
self:_GetZoneCommence(case):SmokeZone(SMOKECOLOR.Red, 45)
self:_GetZoneCommence(case, 1):SmokeZone(SMOKECOLOR.Red, 45)
self:_GetZoneCommence(case, 2):SmokeZone(SMOKECOLOR.Red, 45)
self:_GetZoneAbeamLandingSpot():SmokeZone(SMOKECOLOR.Red, 5)
self:_GetZoneLandingSpot():SmokeZone(SMOKECOLOR.Red, 5)
end
-- Carrier parameter debug tests.
@ -2247,6 +2251,29 @@ function AIRBOSS:New(carriername, alias)
-- @param #string filename (Optional) File name. Default is AIRBOSS-*ALIAS*_LSOgrades.csv.
--- Triggers the FSM event "LSOgrade". Called when the LSO grades a player
-- @function [parent=#AIRBOSS] LSOgrade
-- @param #AIRBOSS self
-- @param #AIRBOSS.PlayerData playerData Player Data.
-- @param #AIRBOSS.LSOgrade grade LSO grade.
--- Triggers the FSM event "LSOgrade". Delayed called when the LSO grades a player.
-- @function [parent=#AIRBOSS] __LSOgrade
-- @param #AIRBOSS self
-- @param #number delay Delay in seconds.
-- @param #AIRBOSS.PlayerData playerData Player Data.
-- @param #AIRBOSS.LSOgrade grade LSO grade.
--- On after "LSOgrade" user function. Called when the carrier passes a waypoint of its route.
-- @function [parent=#AIRBOSS] OnAfterLSOgrade
-- @param #AIRBOSS self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #AIRBOSS.PlayerData playerData Player Data.
-- @param #AIRBOSS.LSOgrade grade LSO grade.
--- Triggers the FSM event "LSOGrade". Called when the LSO grades a player
-- @function [parent=#AIRBOSS] LSOGrade
-- @param #AIRBOSS self
@ -3332,12 +3359,19 @@ end
-- @param #string To To state.
function AIRBOSS:onafterStatus(From, Event, To)
if true then
--env.info("FF Status ==> return")
--return
end
-- Get current time.
local time=timer.getTime()
-- Update marshal and pattern queue every 30 seconds.
if time-self.Tqueue>self.dTqueue then
--collectgarbage()
-- Get time.
local clock=UTILS.SecondsToClock(timer.getAbsTime())
local eta=UTILS.SecondsToClock(self:_GetETAatNextWP())
@ -5683,7 +5717,8 @@ function AIRBOSS:_GetNextMarshalFight()
end
-- Check if conditions are right.
if stack==1 and flight.holding~=nil and Tmarshal>=TmarshalMin then
if flight.holding~=nil and Tmarshal>=TmarshalMin then
if flight.case==1 and stack==1 or flight.case>1 then
if flight.ai then
-- Return AI flight.
return flight
@ -5695,6 +5730,7 @@ function AIRBOSS:_GetNextMarshalFight()
end
end
end
end
return nil
end
@ -6681,7 +6717,8 @@ function AIRBOSS:_GetCharlieTime(flightgroup)
-- Time in seconds until the next recovery starts or 0 if window is already open.
Trecovery=math.max(self.recoverywindow.START-Tnow, 0)
else
return nil
-- Set ~7 min if no future recovery window is defined. Otherwise radio call function crashes.
Trecovery=7*60
end
-- Loop over flights currently in the marshal queue.
@ -6701,7 +6738,7 @@ function AIRBOSS:_GetCharlieTime(flightgroup)
-- Check if flight is already holding or just on its way.
if flight.holding==nil then
-- Flight is also on its way to the marshal stack.
-- Flight is on its way to the marshal stack.
-- Coordinate of the holding zone.
local holdingzone=self:_GetZoneHolding(flight.case, 1):GetCoordinate()
@ -6831,8 +6868,8 @@ function AIRBOSS:_CollapseMarshalStack(flight, nopattern)
for _,_flight in pairs(self.Qmarshal) do
local mflight=_flight --#AIRBOSS.PlayerData
-- Only collapse stack of which the flight left. CASE II/III stack is the same.
if (case==1 and mflight.case==1) or (case>1 and mflight.case>1) then
-- Only collapse stack of which the flight left. CASE II/III stacks are not collapsed.
if (case==1 and mflight.case==1) then --or (case>1 and mflight.case>1) then
-- Get current flag/stack value.
local mstack=mflight.flag
@ -6937,6 +6974,96 @@ function AIRBOSS:_GetFreeStack(ai, case, empty)
-- Recovery case.
case=case or self.case
if case==1 then
return self:_GetFreeStack_Old(ai, case, empty)
end
-- Max number of stacks available.
local nmaxstacks=100
if case==1 then
nmaxstacks=self.Nmaxmarshal
end
-- Assume up to two (human) flights per stack. All are free.
local stack={}
for i=1,nmaxstacks do
stack[i]=self.NmaxStack -- Number of human flights per stack.
end
local nmax=1
-- Loop over all flights in marshal stack.
for _,_flight in pairs(self.Qmarshal) do
local flight=_flight --#AIRBOSS.FlightGroup
-- Check that the case is right.
if flight.case==case then
-- Get stack of flight.
local n=flight.flag
if n>nmax then
nmax=n
end
if n>0 then
if flight.ai or flight.case>1 then
stack[n]=0 -- AI get one stack on their own. Also CASE II/III get one stack each.
else
stack[n]=stack[n]-1
end
else
self:E(string.format("ERROR: Flight %s in marshal stack has stack value <= 0. Stack value is %d.", flight.groupname, n))
end
end
end
local nfree=nil
if stack[nmax]==0 then
-- Max occupied stack is completely full!
if case==1 then
if nmax>=nmaxstacks then
-- Already all Case I stacks are occupied ==> wait outside 10 NM zone.
nfree=nil
else
-- Return next free stack.
nfree=nmax+1
end
else
-- Case II/III return next stack
nfree=nmax+1
end
elseif stack[nmax]==self.NmaxStack then
-- Max occupied stack is completely empty! This should happen only when there is no other flight in the marshal queue.
self:E(self.lid..string.format("ERROR: Max occupied stack is empty. Should not happen! Nmax=%d, stack[nmax]=%d", nmax, stack[nmax]))
nfree=nmax
else
-- Max occupied stack is partly full.
if ai or empty or case>1 then
nfree=nmax+1
else
nfree=nmax
end
end
self:I(self.lid..string.format("Returning free stack %s", tostring(nfree)))
return nfree
end
--- Get next free Marshal stack. Depending on AI/human and recovery case.
-- @param #AIRBOSS self
-- @param #boolean ai If true, get a free stack for an AI flight group.
-- @param #number case Recovery case. Default current (self) case in progress.
-- @param #boolean empty Return lowest stack that is completely empty.
-- @return #number Lowest free stack available for the given case or nil if all Case I stacks are taken.
function AIRBOSS:_GetFreeStack_Old(ai, case, empty)
-- Recovery case.
case=case or self.case
-- Max number of stacks available.
local nmaxstacks=100
if case==1 then
@ -8976,7 +9103,7 @@ function AIRBOSS:_Commencing(playerData, zonecheck)
if zonecheck then
-- Get auto commence zone.
local zoneCommence=self:_GetZoneCommence(playerData.case)
local zoneCommence=self:_GetZoneCommence(playerData.case, playerData.flag)
-- Check if unit is in the zone.
local inzone=playerData.unit:IsInZone(zoneCommence)
@ -10911,8 +11038,9 @@ end
--- Get zone where player are automatically commence when enter.
-- @param #AIRBOSS self
-- @param #number case Recovery case.
-- @param #number stack Stack for Case II/III as we commence from stack>=1.
-- @return Core.Zone#ZONE Holding zone.
function AIRBOSS:_GetZoneCommence(case)
function AIRBOSS:_GetZoneCommence(case, stack)
-- Commence zone.
local zone
@ -10950,11 +11078,10 @@ function AIRBOSS:_GetZoneCommence(case)
else
-- Case II/III
-- We simply take the corridor for now. But a bit shorter. Holding starts at 21 and add 2 NM box as commence.
--zone=self:_GetZoneCorridor(case, 23)
stack=stack or 1
-- Total length.
local l=21
-- Start point at 21 NM for stack=1.
local l=20+stack
-- Offset angle
local offset=self:GetRadial(case, false, true)
@ -17301,7 +17428,7 @@ function AIRBOSS:_MarkMarshalZone(_unitName, flare)
local zoneHolding=self:_GetZoneHolding(case, stack)
-- Get Case I commence zone at three position.
local zoneThree=self:_GetZoneCommence(case)
local zoneThree=self:_GetZoneCommence(case, stack)
-- Pattern alitude.
local patternalt=self:_GetMarshalAltitude(stack, case)