mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
14 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6cc3d73c04 | ||
|
|
e541e39403 | ||
|
|
c7ea45e5fd | ||
|
|
20f28b3d2c | ||
|
|
f3f63ab8aa | ||
|
|
e91090cfff | ||
|
|
1a7fb3c13e | ||
|
|
59857ed79d | ||
|
|
4797665939 | ||
|
|
b89749036d | ||
|
|
c6268488de | ||
|
|
de04369703 | ||
|
|
05b6f19a87 | ||
|
|
2753df8216 |
@@ -47,19 +47,21 @@ function AI_CARGO:New( Carrier, CargoSet )
|
|||||||
|
|
||||||
self:SetStartState( "Unloaded" )
|
self:SetStartState( "Unloaded" )
|
||||||
|
|
||||||
self:AddTransition( "Unloaded", "Pickup", "*" )
|
-- Board
|
||||||
self:AddTransition( "Loaded", "Deploy", "*" )
|
self:AddTransition( "Unloaded", "Pickup", "Unloaded" )
|
||||||
|
self:AddTransition( "*", "Load", "*" )
|
||||||
|
self:AddTransition( "*", "Reload", "*" )
|
||||||
|
self:AddTransition( "*", "Board", "*" )
|
||||||
|
self:AddTransition( "*", "Loaded", "Loaded" )
|
||||||
|
self:AddTransition( "Loaded", "PickedUp", "Loaded" )
|
||||||
|
|
||||||
self:AddTransition( "*", "Load", "Boarding" )
|
-- Unload
|
||||||
self:AddTransition( "Boarding", "Board", "Boarding" )
|
self:AddTransition( "Loaded", "Deploy", "*" )
|
||||||
self:AddTransition( "Loaded", "Board", "Loaded" )
|
self:AddTransition( "*", "Unload", "*" )
|
||||||
self:AddTransition( "Boarding", "Loaded", "Boarding" )
|
self:AddTransition( "*", "Unboard", "*" )
|
||||||
self:AddTransition( "Boarding", "PickedUp", "Loaded" )
|
self:AddTransition( "*", "Unloaded", "Unloaded" )
|
||||||
|
self:AddTransition( "Unloaded", "Deployed", "Unloaded" )
|
||||||
self:AddTransition( "Loaded", "Unload", "Unboarding" )
|
|
||||||
self:AddTransition( "Unboarding", "Unboard", "Unboarding" )
|
|
||||||
self:AddTransition( "Unboarding", "Unloaded", "Unboarding" )
|
|
||||||
self:AddTransition( "Unboarding", "Deployed", "Unloaded" )
|
|
||||||
|
|
||||||
--- Pickup Handler OnBefore for AI_CARGO
|
--- Pickup Handler OnBefore for AI_CARGO
|
||||||
-- @function [parent=#AI_CARGO] OnBeforePickup
|
-- @function [parent=#AI_CARGO] OnBeforePickup
|
||||||
@@ -393,7 +395,7 @@ end
|
|||||||
function AI_CARGO:onafterBoard( Carrier, From, Event, To, Cargo, CarrierUnit, PickupZone )
|
function AI_CARGO:onafterBoard( Carrier, From, Event, To, Cargo, CarrierUnit, PickupZone )
|
||||||
self:F( { Carrier, From, Event, To, Cargo, CarrierUnit:GetName() } )
|
self:F( { Carrier, From, Event, To, Cargo, CarrierUnit:GetName() } )
|
||||||
|
|
||||||
if Carrier and Carrier:IsAlive() and From == "Boarding" then
|
if Carrier and Carrier:IsAlive() then
|
||||||
self:F({ IsLoaded = Cargo:IsLoaded(), Cargo:GetName(), Carrier:GetName() } )
|
self:F({ IsLoaded = Cargo:IsLoaded(), Cargo:GetName(), Carrier:GetName() } )
|
||||||
if not Cargo:IsLoaded() and not Cargo:IsDestroyed() then
|
if not Cargo:IsLoaded() and not Cargo:IsDestroyed() then
|
||||||
self:__Board( -10, Cargo, CarrierUnit, PickupZone )
|
self:__Board( -10, Cargo, CarrierUnit, PickupZone )
|
||||||
@@ -509,7 +511,7 @@ end
|
|||||||
function AI_CARGO:onafterUnboard( Carrier, From, Event, To, Cargo, CarrierUnit, DeployZone, Defend )
|
function AI_CARGO:onafterUnboard( Carrier, From, Event, To, Cargo, CarrierUnit, DeployZone, Defend )
|
||||||
self:F( { Carrier, From, Event, To, Cargo:GetName(), DeployZone = DeployZone, Defend = Defend } )
|
self:F( { Carrier, From, Event, To, Cargo:GetName(), DeployZone = DeployZone, Defend = Defend } )
|
||||||
|
|
||||||
if Carrier and Carrier:IsAlive() and From == "Unboarding" then
|
if Carrier and Carrier:IsAlive() then
|
||||||
if not Cargo:IsUnLoaded() then
|
if not Cargo:IsUnLoaded() then
|
||||||
self:__Unboard( 10, Cargo, CarrierUnit, DeployZone, Defend )
|
self:__Unboard( 10, Cargo, CarrierUnit, DeployZone, Defend )
|
||||||
return
|
return
|
||||||
@@ -580,4 +582,3 @@ function AI_CARGO:onafterDeployed( Carrier, From, Event, To, DeployZone, Defend
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,8 @@ function AI_CARGO_APC:New( APC, CargoSet, CombatRadius )
|
|||||||
self:AddTransition( "*", "Guard", "Unloaded" )
|
self:AddTransition( "*", "Guard", "Unloaded" )
|
||||||
self:AddTransition( "*", "Home", "*" )
|
self:AddTransition( "*", "Home", "*" )
|
||||||
self:AddTransition( "*", "Reload", "Boarding" )
|
self:AddTransition( "*", "Reload", "Boarding" )
|
||||||
|
self:AddTransition( "*", "Deployed", "*" )
|
||||||
|
self:AddTransition( "*", "PickedUp", "*" )
|
||||||
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
||||||
|
|
||||||
self:SetCombatRadius( CombatRadius )
|
self:SetCombatRadius( CombatRadius )
|
||||||
|
|||||||
@@ -64,20 +64,24 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
|
|||||||
self.Zone = ZONE_GROUP:New( Helicopter:GetName(), Helicopter, 300 )
|
self.Zone = ZONE_GROUP:New( Helicopter:GetName(), Helicopter, 300 )
|
||||||
|
|
||||||
self:SetStartState( "Unloaded" )
|
self:SetStartState( "Unloaded" )
|
||||||
|
-- Boarding
|
||||||
|
self:AddTransition( "Unloaded", "Pickup", "Unloaded" )
|
||||||
|
self:AddTransition( "*", "Landed", "*" )
|
||||||
|
self:AddTransition( "*", "Load", "*" )
|
||||||
|
self:AddTransition( "*", "Loaded", "Loaded" )
|
||||||
|
self:AddTransition( "Loaded", "PickedUp", "Loaded" )
|
||||||
|
|
||||||
self:AddTransition( "Unloaded", "Pickup", "*" )
|
-- Unboarding
|
||||||
self:AddTransition( "Loaded", "Deploy", "*" )
|
self:AddTransition( "Loaded", "Deploy", "*" )
|
||||||
self:AddTransition( "*", "Loaded", "Loaded" )
|
self:AddTransition( "*", "Queue", "*" )
|
||||||
self:AddTransition( "Unboarding", "Pickup", "Unloaded" )
|
self:AddTransition( "*", "Orbit" , "*" )
|
||||||
self:AddTransition( "Unloaded", "Unboard", "Unloaded" )
|
self:AddTransition( "*", "Destroyed", "*" )
|
||||||
self:AddTransition( "Unloaded", "Unloaded", "Unloaded" )
|
self:AddTransition( "*", "Unload", "*" )
|
||||||
self:AddTransition( "*", "PickedUp", "*" )
|
self:AddTransition( "*", "Unloaded", "Unloaded" )
|
||||||
self:AddTransition( "*", "Landed", "*" )
|
self:AddTransition( "Unloaded", "Deployed", "Unloaded" )
|
||||||
self:AddTransition( "*", "Queue", "*" )
|
|
||||||
self:AddTransition( "*", "Orbit" , "*" )
|
-- RTB
|
||||||
self:AddTransition( "*", "Home" , "*" )
|
self:AddTransition( "*", "Home" , "*" )
|
||||||
|
|
||||||
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
|
||||||
|
|
||||||
--- Pickup Handler OnBefore for AI_CARGO_HELICOPTER
|
--- Pickup Handler OnBefore for AI_CARGO_HELICOPTER
|
||||||
-- @function [parent=#AI_CARGO_HELICOPTER] OnBeforePickup
|
-- @function [parent=#AI_CARGO_HELICOPTER] OnBeforePickup
|
||||||
@@ -207,6 +211,9 @@ function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
|
|||||||
|
|
||||||
self:SetCarrier( Helicopter )
|
self:SetCarrier( Helicopter )
|
||||||
|
|
||||||
|
self.landingspeed = 15 -- kph
|
||||||
|
self.landingheight = 5.5 -- meter
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -255,6 +262,25 @@ function AI_CARGO_HELICOPTER:SetCarrier( Helicopter )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set landingspeed and -height for helicopter landings. Adjust after tracing if your helis get stuck after landing.
|
||||||
|
-- @param #AI_CARGO_HELICOPTER self
|
||||||
|
-- @param #number speed Landing speed in kph(!), e.g. 15
|
||||||
|
-- @param #number height Landing height in meters(!), e.g. 5.5
|
||||||
|
-- @return #AI_CARGO_HELICOPTER self
|
||||||
|
-- @usage If your choppers get stuck, add tracing to your script to determine if they hit the right parameters like so:
|
||||||
|
--
|
||||||
|
-- BASE:TraceOn()
|
||||||
|
-- BASE:TraceClass("AI_CARGO_HELICOPTER")
|
||||||
|
--
|
||||||
|
-- Watch the DCS.log for entries stating `Helicopter:<name>, Height = Helicopter:<number>, Velocity = Helicopter:<number>`
|
||||||
|
-- Adjust if necessary.
|
||||||
|
function AI_CARGO_HELICOPTER:SetLandingSpeedAndHeight(speed, height)
|
||||||
|
local _speed = speed or 15
|
||||||
|
local _height = height or 5.5
|
||||||
|
self.landingheight = _height
|
||||||
|
self.landingspeed = _speed
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- @param #AI_CARGO_HELICOPTER self
|
--- @param #AI_CARGO_HELICOPTER self
|
||||||
-- @param Wrapper.Group#GROUP Helicopter
|
-- @param Wrapper.Group#GROUP Helicopter
|
||||||
@@ -271,13 +297,13 @@ function AI_CARGO_HELICOPTER:onafterLanded( Helicopter, From, Event, To )
|
|||||||
-- 1 - When the helo lands normally on the ground.
|
-- 1 - When the helo lands normally on the ground.
|
||||||
-- 2 - when the helo is hit and goes RTB or even when it is destroyed.
|
-- 2 - when the helo is hit and goes RTB or even when it is destroyed.
|
||||||
-- For point 2, this is an issue, the infantry may not unload in this case!
|
-- For point 2, this is an issue, the infantry may not unload in this case!
|
||||||
-- So we check if the helo is on the ground, and velocity< 5.
|
-- So we check if the helo is on the ground, and velocity< 15.
|
||||||
-- Only then the infantry can unload (and load too, for consistency)!
|
-- Only then the infantry can unload (and load too, for consistency)!
|
||||||
|
|
||||||
self:F( { Helicopter:GetName(), Height = Helicopter:GetHeight( true ), Velocity = Helicopter:GetVelocityKMH() } )
|
self:T( { Helicopter:GetName(), Height = Helicopter:GetHeight( true ), Velocity = Helicopter:GetVelocityKMH() } )
|
||||||
|
|
||||||
if self.RoutePickup == true then
|
if self.RoutePickup == true then
|
||||||
if Helicopter:GetHeight( true ) <= 5.5 and Helicopter:GetVelocityKMH() < 15 then
|
if Helicopter:GetHeight( true ) <= self.landingheight then --and Helicopter:GetVelocityKMH() < self.landingspeed then
|
||||||
--self:Load( Helicopter:GetPointVec2() )
|
--self:Load( Helicopter:GetPointVec2() )
|
||||||
self:Load( self.PickupZone )
|
self:Load( self.PickupZone )
|
||||||
self.RoutePickup = false
|
self.RoutePickup = false
|
||||||
@@ -285,7 +311,7 @@ function AI_CARGO_HELICOPTER:onafterLanded( Helicopter, From, Event, To )
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.RouteDeploy == true then
|
if self.RouteDeploy == true then
|
||||||
if Helicopter:GetHeight( true ) <= 5.5 and Helicopter:GetVelocityKMH() < 15 then
|
if Helicopter:GetHeight( true ) <= self.landingheight then --and Helicopter:GetVelocityKMH() < self.landingspeed then
|
||||||
self:Unload( self.DeployZone )
|
self:Unload( self.DeployZone )
|
||||||
self.RouteDeploy = false
|
self.RouteDeploy = false
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1707,8 +1707,8 @@ end
|
|||||||
--- Returns the unit of a player and the player name. If the unit does not belong to a player, nil is returned.
|
--- Returns the unit of a player and the player name. If the unit does not belong to a player, nil is returned.
|
||||||
-- @param #FOX self
|
-- @param #FOX self
|
||||||
-- @param DCS#Weapon weapon The weapon.
|
-- @param DCS#Weapon weapon The weapon.
|
||||||
-- @return #number Notching heading right, i.e. missile heading +90<EFBFBD>
|
-- @return #number Notching heading right, i.e. missile heading +90°.
|
||||||
-- @return #number Notching heading left, i.e. missile heading -90<EFBFBD>.
|
-- @return #number Notching heading left, i.e. missile heading -90°.
|
||||||
function FOX:_GetNotchingHeadings(weapon)
|
function FOX:_GetNotchingHeadings(weapon)
|
||||||
|
|
||||||
if weapon then
|
if weapon then
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
-- ## Features:
|
-- ## Features:
|
||||||
--
|
--
|
||||||
-- * Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes.
|
-- * Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes.
|
||||||
-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range <EFBFBD>
|
-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range °
|
||||||
-- * Provide alerts when a missile would have killed your aircraft.
|
-- * Provide alerts when a missile would have killed your aircraft.
|
||||||
-- * Provide alerts when the missile self destructs.
|
-- * Provide alerts when the missile self destructs.
|
||||||
-- * Enable / Disable and Configure the Missile Trainer using the various menu options.
|
-- * Enable / Disable and Configure the Missile Trainer using the various menu options.
|
||||||
|
|||||||
@@ -5371,7 +5371,7 @@ function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, take
|
|||||||
|
|
||||||
if spawnonground then
|
if spawnonground then
|
||||||
|
|
||||||
-- Sh<EFBFBD>ps and FARPS seem to have a build in queue.
|
-- Sh°ps and FARPS seem to have a build in queue.
|
||||||
if spawnonship or spawnonfarp or spawnonrunway or automatic then
|
if spawnonship or spawnonfarp or spawnonrunway or automatic then
|
||||||
self:T(RAT.id..string.format("RAT group %s spawning at farp, ship or runway %s.", self.alias, departure:GetName()))
|
self:T(RAT.id..string.format("RAT group %s spawning at farp, ship or runway %s.", self.alias, departure:GetName()))
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ## Missions: Example missions will be added later.
|
-- ## Missions:
|
||||||
|
--
|
||||||
|
-- * [MAR - On the Range - MOOSE - SC](https://www.digitalcombatsimulator.com/en/files/3317765/) by shagrat
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -2558,7 +2560,7 @@ function RANGE:_DisplayBombTargets(_unitname)
|
|||||||
-- Get elevation
|
-- Get elevation
|
||||||
local elevation=coord:GetLandHeight()
|
local elevation=coord:GetLandHeight()
|
||||||
local eltxt=string.format("%d m", elevation)
|
local eltxt=string.format("%d m", elevation)
|
||||||
if _settings:IsImperial() then
|
if not _settings:IsMetric() then
|
||||||
elevation=UTILS.MetersToFeet(elevation)
|
elevation=UTILS.MetersToFeet(elevation)
|
||||||
eltxt=string.format("%d ft", elevation)
|
eltxt=string.format("%d ft", elevation)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ function SEAD:New( SEADGroupPrefixes )
|
|||||||
end
|
end
|
||||||
|
|
||||||
self:HandleEvent( EVENTS.Shot, self.HandleEventShot )
|
self:HandleEvent( EVENTS.Shot, self.HandleEventShot )
|
||||||
self:I("*** SEAD - Started Version 0.2.8")
|
self:I("*** SEAD - Started Version 0.2.9")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ end
|
|||||||
-- @return #SEAD self
|
-- @return #SEAD self
|
||||||
function SEAD:UpdateSet( SEADGroupPrefixes )
|
function SEAD:UpdateSet( SEADGroupPrefixes )
|
||||||
|
|
||||||
self:F( SEADGroupPrefixes )
|
self:T( SEADGroupPrefixes )
|
||||||
|
|
||||||
if type( SEADGroupPrefixes ) == 'table' then
|
if type( SEADGroupPrefixes ) == 'table' then
|
||||||
for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do
|
for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do
|
||||||
@@ -120,7 +120,7 @@ end
|
|||||||
-- @param #number range Set the engagement range in percent, e.g. 50
|
-- @param #number range Set the engagement range in percent, e.g. 50
|
||||||
-- @return self
|
-- @return self
|
||||||
function SEAD:SetEngagementRange(range)
|
function SEAD:SetEngagementRange(range)
|
||||||
self:F( { range } )
|
self:T( { range } )
|
||||||
range = range or 75
|
range = range or 75
|
||||||
if range < 0 or range > 100 then
|
if range < 0 or range > 100 then
|
||||||
range = 75
|
range = 75
|
||||||
@@ -135,7 +135,7 @@ end
|
|||||||
-- @param #string WeaponName
|
-- @param #string WeaponName
|
||||||
-- @return #boolean Returns true for a match
|
-- @return #boolean Returns true for a match
|
||||||
function SEAD:_CheckHarms(WeaponName)
|
function SEAD:_CheckHarms(WeaponName)
|
||||||
self:F( { WeaponName } )
|
self:T( { WeaponName } )
|
||||||
local hit = false
|
local hit = false
|
||||||
for _,_name in pairs (SEAD.Harms) do
|
for _,_name in pairs (SEAD.Harms) do
|
||||||
if string.find(WeaponName,_name,1) then hit = true end
|
if string.find(WeaponName,_name,1) then hit = true end
|
||||||
@@ -166,7 +166,7 @@ function SEAD:HandleEventShot( EventData )
|
|||||||
local _targetUnit = UNIT:Find(_targetMim) -- Unit name by DCS Object
|
local _targetUnit = UNIT:Find(_targetMim) -- Unit name by DCS Object
|
||||||
if _targetUnit and _targetUnit:IsAlive() then
|
if _targetUnit and _targetUnit:IsAlive() then
|
||||||
local _targetMimgroup = _targetUnit:GetGroup()
|
local _targetMimgroup = _targetUnit:GetGroup()
|
||||||
local _targetMimgroupName = _targetMimgroup:GetName() -- group name
|
_targetMimgroupName = _targetMimgroup:GetName() -- group name
|
||||||
--local _targetskill = _DATABASE.Templates.Units[_targetUnit].Template.skill
|
--local _targetskill = _DATABASE.Templates.Units[_targetUnit].Template.skill
|
||||||
self:T( self.SEADGroupPrefixes )
|
self:T( self.SEADGroupPrefixes )
|
||||||
self:T( _targetMimgroupName )
|
self:T( _targetMimgroupName )
|
||||||
@@ -174,6 +174,7 @@ function SEAD:HandleEventShot( EventData )
|
|||||||
-- see if we are shot at
|
-- see if we are shot at
|
||||||
local SEADGroupFound = false
|
local SEADGroupFound = false
|
||||||
for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do
|
for SEADGroupPrefixID, SEADGroupPrefix in pairs( self.SEADGroupPrefixes ) do
|
||||||
|
self:T( SEADGroupPrefix )
|
||||||
if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then
|
if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then
|
||||||
SEADGroupFound = true
|
SEADGroupFound = true
|
||||||
self:T( '*** SEAD - Group Found' )
|
self:T( '*** SEAD - Group Found' )
|
||||||
|
|||||||
@@ -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, "0°", _menusetrtime, self._SkipperRecoveryOffset, self, _unitName, 0)
|
missionCommands.addCommandForGroup(gid, "0°", _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
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
--- **Ops** -- Combat Search and Rescue.
|
--- **Ops** -- Combat Search and Rescue.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
@@ -23,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
|
||||||
@@ -70,6 +69,7 @@
|
|||||||
--
|
--
|
||||||
-- self.allowDownedPilotCAcontrol = false -- Set to false if you don\'t want to allow control by Combined Arms.
|
-- self.allowDownedPilotCAcontrol = false -- Set to false if you don\'t want to allow control by Combined Arms.
|
||||||
-- self.allowFARPRescue = true -- allows pilots to be rescued by landing at a FARP or Airbase. Else MASH only!
|
-- self.allowFARPRescue = true -- allows pilots to be rescued by landing at a FARP or Airbase. Else MASH only!
|
||||||
|
-- self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued.
|
||||||
-- self.autosmoke = false -- automatically smoke a downed pilot\'s location when a heli is near.
|
-- self.autosmoke = false -- automatically smoke a downed pilot\'s location when a heli is near.
|
||||||
-- self.autosmokedistance = 1000 -- distance for autosmoke
|
-- self.autosmokedistance = 1000 -- distance for autosmoke
|
||||||
-- self.coordtype = 1 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates.
|
-- self.coordtype = 1 -- Use Lat/Long DDM (0), Lat/Long DMS (1), MGRS (2), Bullseye imperial (3) or Bullseye metric (4) for coordinates.
|
||||||
@@ -95,6 +95,8 @@
|
|||||||
-- self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
|
-- self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
|
||||||
-- self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
|
-- self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
|
||||||
-- self.pilotmustopendoors = false -- switch to true to enable check of open doors
|
-- self.pilotmustopendoors = false -- switch to true to enable check of open doors
|
||||||
|
-- -- (added 0.1.9)
|
||||||
|
-- self.suppressmessages = false -- switch off all messaging if you want to do your own
|
||||||
--
|
--
|
||||||
-- ## 2.1 Experimental Features
|
-- ## 2.1 Experimental Features
|
||||||
--
|
--
|
||||||
@@ -214,26 +216,6 @@ CSAR = {
|
|||||||
-- @field Wrapper.Group#GROUP group Spawned group object.
|
-- @field Wrapper.Group#GROUP group Spawned group object.
|
||||||
-- @field #number timestamp Timestamp for approach process
|
-- @field #number timestamp Timestamp for approach process
|
||||||
-- @field #boolean alive Group is alive or dead/rescued
|
-- @field #boolean alive Group is alive or dead/rescued
|
||||||
--
|
|
||||||
--- Updated and sorted list of known NDB beacons (in kHz!) from the available maps.
|
|
||||||
|
|
||||||
--[[ Moved to Utils
|
|
||||||
-- @field #CSAR.SkipFrequencies
|
|
||||||
CSAR.SkipFrequencies = {
|
|
||||||
214,274,291.5,295,297.5,
|
|
||||||
300.5,304,307,309.5,311,312,312.5,316,
|
|
||||||
320,324,328,329,330,336,337,
|
|
||||||
342,343,348,351,352,353,358,
|
|
||||||
363,365,368,372.5,374,
|
|
||||||
380,381,384,389,395,396,
|
|
||||||
414,420,430,432,435,440,450,455,462,470,485,
|
|
||||||
507,515,520,525,528,540,550,560,570,577,580,602,625,641,662,670,680,682,690,
|
|
||||||
705,720,722,730,735,740,745,750,770,795,
|
|
||||||
822,830,862,866,
|
|
||||||
905,907,920,935,942,950,995,
|
|
||||||
1000,1025,1030,1050,1065,1116,1175,1182,1210
|
|
||||||
}
|
|
||||||
--]]
|
|
||||||
|
|
||||||
--- All slot / Limit settings
|
--- All slot / Limit settings
|
||||||
-- @type CSAR.AircraftType
|
-- @type CSAR.AircraftType
|
||||||
@@ -251,7 +233,7 @@ CSAR.AircraftType["Mi-24V"] = 8
|
|||||||
|
|
||||||
--- CSAR class version.
|
--- CSAR class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CSAR.version="0.1.8r3"
|
CSAR.version="0.1.10r3"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- ToDo list
|
-- ToDo list
|
||||||
@@ -361,6 +343,7 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
self.loadtimemax = 135 -- seconds
|
self.loadtimemax = 135 -- seconds
|
||||||
self.radioSound = "beacon.ogg" -- the name of the sound file to use for the Pilot radio beacons. If this isnt added to the mission BEACONS WONT WORK!
|
self.radioSound = "beacon.ogg" -- the name of the sound file to use for the Pilot radio beacons. If this isnt added to the mission BEACONS WONT WORK!
|
||||||
self.allowFARPRescue = true --allows pilot to be rescued by landing at a FARP or Airbase
|
self.allowFARPRescue = true --allows pilot to be rescued by landing at a FARP or Airbase
|
||||||
|
self.FARPRescueDistance = 1000 -- you need to be this close to a FARP or Airport for the pilot to be rescued.
|
||||||
self.max_units = 6 --max number of pilots that can be carried
|
self.max_units = 6 --max number of pilots that can be carried
|
||||||
self.useprefix = true -- Use the Prefixed defined below, Requires Unit have the Prefix defined below
|
self.useprefix = true -- Use the Prefixed defined below, Requires Unit have the Prefix defined below
|
||||||
self.csarPrefix = { "helicargo", "MEDEVAC"} -- prefixes used for useprefix=true - DON\'T use # in names!
|
self.csarPrefix = { "helicargo", "MEDEVAC"} -- prefixes used for useprefix=true - DON\'T use # in names!
|
||||||
@@ -378,6 +361,7 @@ function CSAR:New(Coalition, Template, Alias)
|
|||||||
self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
|
self.approachdist_far = 5000 -- switch do 10 sec interval approach mode, meters
|
||||||
self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
|
self.approachdist_near = 3000 -- switch to 5 sec interval approach mode, meters
|
||||||
self.pilotmustopendoors = false -- switch to true to enable check on open doors
|
self.pilotmustopendoors = false -- switch to true to enable check on open doors
|
||||||
|
self.suppressmessages = false
|
||||||
|
|
||||||
-- WARNING - here\'ll be dragons
|
-- WARNING - here\'ll be dragons
|
||||||
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
|
-- for this to work you need to de-sanitize your mission environment in <DCS root>\Scripts\MissionScripting.lua
|
||||||
@@ -642,7 +626,7 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla
|
|||||||
local _typeName = _typeName or "Pilot"
|
local _typeName = _typeName or "Pilot"
|
||||||
|
|
||||||
if not noMessage then
|
if not noMessage then
|
||||||
self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _typeName .. " is down. ", self.coalition, 10)
|
self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _typeName .. " is down. ", self.coalition, self.messageTime)
|
||||||
end
|
end
|
||||||
|
|
||||||
if _freq then
|
if _freq then
|
||||||
@@ -806,8 +790,7 @@ function CSAR:_EventHandler(EventData)
|
|||||||
if self:_DoubleEjection(_unitname) then
|
if self:_DoubleEjection(_unitname) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _unit:GetTypeName() .. " shot down. No Chute!", self.coalition, 10)
|
self:_DisplayToAllSAR("MAYDAY MAYDAY! " .. _unit:GetTypeName() .. " shot down. No Chute!", self.coalition, self.messageTime)
|
||||||
--local m = MESSAGE:New("MAYDAY MAYDAY! " .. _unit:GetTypeName() .. " shot down. No Chute!",10,"Info"):ToCoalition(self.coalition)
|
|
||||||
else
|
else
|
||||||
self:T(self.lid .. " Pilot has not taken off, ignore")
|
self:T(self.lid .. " Pilot has not taken off, ignore")
|
||||||
end
|
end
|
||||||
@@ -894,11 +877,14 @@ function CSAR:_EventHandler(EventData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
if _place:GetCoalition() == self.coalition or _place:GetCoalition() == coalition.side.NEUTRAL then
|
||||||
|
self:_ScheduledSARFlight(_event.IniUnitName,_event.IniGroupName,true)
|
||||||
|
--[[
|
||||||
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_event.IniUnitName) then
|
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(_event.IniUnitName) then
|
||||||
self:_DisplayMessageToSAR(_unit, "Open the door to let me out!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_unit, "Open the door to let me out!", self.messageTime, true)
|
||||||
else
|
else
|
||||||
self:_RescuePilots(_unit)
|
self:_RescuePilots(_unit)
|
||||||
end
|
end
|
||||||
|
--]]
|
||||||
else
|
else
|
||||||
self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition()))
|
self:T(string.format("Airfield %d, Unit %d", _place:GetCoalition(), _unit:GetCoalition()))
|
||||||
end
|
end
|
||||||
@@ -1112,7 +1098,7 @@ function CSAR:_PickupUnit(_heliUnit, _pilotName, _woundedGroup, _woundedGroupNam
|
|||||||
player = grouptable.player,
|
player = grouptable.player,
|
||||||
}
|
}
|
||||||
|
|
||||||
_woundedGroup:Destroy()
|
_woundedGroup:Destroy(false)
|
||||||
self:_RemoveNameFromDownedPilots(_woundedGroupName,true)
|
self:_RemoveNameFromDownedPilots(_woundedGroupName,true)
|
||||||
|
|
||||||
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s I\'m in! Get to the MASH ASAP! ", _heliName, _pilotName), self.messageTime,true,true)
|
self:_DisplayMessageToSAR(_heliUnit, string.format("%s: %s I\'m in! Get to the MASH ASAP! ", _heliName, _pilotName), self.messageTime,true,true)
|
||||||
@@ -1143,6 +1129,8 @@ end
|
|||||||
-- @return #boolean outcome The outcome.
|
-- @return #boolean outcome The outcome.
|
||||||
function CSAR:_IsLoadingDoorOpen( unit_name )
|
function CSAR:_IsLoadingDoorOpen( unit_name )
|
||||||
self:T(self.lid .. " _IsLoadingDoorOpen")
|
self:T(self.lid .. " _IsLoadingDoorOpen")
|
||||||
|
|
||||||
|
--[[
|
||||||
local ret_val = false
|
local ret_val = false
|
||||||
local unit = Unit.getByName(unit_name)
|
local unit = Unit.getByName(unit_name)
|
||||||
if unit ~= nil then
|
if unit ~= nil then
|
||||||
@@ -1174,8 +1162,9 @@ function CSAR:_IsLoadingDoorOpen( unit_name )
|
|||||||
return ret_val
|
return ret_val
|
||||||
|
|
||||||
end -- nil
|
end -- nil
|
||||||
|
--]]
|
||||||
|
return UTILS.IsLoadingDoorOpen(unit_name)
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Function to check if heli is close to group.
|
--- (Internal) Function to check if heli is close to group.
|
||||||
@@ -1314,7 +1303,8 @@ end
|
|||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
-- @param #string heliname Heli name
|
-- @param #string heliname Heli name
|
||||||
-- @param #string groupname Group name
|
-- @param #string groupname Group name
|
||||||
function CSAR:_ScheduledSARFlight(heliname,groupname)
|
-- @param #boolean isairport If true, EVENT.Landing took place at an airport or FARP
|
||||||
|
function CSAR:_ScheduledSARFlight(heliname,groupname, isairport)
|
||||||
self:T(self.lid .. " _ScheduledSARFlight")
|
self:T(self.lid .. " _ScheduledSARFlight")
|
||||||
self:T({heliname,groupname})
|
self:T({heliname,groupname})
|
||||||
local _heliUnit = self:_GetSARHeli(heliname)
|
local _heliUnit = self:_GetSARHeli(heliname)
|
||||||
@@ -1337,8 +1327,8 @@ function CSAR:_ScheduledSARFlight(heliname,groupname)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if _dist < 200 and _heliUnit:InAir() == false then
|
if ( _dist < self.FARPRescueDistance or isairport ) and _heliUnit:InAir() == false then
|
||||||
if self.pilotmustopendoors and not self:_IsLoadingDoorOpen(heliname) then
|
if self.pilotmustopendoors and self:_IsLoadingDoorOpen(heliname) == false then
|
||||||
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true)
|
self:_DisplayMessageToSAR(_heliUnit, "Open the door to let me out!", self.messageTime, true)
|
||||||
else
|
else
|
||||||
self:_RescuePilots(_heliUnit)
|
self:_RescuePilots(_heliUnit)
|
||||||
@@ -1347,7 +1337,7 @@ function CSAR:_ScheduledSARFlight(heliname,groupname)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--queue up
|
--queue up
|
||||||
self:__Returning(-5,heliname,_woundedGroupName)
|
self:__Returning(-5,heliname,_woundedGroupName, isairport)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1403,7 +1393,9 @@ function CSAR:_DisplayMessageToSAR(_unit, _text, _time, _clear, _speak)
|
|||||||
local group = _unit:GetGroup()
|
local group = _unit:GetGroup()
|
||||||
local _clear = _clear or nil
|
local _clear = _clear or nil
|
||||||
local _time = _time or self.messageTime
|
local _time = _time or self.messageTime
|
||||||
local m = MESSAGE:New(_text,_time,"Info",_clear):ToGroup(group)
|
if not self.suppressmessages then
|
||||||
|
local m = MESSAGE:New(_text,_time,"Info",_clear):ToGroup(group)
|
||||||
|
end
|
||||||
-- integrate SRS
|
-- integrate SRS
|
||||||
if _speak and self.useSRS then
|
if _speak and self.useSRS then
|
||||||
local srstext = SOUNDTEXT:New(_text)
|
local srstext = SOUNDTEXT:New(_text)
|
||||||
@@ -1501,10 +1493,17 @@ function CSAR:_GetClosestDownedPilot(_heli)
|
|||||||
local _shortestDistance = -1
|
local _shortestDistance = -1
|
||||||
local _distance = 0
|
local _distance = 0
|
||||||
local _closestGroupInfo = nil
|
local _closestGroupInfo = nil
|
||||||
local _heliCoord = _heli:GetCoordinate()
|
local _heliCoord = _heli:GetCoordinate() or _heli:GetCoordinate()
|
||||||
|
|
||||||
|
if _heliCoord == nil then
|
||||||
|
self:E("****Error obtaining coordinate!")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
local DownedPilotsTable = self.downedPilots
|
local DownedPilotsTable = self.downedPilots
|
||||||
for _, _groupInfo in pairs(DownedPilotsTable) do
|
|
||||||
|
for _, _groupInfo in UTILS.spairs(DownedPilotsTable) do
|
||||||
|
--for _, _groupInfo in pairs(DownedPilotsTable) do
|
||||||
local _woundedName = _groupInfo.name
|
local _woundedName = _groupInfo.name
|
||||||
local _tempWounded = _groupInfo.group
|
local _tempWounded = _groupInfo.group
|
||||||
|
|
||||||
@@ -1570,12 +1569,11 @@ end
|
|||||||
-- @param #number _messagetime How long to show.
|
-- @param #number _messagetime How long to show.
|
||||||
function CSAR:_DisplayToAllSAR(_message, _side, _messagetime)
|
function CSAR:_DisplayToAllSAR(_message, _side, _messagetime)
|
||||||
self:T(self.lid .. " _DisplayToAllSAR")
|
self:T(self.lid .. " _DisplayToAllSAR")
|
||||||
|
local messagetime = _messagetime or self.messageTime
|
||||||
for _, _unitName in pairs(self.csarUnits) do
|
for _, _unitName in pairs(self.csarUnits) do
|
||||||
local _unit = self:_GetSARHeli(_unitName)
|
local _unit = self:_GetSARHeli(_unitName)
|
||||||
if _unit then
|
if _unit and not self.suppressmessages then
|
||||||
if not _messagetime then
|
self:_DisplayMessageToSAR(_unit, _message, _messagetime)
|
||||||
self:_DisplayMessageToSAR(_unit, _message, _messagetime)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
@@ -1747,9 +1745,21 @@ end
|
|||||||
function CSAR:_GetDistance(_point1, _point2)
|
function CSAR:_GetDistance(_point1, _point2)
|
||||||
self:T(self.lid .. " _GetDistance")
|
self:T(self.lid .. " _GetDistance")
|
||||||
if _point1 and _point2 then
|
if _point1 and _point2 then
|
||||||
local distance = _point1:DistanceFromPointVec2(_point2)
|
local distance1 = _point1:Get2DDistance(_point2)
|
||||||
return distance
|
local distance2 = _point1:DistanceFromPointVec2(_point2)
|
||||||
|
self:I({dist1=distance1, dist2=distance2})
|
||||||
|
if distance1 and type(distance1) == "number" then
|
||||||
|
return distance1
|
||||||
|
elseif distance2 and type(distance2) == "number" then
|
||||||
|
return distance2
|
||||||
|
else
|
||||||
|
self:E("*****Cannot calculate distance!")
|
||||||
|
self:E({_point1,_point2})
|
||||||
|
return -1
|
||||||
|
end
|
||||||
else
|
else
|
||||||
|
self:E("******Cannot calculate distance!")
|
||||||
|
self:E({_point1,_point2})
|
||||||
return -1
|
return -1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1915,19 +1925,19 @@ end
|
|||||||
-- @param #CSAR self
|
-- @param #CSAR self
|
||||||
function CSAR:_CheckDownedPilotTable()
|
function CSAR:_CheckDownedPilotTable()
|
||||||
local pilots = self.downedPilots
|
local pilots = self.downedPilots
|
||||||
for _,_entry in pairs (pilots) do
|
local npilots = {}
|
||||||
self:T("Checking for " .. _entry.name)
|
|
||||||
self:T({entry=_entry})
|
for _ind,_entry in pairs(pilots) do
|
||||||
local group = _entry.group
|
local _group = _entry.group
|
||||||
if not group:IsAlive() then
|
if _group:IsAlive() then
|
||||||
self:T("Group is dead")
|
npilots[_ind] = _entry
|
||||||
if _entry.alive == true then
|
else
|
||||||
self:T("Switching .alive to false")
|
if _entry.alive then
|
||||||
self:__KIA(1,_entry.desc)
|
self:__KIA(1,_entry.desc)
|
||||||
self:_RemoveNameFromDownedPilots(_entry.name,true)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self.downedPilots = npilots
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2047,9 +2057,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
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
-- @module Ops.CTLD
|
-- @module Ops.CTLD
|
||||||
-- @image OPS_CTLD.jpg
|
-- @image OPS_CTLD.jpg
|
||||||
|
|
||||||
-- Date: July 2021
|
-- Date: Aug 2021
|
||||||
|
|
||||||
do
|
do
|
||||||
------------------------------------------------------
|
------------------------------------------------------
|
||||||
@@ -264,7 +264,7 @@ do
|
|||||||
-- Add zones for loading troops and crates and dropping, building crates
|
-- Add zones for loading troops and crates and dropping, building crates
|
||||||
--
|
--
|
||||||
-- -- Add a zone of type LOAD to our setup. Players can load troops and crates.
|
-- -- Add a zone of type LOAD to our setup. Players can load troops and crates.
|
||||||
-- -- "Loadzone" is the name of the zone from the ME. Players can load, if they are inside of the zone.
|
-- -- "Loadzone" is the name of the zone from the ME. Players can load, if they are inside the zone.
|
||||||
-- -- Smoke and Flare color for this zone is blue, it is active (can be used) and has a radio beacon.
|
-- -- Smoke and Flare color for this zone is blue, it is active (can be used) and has a radio beacon.
|
||||||
-- my_ctld:AddCTLDZone("Loadzone",CTLD.CargoZoneType.LOAD,SMOKECOLOR.Blue,true,true)
|
-- my_ctld:AddCTLDZone("Loadzone",CTLD.CargoZoneType.LOAD,SMOKECOLOR.Blue,true,true)
|
||||||
--
|
--
|
||||||
@@ -279,6 +279,13 @@ do
|
|||||||
--
|
--
|
||||||
-- my_ctld:AddCTLDZone("Movezone2",CTLD.CargoZoneType.MOVE,SMOKECOLOR.White,true,true)
|
-- my_ctld:AddCTLDZone("Movezone2",CTLD.CargoZoneType.MOVE,SMOKECOLOR.White,true,true)
|
||||||
--
|
--
|
||||||
|
-- -- Add a zone of type SHIP to our setup. Players can load troops and crates from this ship
|
||||||
|
-- -- "Tarawa" is the unitname (callsign) of the ship from the ME. Players can load, if they are inside the zone.
|
||||||
|
-- -- The ship is 240 meters long and 20 meters wide.
|
||||||
|
-- -- Note that smoke, flares, beacons don't work for this type of loadzone (yet). Also, you need to adjust
|
||||||
|
-- -- the max hover height to deck height plus 5 meters or so for loading to work.
|
||||||
|
-- -- When the ship is moving, forcing hoverload might not be a good idea.
|
||||||
|
-- my_ctld:AddCTLDZone("Tarawa",CTLD.CargoZoneType.SHIP,SMOKECOLOR.Blue,true,true,240,20)
|
||||||
--
|
--
|
||||||
-- ## 2. Options
|
-- ## 2. Options
|
||||||
--
|
--
|
||||||
@@ -511,11 +518,13 @@ CTLD = {
|
|||||||
-- @field #string name Name of Zone.
|
-- @field #string name Name of Zone.
|
||||||
-- @field #string color Smoke color for zone, e.g. SMOKECOLOR.Red.
|
-- @field #string color Smoke color for zone, e.g. SMOKECOLOR.Red.
|
||||||
-- @field #boolean active Active or not.
|
-- @field #boolean active Active or not.
|
||||||
-- @field #string type Type of zone, i.e. load,drop,move
|
-- @field #string type Type of zone, i.e. load,drop,move,ship
|
||||||
-- @field #boolean hasbeacon Create and run radio beacons if active.
|
-- @field #boolean hasbeacon Create and run radio beacons if active.
|
||||||
-- @field #table fmbeacon Beacon info as #CTLD.ZoneBeacon
|
-- @field #table fmbeacon Beacon info as #CTLD.ZoneBeacon
|
||||||
-- @field #table uhfbeacon Beacon info as #CTLD.ZoneBeacon
|
-- @field #table uhfbeacon Beacon info as #CTLD.ZoneBeacon
|
||||||
-- @field #table vhfbeacon Beacon info as #CTLD.ZoneBeacon
|
-- @field #table vhfbeacon Beacon info as #CTLD.ZoneBeacon
|
||||||
|
-- @field #number shiplength For ships - length of ship
|
||||||
|
-- @field #number shipwidth For ships - width of ship
|
||||||
|
|
||||||
--- Zone Type Info.
|
--- Zone Type Info.
|
||||||
-- @type CTLD.CargoZoneType
|
-- @type CTLD.CargoZoneType
|
||||||
@@ -523,6 +532,7 @@ CTLD.CargoZoneType = {
|
|||||||
LOAD = "load",
|
LOAD = "load",
|
||||||
DROP = "drop",
|
DROP = "drop",
|
||||||
MOVE = "move",
|
MOVE = "move",
|
||||||
|
SHIP = "ship",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Buildable table info.
|
--- Buildable table info.
|
||||||
@@ -557,7 +567,7 @@ CTLD.UnitTypes = {
|
|||||||
|
|
||||||
--- CTLD class version.
|
--- CTLD class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
CTLD.version="0.1.4r3"
|
CTLD.version="0.1.5a1"
|
||||||
|
|
||||||
--- Instantiate a new CTLD.
|
--- Instantiate a new CTLD.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@@ -643,6 +653,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
self.pickupZones = {}
|
self.pickupZones = {}
|
||||||
self.dropOffZones = {}
|
self.dropOffZones = {}
|
||||||
self.wpZones = {}
|
self.wpZones = {}
|
||||||
|
self.shipZones = {}
|
||||||
|
|
||||||
-- Cargo
|
-- Cargo
|
||||||
self.Cargo_Crates = {}
|
self.Cargo_Crates = {}
|
||||||
@@ -659,6 +670,7 @@ function CTLD:New(Coalition, Prefixes, Alias)
|
|||||||
|
|
||||||
-- setup
|
-- setup
|
||||||
self.CrateDistance = 30 -- list/load crates in this radius
|
self.CrateDistance = 30 -- list/load crates in this radius
|
||||||
|
self.ExtractFactor = 3.33 -- factor for troops extraction, i.e. CrateDistance * Extractfactor
|
||||||
self.prefixes = Prefixes or {"Cargoheli"}
|
self.prefixes = Prefixes or {"Cargoheli"}
|
||||||
--self.I({prefixes = self.prefixes})
|
--self.I({prefixes = self.prefixes})
|
||||||
self.useprefix = true
|
self.useprefix = true
|
||||||
@@ -927,6 +939,9 @@ function CTLD:_LoadTroops(Group, Unit, Cargotype)
|
|||||||
local hoverload = self:CanHoverLoad(Unit)
|
local hoverload = self:CanHoverLoad(Unit)
|
||||||
-- check if we are in LOAD zone
|
-- check if we are in LOAD zone
|
||||||
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
||||||
|
if not inzone then
|
||||||
|
inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
||||||
|
end
|
||||||
if not inzone then
|
if not inzone then
|
||||||
self:_SendMessage("You are not close enough to a logistics zone!", 10, false, Group)
|
self:_SendMessage("You are not close enough to a logistics zone!", 10, false, Group)
|
||||||
if not self.debug then return self end
|
if not self.debug then return self end
|
||||||
@@ -1116,8 +1131,10 @@ end
|
|||||||
nearestDistance = distance
|
nearestDistance = distance
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if nearestGroup == nil or nearestDistance > self.CrateDistance then
|
local extractdistance = self.CrateDistance * self.ExtractFactor
|
||||||
|
|
||||||
|
if nearestGroup == nil or nearestDistance > extractdistance then
|
||||||
self:_SendMessage("No units close enough to extract!", 10, false, Group)
|
self:_SendMessage("No units close enough to extract!", 10, false, Group)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1165,7 +1182,7 @@ end
|
|||||||
|
|
||||||
-- clean up:
|
-- clean up:
|
||||||
table.remove(self.DroppedTroops, nearestGroupIndex)
|
table.remove(self.DroppedTroops, nearestGroupIndex)
|
||||||
nearestGroup:Destroy()
|
nearestGroup:Destroy(false)
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -1183,8 +1200,13 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
|
|||||||
-- check if we are in LOAD zone
|
-- check if we are in LOAD zone
|
||||||
local inzone = false
|
local inzone = false
|
||||||
local drop = drop or false
|
local drop = drop or false
|
||||||
|
local ship = nil
|
||||||
|
local width = 20
|
||||||
if not drop then
|
if not drop then
|
||||||
inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
inzone = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
||||||
|
if not inzone then
|
||||||
|
inzone, ship, zone, distance, width = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if self.dropcratesanywhere then -- #1570
|
if self.dropcratesanywhere then -- #1570
|
||||||
inzone = true
|
inzone = true
|
||||||
@@ -1230,18 +1252,33 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
|
|||||||
for i=1,50 do
|
for i=1,50 do
|
||||||
math.random(90,270)
|
math.random(90,270)
|
||||||
end
|
end
|
||||||
local rheading = math.floor(math.random(90,270) * heading + 1 / 360)
|
local rheading = math.floor(((math.random(90,270) * heading) + 1) / 360)
|
||||||
if not IsHerc then
|
if not IsHerc then
|
||||||
rheading = rheading + 180 -- mirror for Helis
|
rheading = rheading + 180 -- mirror for Helis
|
||||||
end
|
end
|
||||||
if rheading > 360 then rheading = rheading - 360 end -- catch > 360
|
if rheading > 360 then rheading = rheading - 360 end -- catch > 360
|
||||||
local cratecoord = position:Translate(cratedistance,rheading)
|
local cratecoord = position:Translate(cratedistance,rheading)
|
||||||
local cratevec2 = cratecoord:GetVec2()
|
local cratevec2 = cratecoord:GetVec2()
|
||||||
self.CrateCounter = self.CrateCounter + 1
|
self.CrateCounter = self.CrateCounter + 1
|
||||||
|
if type(ship) == "string" then
|
||||||
|
self:T("Spawning on ship "..ship)
|
||||||
|
local Ship = UNIT:FindByName(ship)
|
||||||
|
local shipcoord = Ship:GetCoordinate()
|
||||||
|
local unitcoord = Unit:GetCoordinate()
|
||||||
|
local dist = shipcoord:Get2DDistance(unitcoord)
|
||||||
|
dist = dist - (20 + math.random(1,10))
|
||||||
|
local width = width / 2
|
||||||
|
local Offy = math.random(-width,width)
|
||||||
|
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType("container_cargo","Cargos",country.id.GERMANY)
|
||||||
|
--:InitCoordinate(cratecoord)
|
||||||
|
:InitLinkToUnit(Ship,dist,Offy,0)
|
||||||
|
:Spawn(270,cratealias)
|
||||||
|
else
|
||||||
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType("container_cargo","Cargos",country.id.GERMANY)
|
self.Spawned_Crates[self.CrateCounter] = SPAWNSTATIC:NewFromType("container_cargo","Cargos",country.id.GERMANY)
|
||||||
:InitCoordinate(cratecoord)
|
:InitCoordinate(cratecoord)
|
||||||
|
--:InitLinkToUnit(Unit,OffsetX,OffsetY,OffsetAngle)
|
||||||
:Spawn(270,cratealias)
|
:Spawn(270,cratealias)
|
||||||
|
end
|
||||||
local templ = cargotype:GetTemplates()
|
local templ = cargotype:GetTemplates()
|
||||||
local sorte = cargotype:GetType()
|
local sorte = cargotype:GetType()
|
||||||
self.CargoCounter = self.CargoCounter +1
|
self.CargoCounter = self.CargoCounter +1
|
||||||
@@ -1390,8 +1427,13 @@ function CTLD:_LoadCratesNearby(Group, Unit)
|
|||||||
-- get nearby crates
|
-- get nearby crates
|
||||||
local finddist = self.CrateDistance or 30
|
local finddist = self.CrateDistance or 30
|
||||||
local nearcrates,number = self:_FindCratesNearby(Group,Unit,finddist) -- #table
|
local nearcrates,number = self:_FindCratesNearby(Group,Unit,finddist) -- #table
|
||||||
if number == 0 or numberonboard == cratelimit then
|
if number == 0 and self.hoverautoloading then
|
||||||
self:_SendMessage("Sorry no loadable crates nearby or fully loaded!", 10, false, Group)
|
return -- exit
|
||||||
|
elseif number == 0 then
|
||||||
|
self:_SendMessage("Sorry no loadable crates nearby!", 10, false, Group)
|
||||||
|
return -- exit
|
||||||
|
elseif numberonboard == cratelimit then
|
||||||
|
self:_SendMessage("Sorry no fully loaded!", 10, false, Group)
|
||||||
return -- exit
|
return -- exit
|
||||||
else
|
else
|
||||||
-- go through crates and load
|
-- go through crates and load
|
||||||
@@ -1415,14 +1457,14 @@ function CTLD:_LoadCratesNearby(Group, Unit)
|
|||||||
table.insert(loaded.Cargo, crate)
|
table.insert(loaded.Cargo, crate)
|
||||||
table.insert(crateidsloaded,crate:GetID())
|
table.insert(crateidsloaded,crate:GetID())
|
||||||
-- destroy crate
|
-- destroy crate
|
||||||
crate:GetPositionable():Destroy()
|
crate:GetPositionable():Destroy(false)
|
||||||
crate.Positionable = nil
|
crate.Positionable = nil
|
||||||
self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group)
|
self:_SendMessage(string.format("Crate ID %d for %s loaded!",crate:GetID(),crate:GetName()), 10, false, Group)
|
||||||
self:_UpdateUnitCargoMass(Unit)
|
|
||||||
self:__CratesPickedUp(1, Group, Unit, crate)
|
self:__CratesPickedUp(1, Group, Unit, crate)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.Loaded_Cargo[unitname] = loaded
|
self.Loaded_Cargo[unitname] = loaded
|
||||||
|
self:_UpdateUnitCargoMass(Unit)
|
||||||
-- clean up real world crates
|
-- clean up real world crates
|
||||||
local existingcrates = self.Spawned_Cargo -- #table
|
local existingcrates = self.Spawned_Cargo -- #table
|
||||||
local newexcrates = {}
|
local newexcrates = {}
|
||||||
@@ -1474,9 +1516,10 @@ function CTLD:_UpdateUnitCargoMass(Unit)
|
|||||||
self:T(self.lid .. " _UpdateUnitCargoMass")
|
self:T(self.lid .. " _UpdateUnitCargoMass")
|
||||||
local calculatedMass = self:_GetUnitCargoMass(Unit)
|
local calculatedMass = self:_GetUnitCargoMass(Unit)
|
||||||
Unit:SetUnitInternalCargo(calculatedMass)
|
Unit:SetUnitInternalCargo(calculatedMass)
|
||||||
local report = REPORT:New("Loadmaster report")
|
--local report = REPORT:New("Loadmaster report")
|
||||||
report:Add("Carrying " .. calculatedMass .. "Kg")
|
--report:Add("Carrying " .. calculatedMass .. "Kg")
|
||||||
self:_SendMessage(report:Text(),10,false,Unit:GetGroup())
|
--self:_SendMessage(report:Text(),10,false,Unit:GetGroup())
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- (Internal) Function to list loaded cargo.
|
--- (Internal) Function to list loaded cargo.
|
||||||
@@ -1557,6 +1600,9 @@ function CTLD:_UnloadTroops(Group, Unit)
|
|||||||
-- check if we are in LOAD zone
|
-- check if we are in LOAD zone
|
||||||
local droppingatbase = false
|
local droppingatbase = false
|
||||||
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
local inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD)
|
||||||
|
if not inzone then
|
||||||
|
inzone, zonename, zone, distance = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP)
|
||||||
|
end
|
||||||
if inzone then
|
if inzone then
|
||||||
droppingatbase = true
|
droppingatbase = true
|
||||||
end
|
end
|
||||||
@@ -1893,17 +1939,16 @@ function CTLD:_BuildObjectFromCrates(Group,Unit,Build,Repair,RepairLocation)
|
|||||||
end
|
end
|
||||||
for _,_template in pairs(temptable) do
|
for _,_template in pairs(temptable) do
|
||||||
self.TroopCounter = self.TroopCounter + 1
|
self.TroopCounter = self.TroopCounter + 1
|
||||||
if canmove then
|
|
||||||
local alias = string.format("%s-%d", _template, math.random(1,100000))
|
local alias = string.format("%s-%d", _template, math.random(1,100000))
|
||||||
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
if canmove then
|
||||||
:InitRandomizeUnits(true,20,2)
|
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
||||||
:InitDelayOff()
|
:InitRandomizeUnits(true,20,2)
|
||||||
:SpawnFromVec2(randomcoord)
|
:InitDelayOff()
|
||||||
|
:SpawnFromVec2(randomcoord)
|
||||||
else -- don't random position of e.g. SAM units build as FOB
|
else -- don't random position of e.g. SAM units build as FOB
|
||||||
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
self.DroppedTroops[self.TroopCounter] = SPAWN:NewWithAlias(_template,alias)
|
||||||
--:InitRandomizeUnits(true,20,2)
|
:InitDelayOff()
|
||||||
:InitDelayOff()
|
:SpawnFromVec2(randomcoord)
|
||||||
:SpawnFromVec2(randomcoord)
|
|
||||||
end
|
end
|
||||||
if self.movetroopstowpzone and canmove then
|
if self.movetroopstowpzone and canmove then
|
||||||
self:_MoveGroupToZone(self.DroppedTroops[self.TroopCounter])
|
self:_MoveGroupToZone(self.DroppedTroops[self.TroopCounter])
|
||||||
@@ -1967,7 +2012,7 @@ function CTLD:_CleanUpCrates(Crates,Build,Number)
|
|||||||
if name == nametype then -- matching crate type
|
if name == nametype then -- matching crate type
|
||||||
table.insert(destIDs,thisID)
|
table.insert(destIDs,thisID)
|
||||||
found = found + 1
|
found = found + 1
|
||||||
nowcrate:GetPositionable():Destroy()
|
nowcrate:GetPositionable():Destroy(false)
|
||||||
nowcrate.Positionable = nil
|
nowcrate.Positionable = nil
|
||||||
end
|
end
|
||||||
if found == numberdest then break end -- got enough
|
if found == numberdest then break end -- got enough
|
||||||
@@ -2133,6 +2178,8 @@ function CTLD:AddZone(Zone)
|
|||||||
table.insert(self.pickupZones,zone)
|
table.insert(self.pickupZones,zone)
|
||||||
elseif zone.type == CTLD.CargoZoneType.DROP then
|
elseif zone.type == CTLD.CargoZoneType.DROP then
|
||||||
table.insert(self.dropOffZones,zone)
|
table.insert(self.dropOffZones,zone)
|
||||||
|
elseif zone.type == CTLD.CargoZoneType.SHIP then
|
||||||
|
table.insert(self.shipZones,zone)
|
||||||
else
|
else
|
||||||
table.insert(self.wpZones,zone)
|
table.insert(self.wpZones,zone)
|
||||||
end
|
end
|
||||||
@@ -2158,6 +2205,8 @@ function CTLD:ActivateZone(Name,ZoneType,NewState)
|
|||||||
table = self.pickupZones
|
table = self.pickupZones
|
||||||
elseif ZoneType == CTLD.CargoZoneType.DROP then
|
elseif ZoneType == CTLD.CargoZoneType.DROP then
|
||||||
table = self.dropOffZones
|
table = self.dropOffZones
|
||||||
|
elseif ZoneType == CTLD.CargoZoneType.SHIP then
|
||||||
|
table = self.shipZones
|
||||||
else
|
else
|
||||||
table = self.wpZones
|
table = self.wpZones
|
||||||
end
|
end
|
||||||
@@ -2255,8 +2304,10 @@ end
|
|||||||
-- @param #number Color Smoke/Flare color e.g. #SMOKECOLOR.Red
|
-- @param #number Color Smoke/Flare color e.g. #SMOKECOLOR.Red
|
||||||
-- @param #string Active Is this zone currently active?
|
-- @param #string Active Is this zone currently active?
|
||||||
-- @param #string HasBeacon Does this zone have a beacon if it is active?
|
-- @param #string HasBeacon Does this zone have a beacon if it is active?
|
||||||
|
-- @param #number Shiplength Length of Ship for shipzones
|
||||||
|
-- @param #number Shipwidth Width of Ship for shipzones
|
||||||
-- @return #CTLD self
|
-- @return #CTLD self
|
||||||
function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon)
|
function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon, Shiplength, Shipwidth)
|
||||||
self:T(self.lid .. " AddCTLDZone")
|
self:T(self.lid .. " AddCTLDZone")
|
||||||
|
|
||||||
local ctldzone = {} -- #CTLD.CargoZone
|
local ctldzone = {} -- #CTLD.CargoZone
|
||||||
@@ -2276,6 +2327,11 @@ function CTLD:AddCTLDZone(Name, Type, Color, Active, HasBeacon)
|
|||||||
ctldzone.vhfbeacon = nil
|
ctldzone.vhfbeacon = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if Type == CTLD.CargoZoneType.SHIP then
|
||||||
|
ctldzone.shiplength = Shiplength or 100
|
||||||
|
ctldzone.shipwidth = Shipwidth or 10
|
||||||
|
end
|
||||||
|
|
||||||
self:AddZone(ctldzone)
|
self:AddZone(ctldzone)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -2367,10 +2423,12 @@ end
|
|||||||
-- @param #CTLD.CargoZoneType Zonetype Zonetype
|
-- @param #CTLD.CargoZoneType Zonetype Zonetype
|
||||||
-- @return #boolean Outcome Is in zone or not
|
-- @return #boolean Outcome Is in zone or not
|
||||||
-- @return #string name Closest zone name
|
-- @return #string name Closest zone name
|
||||||
-- @return #string zone Closest Core.Zone#ZONE object
|
-- @return Core.Zone#ZONE zone Closest Core.Zone#ZONE object
|
||||||
-- @return #number distance Distance to closest zone
|
-- @return #number distance Distance to closest zone
|
||||||
|
-- @return #number width Radius of zone or width of ship
|
||||||
function CTLD:IsUnitInZone(Unit,Zonetype)
|
function CTLD:IsUnitInZone(Unit,Zonetype)
|
||||||
self:T(self.lid .. " IsUnitInZone")
|
self:T(self.lid .. " IsUnitInZone")
|
||||||
|
self:T(Zonetype)
|
||||||
local unitname = Unit:GetName()
|
local unitname = Unit:GetName()
|
||||||
local zonetable = {}
|
local zonetable = {}
|
||||||
local outcome = false
|
local outcome = false
|
||||||
@@ -2378,6 +2436,8 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
|
|||||||
zonetable = self.pickupZones -- #table
|
zonetable = self.pickupZones -- #table
|
||||||
elseif Zonetype == CTLD.CargoZoneType.DROP then
|
elseif Zonetype == CTLD.CargoZoneType.DROP then
|
||||||
zonetable = self.dropOffZones -- #table
|
zonetable = self.dropOffZones -- #table
|
||||||
|
elseif Zonetype == CTLD.CargoZoneType.SHIP then
|
||||||
|
zonetable = self.shipZones -- #table
|
||||||
else
|
else
|
||||||
zonetable = self.wpZones -- #table
|
zonetable = self.wpZones -- #table
|
||||||
end
|
end
|
||||||
@@ -2386,16 +2446,29 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
|
|||||||
local colorret = nil
|
local colorret = nil
|
||||||
local maxdist = 1000000 -- 100km
|
local maxdist = 1000000 -- 100km
|
||||||
local zoneret = nil
|
local zoneret = nil
|
||||||
|
local zonewret = nil
|
||||||
local zonenameret = nil
|
local zonenameret = nil
|
||||||
for _,_cargozone in pairs(zonetable) do
|
for _,_cargozone in pairs(zonetable) do
|
||||||
local czone = _cargozone -- #CTLD.CargoZone
|
local czone = _cargozone -- #CTLD.CargoZone
|
||||||
local unitcoord = Unit:GetCoordinate()
|
local unitcoord = Unit:GetCoordinate()
|
||||||
local zonename = czone.name
|
local zonename = czone.name
|
||||||
local zone = ZONE:FindByName(zonename)
|
|
||||||
zonecoord = zone:GetCoordinate()
|
|
||||||
local active = czone.active
|
local active = czone.active
|
||||||
local color = czone.color
|
local color = czone.color
|
||||||
local zoneradius = zone:GetRadius()
|
local zone = nil
|
||||||
|
local zoneradius = 100
|
||||||
|
local zonewidth = 20
|
||||||
|
if Zonetype == CTLD.CargoZoneType.SHIP then
|
||||||
|
self:T("Checking Type Ship: "..zonename)
|
||||||
|
zone = UNIT:FindByName(zonename)
|
||||||
|
zonecoord = zone:GetCoordinate()
|
||||||
|
zoneradius = czone.shiplength
|
||||||
|
zonewidth = czone.shipwidth
|
||||||
|
else
|
||||||
|
zone = ZONE:FindByName(zonename)
|
||||||
|
zonecoord = zone:GetCoordinate()
|
||||||
|
zoneradius = zone:GetRadius()
|
||||||
|
zonewidth = zoneradius
|
||||||
|
end
|
||||||
local distance = self:_GetDistance(zonecoord,unitcoord)
|
local distance = self:_GetDistance(zonecoord,unitcoord)
|
||||||
if distance <= zoneradius and active then
|
if distance <= zoneradius and active then
|
||||||
outcome = true
|
outcome = true
|
||||||
@@ -2404,10 +2477,15 @@ function CTLD:IsUnitInZone(Unit,Zonetype)
|
|||||||
maxdist = distance
|
maxdist = distance
|
||||||
zoneret = zone
|
zoneret = zone
|
||||||
zonenameret = zonename
|
zonenameret = zonename
|
||||||
|
zonewret = zonewidth
|
||||||
colorret = color
|
colorret = color
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return outcome, zonenameret, zoneret, maxdist
|
if Zonetype == CTLD.CargoZoneType.SHIP then
|
||||||
|
return outcome, zonenameret, zoneret, maxdist, zonewret
|
||||||
|
else
|
||||||
|
return outcome, zonenameret, zoneret, maxdist
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- User function - Start smoke in a zone close to the Unit.
|
--- User function - Start smoke in a zone close to the Unit.
|
||||||
@@ -2590,6 +2668,9 @@ end
|
|||||||
self:T(self.lid .. " CanHoverLoad")
|
self:T(self.lid .. " CanHoverLoad")
|
||||||
if self:IsHercules(Unit) then return false end
|
if self:IsHercules(Unit) then return false end
|
||||||
local outcome = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) and self:IsCorrectHover(Unit)
|
local outcome = self:IsUnitInZone(Unit,CTLD.CargoZoneType.LOAD) and self:IsCorrectHover(Unit)
|
||||||
|
if not outcome then
|
||||||
|
outcome = self:IsUnitInZone(Unit,CTLD.CargoZoneType.SHIP) --and self:IsCorrectHover(Unit)
|
||||||
|
end
|
||||||
return outcome
|
return outcome
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -2651,7 +2732,7 @@ end
|
|||||||
if self.hoverautoloading then
|
if self.hoverautoloading then
|
||||||
for _,_pilot in pairs (self.CtldUnits) do
|
for _,_pilot in pairs (self.CtldUnits) do
|
||||||
local Unit = UNIT:FindByName(_pilot)
|
local Unit = UNIT:FindByName(_pilot)
|
||||||
self:AutoHoverLoad(Unit)
|
if self:CanHoverLoad(Unit) then self:AutoHoverLoad(Unit) end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
@@ -2683,7 +2764,7 @@ end
|
|||||||
-- @return #CTLD self
|
-- @return #CTLD self
|
||||||
function CTLD:onafterStart(From, Event, To)
|
function CTLD:onafterStart(From, Event, To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
self:I(self.lid .. "Started.")
|
self:I(self.lid .. "Started ("..self.version..")")
|
||||||
if self.useprefix or self.enableHercules then
|
if self.useprefix or self.enableHercules then
|
||||||
local prefix = self.prefixes
|
local prefix = self.prefixes
|
||||||
if self.enableHercules then
|
if self.enableHercules then
|
||||||
|
|||||||
@@ -162,33 +162,32 @@ RADIOSPEECH.Vocabulary.RU = {
|
|||||||
["8000"] = { "8000", 0.92 },
|
["8000"] = { "8000", 0.92 },
|
||||||
["9000"] = { "9000", 0.87 },
|
["9000"] = { "9000", 0.87 },
|
||||||
|
|
||||||
["Ñ<EFBFBD>тепени"] = { "degrees", 0.5 },
|
["градусы"] = { "degrees", 0.5 },
|
||||||
["километров"] = { "kilometers", 0.65 },
|
["километры"] = { "kilometers", 0.65 },
|
||||||
["km"] = { "kilometers", 0.65 },
|
["km"] = { "kilometers", 0.65 },
|
||||||
["миль"] = { "miles", 0.45 },
|
["мили"] = { "miles", 0.45 },
|
||||||
["mi"] = { "miles", 0.45 },
|
["mi"] = { "miles", 0.45 },
|
||||||
["метры"] = { "meters", 0.41 },
|
["метров"] = { "meters", 0.41 },
|
||||||
["m"] = { "meters", 0.41 },
|
["m"] = { "meters", 0.41 },
|
||||||
["ноги"] = { "feet", 0.37 },
|
["ноги"] = { "feet", 0.37 },
|
||||||
|
|
||||||
["br"] = { "br", 1.1 },
|
["br"] = { "br", 1.1 },
|
||||||
["bra"] = { "bra", 0.3 },
|
["bra"] = { "bra", 0.3 },
|
||||||
|
|
||||||
|
["возвращение на базу"] = { "returning_to_base", 1.40 },
|
||||||
|
["на пути к наземной цели"] = { "on_route_to_ground_target", 1.45 },
|
||||||
|
["перехват боги"] = { "intercepting_bogeys", 1.22 },
|
||||||
|
["поражение наземной цели"] = { "engaging_ground_target", 1.53 },
|
||||||
|
["привлечение болотных птиц"] = { "engaging_bogeys", 1.68 },
|
||||||
|
["колёса вверх..."] = { "wheels_up", 0.92 },
|
||||||
|
["посадка на базу"] = { "landing at base", 1.04 },
|
||||||
|
["патрулирование"] = { "patrolling", 0.96 },
|
||||||
|
|
||||||
["возвращаÑ<EFBFBD>Ñ<EFBFBD>ÑŒ на базу"] = { "returning_to_base", 1.40 },
|
["для"] = { "for", 0.27 },
|
||||||
["на пути к наземной цели"] = { "on_route_to_ground_target", 1.45 },
|
["и"] = { "and", 0.17 },
|
||||||
["перехват Ñ<>амолетов"] = { "intercepting_bogeys", 1.22 },
|
["на сайте"] = { "at", 0.19 },
|
||||||
["поражение наземной цели"] = { "engaging_ground_target", 1.53 },
|
["точка"] = { "dot", 0.51 },
|
||||||
["захватывающие Ñ<>амолеты"] = { "engaging_bogeys", 1.68 },
|
["защитник"] = { "defender", 0.45 },
|
||||||
["колеÑ<EFBFBD>а вверх"] = { "wheels_up", 0.92 },
|
|
||||||
["поÑ<EFBFBD>адка на базу"] = { "landing at base", 1.04 },
|
|
||||||
["патрулирующий"] = { "patrolling", 0.96 },
|
|
||||||
|
|
||||||
["за"] = { "for", 0.27 },
|
|
||||||
["и"] = { "and", 0.17 },
|
|
||||||
["в"] = { "at", 0.19 },
|
|
||||||
["dot"] = { "dot", 0.51 },
|
|
||||||
["defender"] = { "defender", 0.45 },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Create a new RADIOSPEECH object for a given radio frequency/modulation.
|
--- Create a new RADIOSPEECH object for a given radio frequency/modulation.
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ UTILS.tostringLL = function( lat, lon, acc, DMS)
|
|||||||
secFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
|
secFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 024<EFBFBD> 23' 12"N or 024<EFBFBD> 23' 12.03"N
|
-- 024° 23' 12"N or 024° 23' 12.03"N
|
||||||
return string.format('%03d°', latDeg)..string.format('%02d', latMin)..'\''..string.format(secFrmtStr, latSec)..'"'..latHemi..' '
|
return string.format('%03d°', latDeg)..string.format('%02d', latMin)..'\''..string.format(secFrmtStr, latSec)..'"'..latHemi..' '
|
||||||
.. string.format('%03d°', lonDeg)..string.format('%02d', lonMin)..'\''..string.format(secFrmtStr, lonSec)..'"'..lonHemi
|
.. string.format('%03d°', lonDeg)..string.format('%02d', lonMin)..'\''..string.format(secFrmtStr, lonSec)..'"'..lonHemi
|
||||||
|
|
||||||
@@ -1510,7 +1510,7 @@ end
|
|||||||
--@return #table
|
--@return #table
|
||||||
function UTILS.ShuffleTable(t)
|
function UTILS.ShuffleTable(t)
|
||||||
if t == nil or type(t) ~= "table" then
|
if t == nil or type(t) ~= "table" then
|
||||||
BASE:I("Error in ShuffleTable: Missing or wrong tyåe of Argument")
|
BASE:I("Error in ShuffleTable: Missing or wrong type of Argument")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
math.random()
|
math.random()
|
||||||
@@ -1535,8 +1535,8 @@ function UTILS.IsLoadingDoorOpen( unit_name )
|
|||||||
if unit ~= nil then
|
if unit ~= nil then
|
||||||
local type_name = unit:getTypeName()
|
local type_name = unit:getTypeName()
|
||||||
|
|
||||||
if type_name == "Mi-8MT" and unit:getDrawArgumentValue(86) == 1 or unit:getDrawArgumentValue(250) == 1 then
|
if type_name == "Mi-8MT" and unit:getDrawArgumentValue(38) == 1 or unit:getDrawArgumentValue(86) == 1 or unit:getDrawArgumentValue(250) == 1 then
|
||||||
BASE:T(unit_name .. " Cargo doors are open or cargo door not present")
|
BASE:T(unit_name .. " Cargo doors are open or cargo door not present")
|
||||||
ret_val = true
|
ret_val = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user