AIRBOSS / ATIS deleted extra char before degree char. Small correction for CSAR landings at Airports

This commit is contained in:
Applevangelist 2021-08-18 09:28:30 +02:00
parent 9a05f5bc93
commit 30623f7d38
3 changed files with 85 additions and 84 deletions

View File

@ -383,13 +383,13 @@ ATIS.Alphabet = {
--- Runway correction for converting true to magnetic heading. --- Runway correction for converting true to magnetic heading.
-- @type ATIS.RunwayM2T -- @type ATIS.RunwayM2T
-- @field #number Caucasus 0° (East). -- @field #number Caucasus 0° (East).
-- @field #number Nevada +12° (East). -- @field #number Nevada +12° (East).
-- @field #number Normandy -10° (West). -- @field #number Normandy -10° (West).
-- @field #number PersianGulf +2° (East). -- @field #number PersianGulf +2° (East).
-- @field #number TheChannel -10° (West). -- @field #number TheChannel -10° (West).
-- @field #number Syria +5° (East). -- @field #number Syria +5° (East).
-- @field #number MarianaIslands +2° (East). -- @field #number MarianaIslands +2° (East).
ATIS.RunwayM2T={ ATIS.RunwayM2T={
Caucasus=0, Caucasus=0,
Nevada=12, Nevada=12,
@ -839,9 +839,9 @@ function ATIS:SetMapMarks(switch)
return self return self
end end
--- Set magnetic runway headings as depicted on the runway, *e.g.* "13" for 130° or "25L" for the left runway with magnetic heading 250°. --- Set magnetic runway headings as depicted on the runway, *e.g.* "13" for 130° or "25L" for the left runway with magnetic heading 250°.
-- @param #ATIS self -- @param #ATIS self
-- @param #table headings Magnetic headings. Inverse (-180°) headings are added automatically. You only need to specify one heading per runway direction. "L"eft and "R" right can also be appended. -- @param #table headings Magnetic headings. Inverse (-180°) headings are added automatically. You only need to specify one heading per runway direction. "L"eft and "R" right can also be appended.
-- @return #ATIS self -- @return #ATIS self
function ATIS:SetRunwayHeadingsMagnetic(headings) function ATIS:SetRunwayHeadingsMagnetic(headings)
@ -974,12 +974,12 @@ end
-- --
-- To get *true* from *magnetic* heading one has to add easterly or substract westerly variation, e.g -- To get *true* from *magnetic* heading one has to add easterly or substract westerly variation, e.g
-- --
-- A magnetic heading of 180° corresponds to a true heading of -- A magnetic heading of 180° corresponds to a true heading of
-- --
-- * 186° on the Caucaus map -- * 186° on the Caucaus map
-- * 192° on the Nevada map -- * 192° on the Nevada map
-- * 170° on the Normany map -- * 170° on the Normany map
-- * 182° on the Persian Gulf map -- * 182° on the Persian Gulf map
-- --
-- Likewise, to convert *true* into *magnetic* heading, one has to substract easterly and add westerly variation. -- Likewise, to convert *true* into *magnetic* heading, one has to substract easterly and add westerly variation.
-- --
@ -1314,7 +1314,7 @@ function ATIS:onafterBroadcast(From, Event, To)
local g= 9.80665 --[m/s^2] local g= 9.80665 --[m/s^2]
local M= 0.0289644 --[kg/mol] local M= 0.0289644 --[kg/mol]
local T0=coord:GetTemperature(0)+273.15 --[K] Temp at sea level. local T0=coord:GetTemperature(0)+273.15 --[K] Temp at sea level.
local TS=288.15 -- Standard Temperature assumed by Altimeter is 15°C local TS=288.15 -- Standard Temperature assumed by Altimeter is 15°C
local q=qnh*100 local q=qnh*100
-- Calculate Pressure. -- Calculate Pressure.
@ -1451,13 +1451,13 @@ function ATIS:onafterBroadcast(From, Event, To)
--- Temperature and Dew Point --- --- Temperature and Dew Point ---
--------------------------------- ---------------------------------
-- Temperature in °C. -- Temperature in °C.
local temperature=coord:GetTemperature(height+5) local temperature=coord:GetTemperature(height+5)
-- Dew point in °C. -- Dew point in °C.
local dewpoint=temperature-(100-self.relHumidity)/5 local dewpoint=temperature-(100-self.relHumidity)/5
-- Convert to °F. -- Convert to °F.
if self.TDegF then if self.TDegF then
temperature=UTILS.CelciusToFarenheit(temperature) temperature=UTILS.CelciusToFarenheit(temperature)
dewpoint=UTILS.CelciusToFarenheit(dewpoint) dewpoint=UTILS.CelciusToFarenheit(dewpoint)
@ -1901,15 +1901,15 @@ function ATIS:onafterBroadcast(From, Event, To)
-- Temperature -- Temperature
if self.TDegF then if self.TDegF then
if temperature<0 then if temperature<0 then
subtitle=string.format("Temperature -%s °F", TEMPERATURE) subtitle=string.format("Temperature -%s °F", TEMPERATURE)
else else
subtitle=string.format("Temperature %s °F", TEMPERATURE) subtitle=string.format("Temperature %s °F", TEMPERATURE)
end end
else else
if temperature<0 then if temperature<0 then
subtitle=string.format("Temperature -%s °C", TEMPERATURE) subtitle=string.format("Temperature -%s °C", TEMPERATURE)
else else
subtitle=string.format("Temperature %s °C", TEMPERATURE) subtitle=string.format("Temperature %s °C", TEMPERATURE)
end end
end end
local _TEMPERATURE=subtitle local _TEMPERATURE=subtitle
@ -1930,15 +1930,15 @@ function ATIS:onafterBroadcast(From, Event, To)
-- Dew point -- Dew point
if self.TDegF then if self.TDegF then
if dewpoint<0 then if dewpoint<0 then
subtitle=string.format("Dew point -%s °F", DEWPOINT) subtitle=string.format("Dew point -%s °F", DEWPOINT)
else else
subtitle=string.format("Dew point %s °F", DEWPOINT) subtitle=string.format("Dew point %s °F", DEWPOINT)
end end
else else
if dewpoint<0 then if dewpoint<0 then
subtitle=string.format("Dew point -%s °C", DEWPOINT) subtitle=string.format("Dew point -%s °C", DEWPOINT)
else else
subtitle=string.format("Dew point %s °C", DEWPOINT) subtitle=string.format("Dew point %s °C", DEWPOINT)
end end
end end
local _DEWPOINT=subtitle local _DEWPOINT=subtitle
@ -2276,8 +2276,8 @@ function ATIS:onafterReport(From, Event, To, Text)
-- Replace other stuff. -- Replace other stuff.
local text=string.gsub(text, "SM", "statute miles") local text=string.gsub(text, "SM", "statute miles")
local text=string.gsub(text, "°C", "degrees Celsius") local text=string.gsub(text, "°C", "degrees Celsius")
local text=string.gsub(text, "°F", "degrees Fahrenheit") local text=string.gsub(text, "°F", "degrees Fahrenheit")
local text=string.gsub(text, "inHg", "inches of Mercury") local text=string.gsub(text, "inHg", "inches of Mercury")
local text=string.gsub(text, "mmHg", "millimeters of Mercury") local text=string.gsub(text, "mmHg", "millimeters of Mercury")
local text=string.gsub(text, "hPa", "hecto Pascals") local text=string.gsub(text, "hPa", "hecto Pascals")
@ -2397,7 +2397,7 @@ end
--- Get runway from user supplied magnetic heading. --- Get runway from user supplied magnetic heading.
-- @param #ATIS self -- @param #ATIS self
-- @param #number windfrom Wind direction (from) in degrees. -- @param #number windfrom Wind direction (from) in degrees.
-- @return #string Runway magnetic heading divided by ten (and rounded). Eg, "13" for 130°. -- @return #string Runway magnetic heading divided by ten (and rounded). Eg, "13" for 130°.
function ATIS:GetMagneticRunway(windfrom) function ATIS:GetMagneticRunway(windfrom)
local diffmin=nil local diffmin=nil
@ -2440,7 +2440,7 @@ function ATIS:GetNavPoint(navpoints, runway, left)
local navL=self:GetRunwayLR(nav.runway) local navL=self:GetRunwayLR(nav.runway)
local hdgD=UTILS.HdgDiff(navy,rwyy) local hdgD=UTILS.HdgDiff(navy,rwyy)
if hdgD<=15 then --We allow an error of +-15° here. if hdgD<=15 then --We allow an error of +-15° here.
if navL==nil or (navL==true and left==true) or (navL==false and left==false) then if navL==nil or (navL==true and left==true) or (navL==false and left==false) then
return nav return nav
end end

View File

@ -725,7 +725,7 @@
-- --
-- The same holds true after the recovery window closes. The carrier will head back to the place where he left its assigned route and resume the path to the next waypoint defined in the mission editor. -- The same holds true after the recovery window closes. The carrier will head back to the place where he left its assigned route and resume the path to the next waypoint defined in the mission editor.
-- --
-- Note that the carrier will only head into the wind, if the wind direction is different by more than 5° from the current heading of the carrier (the angled runway, if any, fis taken into account here). -- Note that the carrier will only head into the wind, if the wind direction is different by more than 5° from the current heading of the carrier (the angled runway, if any, fis taken into account here).
-- --
-- === -- ===
-- --
@ -864,10 +864,10 @@
-- --
-- The graph displays the lineup error (LUE) as a function of the distance to the carrier. -- The graph displays the lineup error (LUE) as a function of the distance to the carrier.
-- --
-- The pilot approaches the carrier from the port side, LUE>0°, at a distance of ~1 NM. -- The pilot approaches the carrier from the port side, LUE>0°, at a distance of ~1 NM.
-- At the beginning of the groove (X), he significantly overshoots to the starboard side (LUE<5°). -- At the beginning of the groove (X), he significantly overshoots to the starboard side (LUE<5°).
-- In the middle (IM), he performs good corrections and smoothly reduces the lineup error. -- In the middle (IM), he performs good corrections and smoothly reduces the lineup error.
-- Finally, at a distance of ~0.3 NM (IC) he has corrected his lineup with the runway to a reasonable level, |LUE|<0.5°. -- Finally, at a distance of ~0.3 NM (IC) he has corrected his lineup with the runway to a reasonable level, |LUE|<0.5°.
-- --
-- ## Glideslope Error -- ## Glideslope Error
-- --
@ -876,7 +876,7 @@
-- The graph displays the glideslope error (GSE) as a function of the distance to the carrier. -- The graph displays the glideslope error (GSE) as a function of the distance to the carrier.
-- --
-- In this case the pilot already enters the groove (X) below the optimal glideslope. He is not able to correct his height in the IM part and -- In this case the pilot already enters the groove (X) below the optimal glideslope. He is not able to correct his height in the IM part and
-- stays significantly too low. In close, he performs a harsh correction to gain altitude and ends up even slightly too high (GSE>0.5°). -- stays significantly too low. In close, he performs a harsh correction to gain altitude and ends up even slightly too high (GSE>0.5°).
-- At his point further corrections are necessary. -- At his point further corrections are necessary.
-- --
-- ## Angle of Attack -- ## Angle of Attack
@ -2438,7 +2438,7 @@ end
-- @param #number duration Default duration of the recovery in minutes. Default 30 min. -- @param #number duration Default duration of the recovery in minutes. Default 30 min.
-- @param #number windondeck Default wind on deck in knots. Default 25 knots. -- @param #number windondeck Default wind on deck in knots. Default 25 knots.
-- @param #boolean uturn U-turn after recovery window closes on=true or off=false/nil. Default off. -- @param #boolean uturn U-turn after recovery window closes on=true or off=false/nil. Default off.
-- @param #number offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30°. -- @param #number offset Relative Marshal radial in degrees for Case II/III recoveries. Default 30°.
-- @return #AIRBOSS self -- @return #AIRBOSS self
function AIRBOSS:SetMenuRecovery(duration, windondeck, uturn, offset) function AIRBOSS:SetMenuRecovery(duration, windondeck, uturn, offset)
@ -3878,7 +3878,7 @@ function AIRBOSS:_CheckRecoveryTimes()
-- Check if time is less than 5 minutes. -- Check if time is less than 5 minutes.
if nextwindow.WIND and nextwindow.START-time<self.dTturn 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. -- Check that wind is blowing from a direction > 5° different from the current heading.
local hdg=self:GetHeading() local hdg=self:GetHeading()
local wind=self:GetHeadingIntoWind() local wind=self:GetHeadingIntoWind()
local delta=self:_GetDeltaHeading(hdg, wind) local delta=self:_GetDeltaHeading(hdg, wind)
@ -3896,7 +3896,7 @@ function AIRBOSS:_CheckRecoveryTimes()
end end
--Debug info --Debug info
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))) 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. -- Time into the wind 1 day or if longer recovery time + the 5 min early.
local t=math.max(nextwindow.STOP-nextwindow.START+self.dTturn, 60*60*24) local t=math.max(nextwindow.STOP-nextwindow.START+self.dTturn, 60*60*24)
@ -6933,7 +6933,7 @@ function AIRBOSS:_AddMarshalGroup(flight, stack)
-- For case 1 we want the BRC but above routine return FB. -- For case 1 we want the BRC but above routine return FB.
radial=self:GetBRC() radial=self:GetBRC()
end end
local text=string.format("Select TACAN %03d°, channel %d%s (%s)", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) local text=string.format("Select TACAN %03d°, channel %d%s (%s)", radial, self.TACANchannel,self.TACANmode, self.TACANmorse)
self:MessageToPlayer(flight, text, nil, "") self:MessageToPlayer(flight, text, nil, "")
end end
@ -9346,7 +9346,7 @@ function AIRBOSS:_Initial(playerData)
-- Hook down for students. -- Hook down for students.
if playerData.difficulty==AIRBOSS.Difficulty.EASY and playerData.actype~=AIRBOSS.AircraftCarrier.AV8B then if playerData.difficulty==AIRBOSS.Difficulty.EASY and playerData.actype~=AIRBOSS.AircraftCarrier.AV8B then
if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then
hint=hint.." - Hook down, SAS on, Wing Sweep 68°!" hint=hint.." - Hook down, SAS on, Wing Sweep 68°!"
else else
hint=hint.." - Hook down!" hint=hint.." - Hook down!"
end end
@ -11331,15 +11331,15 @@ function AIRBOSS:_AttitudeMonitor(playerData)
-- Output -- Output
local text=string.format("Pattern step: %s", step) local text=string.format("Pattern step: %s", step)
text=text..string.format("\nAoA=%.1f° = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units(playerData, aoa), UTILS.MpsToKnots(vabs)) text=text..string.format("\nAoA=%.1f° = %.1f Units | |V|=%.1f knots", aoa, self:_AoADeg2Units(playerData, aoa), UTILS.MpsToKnots(vabs))
if self.Debug then if self.Debug then
-- Velocity vector. -- Velocity vector.
text=text..string.format("\nVx=%.1f Vy=%.1f Vz=%.1f m/s", velo.x, velo.y, velo.z) text=text..string.format("\nVx=%.1f Vy=%.1f Vz=%.1f m/s", velo.x, velo.y, velo.z)
--Wind vector. --Wind vector.
text=text..string.format("\nWind Vx=%.1f Vy=%.1f Vz=%.1f m/s", wind.x, wind.y, wind.z) text=text..string.format("\nWind Vx=%.1f Vy=%.1f Vz=%.1f m/s", wind.x, wind.y, wind.z)
end end
text=text..string.format("\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw) text=text..string.format("\nPitch=%.1f° | Roll=%.1f° | Yaw=%.1f°", pitch, roll, yaw)
text=text..string.format("\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y*196.85) text=text..string.format("\nClimb Angle=%.1f° | Rate=%d ft/min", unit:GetClimbAngle(), velo.y*196.85)
local dist=self:_GetOptLandingCoordinate():Get3DDistance(playerData.unit) local dist=self:_GetOptLandingCoordinate():Get3DDistance(playerData.unit)
-- Get player velocity in km/h. -- Get player velocity in km/h.
local vplayer=playerData.unit:GetVelocityKMH() local vplayer=playerData.unit:GetVelocityKMH()
@ -11360,14 +11360,14 @@ function AIRBOSS:_AttitudeMonitor(playerData)
playerData.step==AIRBOSS.PatternStep.GROOVE_IW then playerData.step==AIRBOSS.PatternStep.GROOVE_IW then
local lue=self:_Lineup(playerData.unit, true) local lue=self:_Lineup(playerData.unit, true)
local gle=self:_Glideslope(playerData.unit) local gle=self:_Glideslope(playerData.unit)
text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi)
text=text..string.format("\nLineUp=%.2f° | GlideSlope=%.2f° | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa)) text=text..string.format("\nLineUp=%.2f° | GlideSlope=%.2f° | AoA=%.1f Units", lue, gle, self:_AoADeg2Units(playerData, aoa))
local grade, points, analysis=self:_LSOgrade(playerData) local grade, points, analysis=self:_LSOgrade(playerData)
text=text..string.format("\nTgroove=%.1f sec", self:_GetTimeInGroove(playerData)) text=text..string.format("\nTgroove=%.1f sec", self:_GetTimeInGroove(playerData))
text=text..string.format("\nGrade: %s %.1f PT - %s", grade, points, analysis) text=text..string.format("\nGrade: %s %.1f PT - %s", grade, points, analysis)
else else
text=text..string.format("\nR=%.2f NM | X=%d Z=%d m", UTILS.MetersToNM(rho), dx, dz) text=text..string.format("\nR=%.2f NM | X=%d Z=%d m", UTILS.MetersToNM(rho), dx, dz)
text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi) text=text..string.format("\nGamma=%.1f° | Rho=%.1f°", relhead, phi)
end end
MESSAGE:New(text, 1, nil , true):ToClient(playerData.client) MESSAGE:New(text, 1, nil , true):ToClient(playerData.client)
@ -12695,7 +12695,7 @@ function AIRBOSS:_PlayerHint(playerData, delay, soundoff)
if self.holdingoffset<0 then if self.holdingoffset<0 then
turn="left" turn="left"
end end
hint=hint..string.format("\nTurn %s and select TACAN %03d°.", turn, radial) hint=hint..string.format("\nTurn %s and select TACAN %03d°.", turn, radial)
end end
end end
@ -12704,7 +12704,7 @@ function AIRBOSS:_PlayerHint(playerData, delay, soundoff)
if playerData.step==AIRBOSS.PatternStep.DIRTYUP then if playerData.step==AIRBOSS.PatternStep.DIRTYUP then
if playerData.difficulty==AIRBOSS.Difficulty.EASY then if playerData.difficulty==AIRBOSS.Difficulty.EASY then
if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
hint=hint.."\nFAF! Checks completed. Nozzles 50°." hint=hint.."\nFAF! Checks completed. Nozzles 50°."
else else
--TODO: Tomcat? --TODO: Tomcat?
hint=hint.."\nDirty up! Hook, gear and flaps down." hint=hint.."\nDirty up! Hook, gear and flaps down."
@ -12773,14 +12773,14 @@ function AIRBOSS:_StepHint(playerData, step)
-- Late break. -- Late break.
if step==AIRBOSS.PatternStep.LATEBREAK then if step==AIRBOSS.PatternStep.LATEBREAK then
if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then if playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then
hint=hint.."\nWing Sweep 20°, Gear DOWN < 280 KIAS." hint=hint.."\nWing Sweep 20°, Gear DOWN < 280 KIAS."
end end
end end
-- Abeam. -- Abeam.
if step==AIRBOSS.PatternStep.ABEAM then if step==AIRBOSS.PatternStep.ABEAM then
if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then if playerData.actype==AIRBOSS.AircraftCarrier.AV8B then
hint=hint.."\nNozzles 50°-60°. Antiskid OFF. Lights OFF." hint=hint.."\nNozzles 50°-60°. Antiskid OFF. Lights OFF."
elseif playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then elseif playerData.actype==AIRBOSS.AircraftCarrier.F14A or playerData.actype==AIRBOSS.AircraftCarrier.F14B then
hint=hint.."\nSlats/Flaps EXTENDED < 225 KIAS. DLC SELECTED. Auto Throttle IF DESIRED." hint=hint.."\nSlats/Flaps EXTENDED < 225 KIAS. DLC SELECTED. Auto Throttle IF DESIRED."
else else
@ -13215,7 +13215,7 @@ function AIRBOSS:_Debrief(playerData)
end end
-- Re-enter message. -- Re-enter message.
local text=string.format("fly heading %03d° for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM(distance)) local text=string.format("fly heading %03d° for %d NM to re-enter the pattern.", heading, UTILS.MetersToNM(distance))
self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 5) self:MessageToPlayer(playerData, text, "LSO", nil, nil, false, 5)
else else
@ -13411,9 +13411,9 @@ function AIRBOSS:_CheckCollisionCoord(coordto, coordfrom)
local text="" local text=""
if clear then if clear then
text=string.format("Path into direction %03d° is clear for the next %.1f NM.", direction, UTILS.MetersToNM(d)) text=string.format("Path into direction %03d° is clear for the next %.1f NM.", direction, UTILS.MetersToNM(d))
else else
text=string.format("Detected obstacle at distance %.1f NM into direction %03d°.", UTILS.MetersToNM(d), direction) text=string.format("Detected obstacle at distance %.1f NM into direction %03d°.", UTILS.MetersToNM(d), direction)
end end
self:T2(self.lid..text) self:T2(self.lid..text)
@ -13473,7 +13473,7 @@ function AIRBOSS:_Pathfinder()
local collision=self:_CheckFreePathToNextWP(fromcoord) local collision=self:_CheckFreePathToNextWP(fromcoord)
-- Debug info. -- Debug info.
self:T2(self.lid..string.format("Pathfinder d=%.1f m, direction=%03d°, collision=%s", distance, direction, tostring(collision))) self:T2(self.lid..string.format("Pathfinder d=%.1f m, direction=%03d°, collision=%s", distance, direction, tostring(collision)))
-- If path is clear, we start a little detour. -- If path is clear, we start a little detour.
if not collision then if not collision then
@ -13907,7 +13907,7 @@ function AIRBOSS:_CheckPatternUpdate()
-- Update if carrier moves by more than 2.5 NM. -- Update if carrier moves by more than 2.5 NM.
local Dupdate=UTILS.NMToMeters(2.5) local Dupdate=UTILS.NMToMeters(2.5)
-- Update if carrier turned by more than 5°. -- Update if carrier turned by more than 5°.
local Hupdate=5 local Hupdate=5
----------------------- -----------------------
@ -13941,7 +13941,7 @@ function AIRBOSS:_CheckPatternUpdate()
-- Check if orientation changed. -- Check if orientation changed.
local Hchange=false local Hchange=false
if math.abs(deltaHeading)>=Hupdate then if math.abs(deltaHeading)>=Hupdate then
self:T(self.lid..string.format("Carrier heading changed by %d°.", deltaHeading)) self:T(self.lid..string.format("Carrier heading changed by %d°.", deltaHeading))
Hchange=true Hchange=true
end end
@ -15642,7 +15642,7 @@ end
function AIRBOSS:_MarshalCallNewFinalBearing(FB) function AIRBOSS:_MarshalCallNewFinalBearing(FB)
-- Subtitle. -- Subtitle.
local text=string.format("new final bearing %03d°.", FB) local text=string.format("new final bearing %03d°.", FB)
-- Debug message. -- Debug message.
self:I(self.lid..text) self:I(self.lid..text)
@ -15665,7 +15665,7 @@ end
function AIRBOSS:_MarshalCallCarrierTurnTo(hdg) function AIRBOSS:_MarshalCallCarrierTurnTo(hdg)
-- Subtitle. -- Subtitle.
local text=string.format("carrier is now starting turn to heading %03d°.", hdg) local text=string.format("carrier is now starting turn to heading %03d°.", hdg)
-- Debug message. -- Debug message.
self:I(self.lid..text) self:I(self.lid..text)
@ -15718,11 +15718,11 @@ function AIRBOSS:_MarshalCallRecoveryStart(case)
-- Debug output. -- Debug output.
local text=string.format("Starting aircraft recovery Case %d ops.", case) local text=string.format("Starting aircraft recovery Case %d ops.", case)
if case==1 then if case==1 then
text=text..string.format(" BRC %03d°.", self:GetBRC()) text=text..string.format(" BRC %03d°.", self:GetBRC())
elseif case==2 then elseif case==2 then
text=text..string.format(" Marshal radial %03d°. BRC %03d°.", radial, self:GetBRC()) text=text..string.format(" Marshal radial %03d°. BRC %03d°.", radial, self:GetBRC())
elseif case==3 then elseif case==3 then
text=text..string.format(" Marshal radial %03d°. Final heading %03d°.", radial, self:GetFinalBearing(false)) text=text..string.format(" Marshal radial %03d°. Final heading %03d°.", radial, self:GetFinalBearing(false))
end end
self:T(self.lid..text) self:T(self.lid..text)
@ -15767,7 +15767,7 @@ function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe)
local CT=UTILS.Split(clock[1], ":") local CT=UTILS.Split(clock[1], ":")
-- Subtitle text. -- Subtitle text.
local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe) local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe)
-- Debug message. -- Debug message.
self:I(self.lid..text) self:I(self.lid..text)
@ -15944,11 +15944,11 @@ function AIRBOSS:_AddF10Commands(_unitName)
missionCommands.addCommandForGroup(gid, "60 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 60) missionCommands.addCommandForGroup(gid, "60 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 60)
missionCommands.addCommandForGroup(gid, "90 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 90) missionCommands.addCommandForGroup(gid, "90 min", _menusetrtime, self._SkipperRecoveryTime, self, _unitName, 90)
local _menusetrtime=missionCommands.addSubMenuForGroup(gid, "Set Marshal Radial", _skipperPath) local _menusetrtime=missionCommands.addSubMenuForGroup(gid, "Set Marshal Radial", _skipperPath)
missionCommands.addCommandForGroup(gid, "+30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30) missionCommands.addCommandForGroup(gid, "+30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 30)
missionCommands.addCommandForGroup(gid, "+15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15) missionCommands.addCommandForGroup(gid, "+15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 15)
missionCommands.addCommandForGroup(gid, "", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0) missionCommands.addCommandForGroup(gid, "", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0)
missionCommands.addCommandForGroup(gid, "-15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15) missionCommands.addCommandForGroup(gid, "-15°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -15)
missionCommands.addCommandForGroup(gid, "-30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30) missionCommands.addCommandForGroup(gid, "-30°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, -30)
missionCommands.addCommandForGroup(gid, "U-turn On/Off", _skipperPath, self._SkipperRecoveryUturn, self, _unitName) missionCommands.addCommandForGroup(gid, "U-turn On/Off", _skipperPath, self._SkipperRecoveryUturn, self, _unitName)
missionCommands.addCommandForGroup(gid, "Start CASE I", _skipperPath, self._SkipperStartRecovery, self, _unitName, 1) missionCommands.addCommandForGroup(gid, "Start CASE I", _skipperPath, self._SkipperStartRecovery, self, _unitName, 1)
missionCommands.addCommandForGroup(gid, "Start CASE II", _skipperPath, self._SkipperStartRecovery, self, _unitName, 2) missionCommands.addCommandForGroup(gid, "Start CASE II", _skipperPath, self._SkipperStartRecovery, self, _unitName, 2)
@ -16005,7 +16005,7 @@ function AIRBOSS:_SkipperStartRecovery(_unitName, case)
-- Inform player. -- Inform player.
local text=string.format("affirm, Case %d recovery will start in 5 min for %d min. Wind on deck %d knots. U-turn=%s.", case, self.skipperTime, self.skipperSpeed, tostring(self.skipperUturn)) local text=string.format("affirm, Case %d recovery will start in 5 min for %d min. Wind on deck %d knots. U-turn=%s.", case, self.skipperTime, self.skipperSpeed, tostring(self.skipperUturn))
if case>1 then if case>1 then
text=text..string.format(" Marshal radial %d°.", self.skipperOffset) text=text..string.format(" Marshal radial %d°.", self.skipperOffset)
end end
if self:IsRecovering() then if self:IsRecovering() then
text="negative, carrier is already recovering." text="negative, carrier is already recovering."
@ -16071,7 +16071,7 @@ function AIRBOSS:_SkipperRecoveryOffset(_unitName, offset)
if playerData then if playerData then
-- Inform player. -- Inform player.
local text=string.format("roger, relative CASE II/III Marshal radial set to %d°.", offset) local text=string.format("roger, relative CASE II/III Marshal radial set to %d°.", offset)
self:MessageToPlayer(playerData, text, "AIRBOSS") self:MessageToPlayer(playerData, text, "AIRBOSS")
self.skipperOffset=offset self.skipperOffset=offset
@ -16534,7 +16534,7 @@ function AIRBOSS:_RequestCommence(_unitName)
-- For case 1 we want the BRC but above routine return FB. -- For case 1 we want the BRC but above routine return FB.
radial=self:GetBRC() radial=self:GetBRC()
end end
text=text..string.format("\nSelect TACAN %03d°, Channel %d%s (%s).\n", radial, self.TACANchannel,self.TACANmode, self.TACANmorse) text=text..string.format("\nSelect TACAN %03d°, Channel %d%s (%s).\n", radial, self.TACANchannel,self.TACANmode, self.TACANmorse)
end end
-- TODO: Inform section members. -- TODO: Inform section members.
@ -17146,7 +17146,7 @@ function AIRBOSS:_DisplayCarrierInfo(_unitname)
-- Only include current and future recovery windows. -- Only include current and future recovery windows.
if Tabs<recovery.STOP then if Tabs<recovery.STOP then
-- Output text. -- Output text.
recoverytext=recoverytext..string.format("\n* %s - %s: Case %d (%d°)", UTILS.SecondsToClock(recovery.START), UTILS.SecondsToClock(recovery.STOP), recovery.CASE, recovery.OFFSET) recoverytext=recoverytext..string.format("\n* %s - %s: Case %d (%d°)", UTILS.SecondsToClock(recovery.START), UTILS.SecondsToClock(recovery.STOP), recovery.CASE, recovery.OFFSET)
if recovery.WIND then if recovery.WIND then
recoverytext=recoverytext..string.format(" @ %.1f kts wind", recovery.SPEED) recoverytext=recoverytext..string.format(" @ %.1f kts wind", recovery.SPEED)
end end
@ -17187,9 +17187,9 @@ function AIRBOSS:_DisplayCarrierInfo(_unitname)
text=text..string.format("Case %d recovery ops\n", self.case) text=text..string.format("Case %d recovery ops\n", self.case)
else else
local radial=self:GetRadial(self.case, true, true, false) local radial=self:GetRadial(self.case, true, true, false)
text=text..string.format("Case %d recovery ops\nMarshal radial %03d°\n", self.case, radial) text=text..string.format("Case %d recovery ops\nMarshal radial %03d°\n", self.case, radial)
end end
text=text..string.format("BRC %03d° - FB %03d°\n", self:GetBRC(), self:GetFinalBearing(true)) text=text..string.format("BRC %03d° - FB %03d°\n", self:GetBRC(), self:GetFinalBearing(true))
text=text..string.format("Speed %.1f kts - Wind on deck %.1f kts\n", carrierspeed, wind) text=text..string.format("Speed %.1f kts - Wind on deck %.1f kts\n", carrierspeed, wind)
text=text..string.format("Tower frequency %.3f MHz\n", self.TowerFreq) text=text..string.format("Tower frequency %.3f MHz\n", self.TowerFreq)
text=text..string.format("Marshal radio %.3f MHz\n", self.MarshalFreq) text=text..string.format("Marshal radio %.3f MHz\n", self.MarshalFreq)
@ -17250,10 +17250,10 @@ function AIRBOSS:_DisplayCarrierWeather(_unitname)
local WodPA=UTILS.MpsToKnots(WodPA) local WodPA=UTILS.MpsToKnots(WodPA)
local WodPP=UTILS.MpsToKnots(WodPP) local WodPP=UTILS.MpsToKnots(WodPP)
local WD=string.format('%03d°', Wd) local WD=string.format('%03d°', Wd)
local Ts=string.format("%d°C",T) local Ts=string.format("%d°C",T)
local tT=string.format("%d°C",T) local tT=string.format("%d°C",T)
local tW=string.format("%.1f knots", UTILS.MpsToKnots(Ws)) local tW=string.format("%.1f knots", UTILS.MpsToKnots(Ws))
local tP=string.format("%.2f inHg", UTILS.hPa2inHg(P)) local tP=string.format("%.2f inHg", UTILS.hPa2inHg(P))
@ -17504,7 +17504,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName)
if playerData.step==AIRBOSS.PatternStep.HOLDING and playerData.case>1 then if playerData.step==AIRBOSS.PatternStep.HOLDING and playerData.case>1 then
-- Get inverse magnetic radial potential offset. -- Get inverse magnetic radial potential offset.
local radial=self:GetRadial(playerData.case, true, true, true) local radial=self:GetRadial(playerData.case, true, true, true)
stacktext=stacktext..string.format("Select TACAN %03d°, %d DME\n", radial, angels+15) stacktext=stacktext..string.format("Select TACAN %03d°, %d DME\n", radial, angels+15)
end end
end end
@ -17545,7 +17545,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName)
local brc=self:GetBRC() local brc=self:GetBRC()
-- Help player to find its way to the initial zone. -- Help player to find its way to the initial zone.
text=text..string.format("\nTo Initial: Fly heading %03d° for %.1f NM and turn to BRC %03d°", flyhdg, flydist, brc) text=text..string.format("\nTo Initial: Fly heading %03d° for %.1f NM and turn to BRC %03d°", flyhdg, flydist, brc)
elseif playerData.step==AIRBOSS.PatternStep.PLATFORM then elseif playerData.step==AIRBOSS.PatternStep.PLATFORM then
@ -17560,7 +17560,7 @@ function AIRBOSS:_DisplayPlayerStatus(_unitName)
local hdg=self:GetRadial(playerData.case, true, true, true) local hdg=self:GetRadial(playerData.case, true, true, true)
-- Help player to find its way to the initial zone. -- Help player to find its way to the initial zone.
text=text..string.format("\nTo Platform: Fly heading %03d° for %.1f NM and turn to %03d°", flyhdg, flydist, hdg) text=text..string.format("\nTo Platform: Fly heading %03d° for %.1f NM and turn to %03d°", flyhdg, flydist, hdg)
end end

