mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
a68eeae9bd
@ -3477,7 +3477,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " wheels up.", DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " wheels up.", DefenderGroup )
|
||||||
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " колеÑ<EFBFBD>а вверх.", DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " колёса вверх.", DefenderGroup )
|
||||||
end
|
end
|
||||||
--Fsm:__Engage( 2, DefenderTarget.Set ) -- Engage on the TargetSetUnit
|
--Fsm:__Engage( 2, DefenderTarget.Set ) -- Engage on the TargetSetUnit
|
||||||
Fsm:EngageRoute( DefenderTarget.Set ) -- Engage on the TargetSetUnit
|
Fsm:EngageRoute( DefenderTarget.Set ) -- Engage on the TargetSetUnit
|
||||||
@ -3498,7 +3498,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", intercepting bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", intercepting bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
||||||
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", перехват Ñ<>амолетов в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", перехватывая боги в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
||||||
elseif Squadron.Language == "DE" and self.SetSendPlayerMessages then
|
elseif Squadron.Language == "DE" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", Eindringlinge abfangen bei" .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", Eindringlinge abfangen bei" .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
||||||
end
|
end
|
||||||
@ -3520,7 +3520,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", engaging bogeys at " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
||||||
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", захватывающие Ñ<>амолеты в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", задействуя боги в " .. Coordinate:ToStringA2A( DefenderGroup, nil, Squadron.Language ), DefenderGroup )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:GetParent( Fsm ).onafterEngage( self, DefenderGroup, From, Event, To, AttackSetUnit )
|
self:GetParent( Fsm ).onafterEngage( self, DefenderGroup, From, Event, To, AttackSetUnit )
|
||||||
@ -3538,7 +3538,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " returning to base.", DefenderGroup )
|
||||||
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", возвращаÑ<EFBFBD>Ñ<EFBFBD>ÑŒ на базу.", DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", возвращение на базу.", DefenderGroup )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
|
Dispatcher:ClearDefenderTaskTarget( DefenderGroup )
|
||||||
@ -3569,7 +3569,7 @@ do -- AI_A2A_DISPATCHER
|
|||||||
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
if Squadron.Language == "EN" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " landing at base.", DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. " landing at base.", DefenderGroup )
|
||||||
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
elseif Squadron.Language == "RU" and self.SetSendPlayerMessages then
|
||||||
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", захватывающие Ñ<>амолеты в поÑ<C2BE>адка на базу.", DefenderGroup )
|
Dispatcher:MessageToPlayers( Squadron, DefenderName .. ", посадка на базу.", DefenderGroup )
|
||||||
end
|
end
|
||||||
|
|
||||||
if Action and Action == "Destroy" then
|
if Action and Action == "Destroy" then
|
||||||
|
|||||||
@ -47,19 +47,21 @@ function AI_CARGO:New( Carrier, CargoSet )
|
|||||||
|
|
||||||
self:SetStartState( "Unloaded" )
|
self:SetStartState( "Unloaded" )
|
||||||
|
|
||||||
self:AddTransition( "Unloaded", "Pickup", "*" )
|
-- Board
|
||||||
|
self:AddTransition( "Unloaded", "Pickup", "Unloaded" )
|
||||||
|
self:AddTransition( "*", "Load", "*" )
|
||||||
|
self:AddTransition( "*", "Reload", "*" )
|
||||||
|
self:AddTransition( "*", "Board", "*" )
|
||||||
|
self:AddTransition( "*", "Loaded", "Loaded" )
|
||||||
|
self:AddTransition( "Loaded", "PickedUp", "Loaded" )
|
||||||
|
|
||||||
|
-- Unload
|
||||||
self:AddTransition( "Loaded", "Deploy", "*" )
|
self:AddTransition( "Loaded", "Deploy", "*" )
|
||||||
|
self:AddTransition( "*", "Unload", "*" )
|
||||||
|
self:AddTransition( "*", "Unboard", "*" )
|
||||||
|
self:AddTransition( "*", "Unloaded", "Unloaded" )
|
||||||
|
self:AddTransition( "Unloaded", "Deployed", "Unloaded" )
|
||||||
|
|
||||||
self:AddTransition( "*", "Load", "Boarding" )
|
|
||||||
self:AddTransition( "Boarding", "Board", "Boarding" )
|
|
||||||
self:AddTransition( "Loaded", "Board", "Loaded" )
|
|
||||||
self:AddTransition( "Boarding", "Loaded", "Boarding" )
|
|
||||||
self:AddTransition( "Boarding", "PickedUp", "Loaded" )
|
|
||||||
|
|
||||||
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 )
|
||||||
|
|||||||
@ -174,8 +174,8 @@ function AI_CARGO_DISPATCHER_HELICOPTER:New( HelicopterSet, CargoSet, PickupZone
|
|||||||
self:SetPickupSpeed( 350, 150 )
|
self:SetPickupSpeed( 350, 150 )
|
||||||
self:SetDeploySpeed( 350, 150 )
|
self:SetDeploySpeed( 350, 150 )
|
||||||
|
|
||||||
self:SetPickupRadius( 0, 0 )
|
self:SetPickupRadius( 40, 12 )
|
||||||
self:SetDeployRadius( 0, 0 )
|
self:SetDeployRadius( 40, 12 )
|
||||||
|
|
||||||
self:SetPickupHeight( 500, 200 )
|
self:SetPickupHeight( 500, 200 )
|
||||||
self:SetDeployHeight( 500, 200 )
|
self:SetDeployHeight( 500, 200 )
|
||||||
@ -186,6 +186,9 @@ end
|
|||||||
|
|
||||||
function AI_CARGO_DISPATCHER_HELICOPTER:AICargo( Helicopter, CargoSet )
|
function AI_CARGO_DISPATCHER_HELICOPTER:AICargo( Helicopter, CargoSet )
|
||||||
|
|
||||||
return AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
|
local dispatcher = AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
|
||||||
|
dispatcher:SetLandingSpeedAndHeight(27, 6)
|
||||||
|
return dispatcher
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -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", "*" )
|
self:AddTransition( "Unloaded", "Pickup", "Unloaded" )
|
||||||
self:AddTransition( "Loaded", "Deploy", "*" )
|
|
||||||
self:AddTransition( "*", "Loaded", "Loaded" )
|
|
||||||
self:AddTransition( "Unboarding", "Pickup", "Unloaded" )
|
|
||||||
self:AddTransition( "Unloaded", "Unboard", "Unloaded" )
|
|
||||||
self:AddTransition( "Unloaded", "Unloaded", "Unloaded" )
|
|
||||||
self:AddTransition( "*", "PickedUp", "*" )
|
|
||||||
self:AddTransition( "*", "Landed", "*" )
|
self:AddTransition( "*", "Landed", "*" )
|
||||||
|
self:AddTransition( "*", "Load", "*" )
|
||||||
|
self:AddTransition( "*", "Loaded", "Loaded" )
|
||||||
|
self:AddTransition( "Loaded", "PickedUp", "Loaded" )
|
||||||
|
|
||||||
|
-- Unboarding
|
||||||
|
self:AddTransition( "Loaded", "Deploy", "*" )
|
||||||
self:AddTransition( "*", "Queue", "*" )
|
self:AddTransition( "*", "Queue", "*" )
|
||||||
self:AddTransition( "*", "Orbit" , "*" )
|
self:AddTransition( "*", "Orbit" , "*" )
|
||||||
self:AddTransition( "*", "Home" , "*" )
|
self:AddTransition( "*", "Destroyed", "*" )
|
||||||
|
self:AddTransition( "*", "Unload", "*" )
|
||||||
|
self:AddTransition( "*", "Unloaded", "Unloaded" )
|
||||||
|
self:AddTransition( "Unloaded", "Deployed", "Unloaded" )
|
||||||
|
|
||||||
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
-- RTB
|
||||||
|
self:AddTransition( "*", "Home" , "*" )
|
||||||
|
|
||||||
--- 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
|
||||||
|
|||||||
@ -59,7 +59,7 @@
|
|||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
--- *The worst thing that can happen to a good cause is, not to be skillfully attacked, but to be ineptly defended.* - Frédéric Bastiat
|
--- *The worst thing that can happen to a good cause is, not to be skillfully attacked, but to be ineptly defended.* - Frédéric Bastiat
|
||||||
--
|
--
|
||||||
-- Simple Class for a more intelligent Air Defense System
|
-- Simple Class for a more intelligent Air Defense System
|
||||||
--
|
--
|
||||||
|
|||||||
@ -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 <20>
|
-- * 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.
|
-- Ships 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()))
|
||||||
|
|
||||||
|
|||||||
@ -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' )
|
||||||
|
|||||||
@ -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,12 +343,13 @@ 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!
|
||||||
self.template = Template or "generic" -- template for downed pilot
|
self.template = Template or "generic" -- template for downed pilot
|
||||||
self.mashprefix = {"MASH"} -- prefixes used to find MASHes
|
self.mashprefix = {"MASH"} -- prefixes used to find MASHes
|
||||||
self.mash = SET_GROUP:New():FilterCoalitions(self.coalition):FilterPrefixes(self.mashprefix):FilterOnce() -- currently only GROUP objects, maybe support STATICs also?
|
|
||||||
self.autosmoke = false -- automatically smoke location when heli is near
|
self.autosmoke = false -- automatically smoke location when heli is near
|
||||||
self.autosmokedistance = 2000 -- distance for autosmoke
|
self.autosmokedistance = 2000 -- distance for autosmoke
|
||||||
-- added 0.1.4
|
-- added 0.1.4
|
||||||
@ -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
|
||||||
@ -934,7 +920,7 @@ function CSAR:_InitSARForPilot(_downedGroup, _GroupName, _freq, _nomessage)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- trigger FSM event
|
-- trigger FSM event
|
||||||
self:__PilotDown(2,_downedGroup, _freqk, _leadername, _coordinatesText)
|
self:__PilotDown(2,_downedGroup, _freqk, _groupName, _coordinatesText)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
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
|
||||||
|
if not self.suppressmessages then
|
||||||
local m = MESSAGE:New(_text,_time,"Info",_clear):ToGroup(group)
|
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,14 +1569,13 @@ 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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -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
|
else
|
||||||
|
self:E("*****Cannot calculate distance!")
|
||||||
|
self:E({_point1,_point2})
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:E("******Cannot calculate distance!")
|
||||||
|
self:E({_point1,_point2})
|
||||||
return -1
|
return -1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1907,6 +1917,7 @@ function CSAR:onafterStart(From, Event, To)
|
|||||||
else
|
else
|
||||||
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart()
|
self.allheligroupset = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterCategoryHelicopter():FilterStart()
|
||||||
end
|
end
|
||||||
|
self.mash = SET_GROUP:New():FilterCoalitions(self.coalitiontxt):FilterPrefixes(self.mashprefix):FilterStart() -- currently only GROUP objects, maybe support STATICs also?
|
||||||
self:__Status(-10)
|
self:__Status(-10)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@ -1915,19 +1926,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 +2058,10 @@ end
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
-- @param #string Heliname Name of the helicopter group.
|
-- @param #string Heliname Name of the helicopter group.
|
||||||
-- @param #string Woundedgroupname Name of the downed pilot\'s group.
|
-- @param #string Woundedgroupname Name of the downed pilot\'s group.
|
||||||
function CSAR:onbeforeReturning(From, Event, To, Heliname, Woundedgroupname)
|
-- @param #boolean IsAirport True if heli has landed on an AFB (from event land).
|
||||||
|
function CSAR:onbeforeReturning(From, Event, To, Heliname, Woundedgroupname, IsAirPort)
|
||||||
self:T({From, Event, To, Heliname, Woundedgroupname})
|
self:T({From, Event, To, Heliname, Woundedgroupname})
|
||||||
self:_ScheduledSARFlight(Heliname,Woundedgroupname)
|
self:_ScheduledSARFlight(Heliname,Woundedgroupname, IsAirPort)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
@ -1117,7 +1132,9 @@ end
|
|||||||
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,7 +1252,7 @@ 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
|
||||||
@ -1238,10 +1260,25 @@ function CTLD:_GetCrates(Group, Unit, Cargo, number, drop)
|
|||||||
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,7 +1457,7 @@ 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:__CratesPickedUp(1, Group, Unit, crate)
|
self:__CratesPickedUp(1, Group, Unit, crate)
|
||||||
@ -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
|
||||||
@ -1966,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
|
||||||
@ -2132,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
|
||||||
@ -2157,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
|
||||||
@ -2254,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
|
||||||
@ -2275,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
|
||||||
@ -2366,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
|
||||||
@ -2377,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
|
||||||
@ -2385,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
|
||||||
@ -2403,11 +2477,16 @@ 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
|
||||||
|
if Zonetype == CTLD.CargoZoneType.SHIP then
|
||||||
|
return outcome, zonenameret, zoneret, maxdist, zonewret
|
||||||
|
else
|
||||||
return outcome, zonenameret, zoneret, maxdist
|
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.
|
||||||
-- @param #CTLD self
|
-- @param #CTLD self
|
||||||
@ -2589,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
|
||||||
|
|
||||||
@ -2650,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
|
||||||
@ -2682,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,33 @@ 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 },
|
||||||
|
|
||||||
|
|
||||||
["возвращаÑ<EFBFBD>Ñ<EFBFBD>ÑŒ на базу"] = { "returning_to_base", 1.40 },
|
["возвращение на базу"] = { "returning_to_base", 1.40 },
|
||||||
["на пути к наземной цели"] = { "on_route_to_ground_target", 1.45 },
|
["на пути к наземной цели"] = { "on_route_to_ground_target", 1.45 },
|
||||||
["перехват Ñ<>амолетов"] = { "intercepting_bogeys", 1.22 },
|
["перехват боги"] = { "intercepting_bogeys", 1.22 },
|
||||||
["поражение наземной цели"] = { "engaging_ground_target", 1.53 },
|
["поражение наземной цели"] = { "engaging_ground_target", 1.53 },
|
||||||
["захватывающие Ñ<>амолеты"] = { "engaging_bogeys", 1.68 },
|
["привлечение болотных птиц"] = { "engaging_bogeys", 1.68 },
|
||||||
["колеÑ<EFBFBD>а вверх"] = { "wheels_up", 0.92 },
|
["колёса вверх..."] = { "wheels_up", 0.92 },
|
||||||
["поÑ<EFBFBD>адка на базу"] = { "landing at base", 1.04 },
|
["посадка на базу"] = { "landing at base", 1.04 },
|
||||||
["патрулирующий"] = { "patrolling", 0.96 },
|
["патрулирование"] = { "patrolling", 0.96 },
|
||||||
|
|
||||||
["за"] = { "for", 0.27 },
|
["для"] = { "for", 0.27 },
|
||||||
["и"] = { "and", 0.17 },
|
["и"] = { "and", 0.17 },
|
||||||
["в"] = { "at", 0.19 },
|
["на сайте"] = { "at", 0.19 },
|
||||||
["dot"] = { "dot", 0.51 },
|
["точка"] = { "dot", 0.51 },
|
||||||
["defender"] = { "defender", 0.45 },
|
["защитник"] = { "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.
|
||||||
|
|||||||
@ -507,7 +507,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<32> 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
|
||||||
|
|
||||||
@ -923,7 +923,7 @@ function UTILS.RandomGaussian(x0, sigma, xmin, xmax, imax)
|
|||||||
local x1=math.random()
|
local x1=math.random()
|
||||||
local x2=math.random()
|
local x2=math.random()
|
||||||
|
|
||||||
-- Transform to Gaussian exp(-(x-x0)²/(2*sigma²).
|
-- Transform to Gaussian exp(-(x-x0)°/(2*sigma°).
|
||||||
r = math.sqrt(-2*sigma*sigma * math.log(x1)) * math.cos(2*math.pi * x2) + x0
|
r = math.sqrt(-2*sigma*sigma * math.log(x1)) * math.cos(2*math.pi * x2) + x0
|
||||||
|
|
||||||
i=i+1
|
i=i+1
|
||||||
@ -1553,7 +1553,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()
|
||||||
@ -1578,7 +1578,7 @@ 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
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user