View File

@ -22,7 +22,7 @@
-- @module Ops.CSAR -- @module Ops.CSAR
-- @image OPS_CSAR.jpg -- @image OPS_CSAR.jpg
-- Date: July 2021 -- Date: Aug 2021
------------------------------------------------------------------------- -------------------------------------------------------------------------
--- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM
@ -233,7 +233,7 @@ CSAR.AircraftType["Mi-24V"] = 8
--- CSAR class version. --- CSAR class version.
-- @field #string version -- @field #string version
CSAR.version="0.1.10r2" CSAR.version="0.1.10r3"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
@ -1337,7 +1337,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname, isairport)
end end
--queue up --queue up
self:__Returning(-5,heliname,_woundedGroupName) self:__Returning(-5,heliname,_woundedGroupName, isairport)
return self return self
end end
@ -2058,9 +2058,10 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param #string Heliname Name of the helicopter group. -- @param #string Heliname Name of the helicopter group.
-- @param #string Woundedgroupname Name of the downed pilot\'s group. -- @param #string Woundedgroupname Name of the downed pilot\'s group.
function CSAR:onbeforeReturning(From, Event, To, Heliname, Woundedgroupname) -- @param #boolean IsAirport True if heli has landed on an AFB (from event land).
function CSAR:onbeforeReturning(From, Event, To, Heliname, Woundedgroupname, IsAirPort)
self:T({From, Event, To, Heliname, Woundedgroupname}) self:T({From, Event, To, Heliname, Woundedgroupname})
self:_ScheduledSARFlight(Heliname,Woundedgroupname) self:_ScheduledSARFlight(Heliname,Woundedgroupname, IsAirPort)
return self return self
end end