mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
130 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4a406604bd | ||
|
|
55cee46a8d | ||
|
|
607c52c0b7 | ||
|
|
2694321256 | ||
|
|
e8e790102a | ||
|
|
9c5561921b | ||
|
|
78fab9ab0c | ||
|
|
058c750bc6 | ||
|
|
f29da39dff | ||
|
|
624a7c70c9 | ||
|
|
0447ee2d9e | ||
|
|
456fcd38d0 | ||
|
|
a3cab7097a | ||
|
|
848e2f1294 | ||
|
|
ef4dc48ea1 | ||
|
|
2138a33292 | ||
|
|
a59343b987 | ||
|
|
a4ca4bdc99 | ||
|
|
a57b9a9081 | ||
|
|
249a6af456 | ||
|
|
18685d1a94 | ||
|
|
493b090534 | ||
|
|
389adab9b8 | ||
|
|
6360b8c58f | ||
|
|
b0818977cf | ||
|
|
32deb160ef | ||
|
|
2ba5215036 | ||
|
|
73ea4c7b32 | ||
|
|
46c37ff06a | ||
|
|
ff4708b624 | ||
|
|
82b2c84f13 | ||
|
|
48e8b1a9b3 | ||
|
|
1ad7c54ace | ||
|
|
9998c86c1f | ||
|
|
01a707ae0a | ||
|
|
570e8388fc | ||
|
|
9c5b5d4633 | ||
|
|
822bf13626 | ||
|
|
c520de0087 | ||
|
|
0e9076efa3 | ||
|
|
74cd5e3387 | ||
|
|
65c92be09e | ||
|
|
8e776cb3ab | ||
|
|
ab6cd2b751 | ||
|
|
18c3d990fc | ||
|
|
19d5cb8ecb | ||
|
|
2b56a78255 | ||
|
|
176d9df476 | ||
|
|
c94275cb8b | ||
|
|
45dbce3677 | ||
|
|
18745158a3 | ||
|
|
98c6c88391 | ||
|
|
2e4fd72781 | ||
|
|
80ced88ef1 | ||
|
|
8af3f89c14 | ||
|
|
fe3079caad | ||
|
|
61ac6b4131 | ||
|
|
36cb189512 | ||
|
|
15f9843878 | ||
|
|
67f847dd16 | ||
|
|
8b9143d3f1 | ||
|
|
0388d47f23 | ||
|
|
de9b173d9b | ||
|
|
2cecc526fb | ||
|
|
968d178317 | ||
|
|
3c477b872a | ||
|
|
77e6088114 | ||
|
|
edd6594953 | ||
|
|
f8c05c99d0 | ||
|
|
50f6d98b49 | ||
|
|
147eeb05f6 | ||
|
|
d8cb15a577 | ||
|
|
0daac876ea | ||
|
|
1832125022 | ||
|
|
c311c40b72 | ||
|
|
db516a2077 | ||
|
|
ff8766669c | ||
|
|
06dc9a732e | ||
|
|
50c74d0852 | ||
|
|
1c97eb6f3c | ||
|
|
69449430d1 | ||
|
|
663cd34aa3 | ||
|
|
cfed6f5153 | ||
|
|
2b22d5288c | ||
|
|
a64424ecc8 | ||
|
|
fd1b2ecb86 | ||
|
|
6cae3e62cf | ||
|
|
05ce7e4513 | ||
|
|
136bd19f19 | ||
|
|
8873504daf | ||
|
|
a844a5d697 | ||
|
|
a49f4eaa21 | ||
|
|
e6e2651f8c | ||
|
|
b93ba13644 | ||
|
|
e4a51951b0 | ||
|
|
ad56e39942 | ||
|
|
ea09dc5a6e | ||
|
|
8ecfd913a3 | ||
|
|
53367c786e | ||
|
|
db5797bb4e | ||
|
|
5e8fe97752 | ||
|
|
393fa0bfbb | ||
|
|
4f51884b9d | ||
|
|
4c5c320073 | ||
|
|
9098590568 | ||
|
|
555bb7e68b | ||
|
|
c0a18957f0 | ||
|
|
2cf939560e | ||
|
|
9d3a7aae78 | ||
|
|
f6ed592f92 | ||
|
|
c98757d13c | ||
|
|
17378f509e | ||
|
|
7f18ea0e7a | ||
|
|
5172619cb1 | ||
|
|
3962529698 | ||
|
|
6481d5d41e | ||
|
|
6cc3d73c04 | ||
|
|
e541e39403 | ||
|
|
c7ea45e5fd | ||
|
|
20f28b3d2c | ||
|
|
f3f63ab8aa | ||
|
|
e91090cfff | ||
|
|
1a7fb3c13e | ||
|
|
59857ed79d | ||
|
|
4797665939 | ||
|
|
b89749036d | ||
|
|
c6268488de | ||
|
|
de04369703 | ||
|
|
05b6f19a87 | ||
|
|
2753df8216 |
33
Moose Development/Moose/.lua-format
Normal file
33
Moose Development/Moose/.lua-format
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# See https://github.com/Koihik/LuaFormatter
|
||||||
|
# Use '-- LuaFormatter off' and '-- LuaFormatter on' around code blocks to inhibit formatting
|
||||||
|
|
||||||
|
column_limit: 500
|
||||||
|
indent_width: 2
|
||||||
|
use_tab: false
|
||||||
|
continuation_indent_width: 2
|
||||||
|
keep_simple_control_block_one_line: false
|
||||||
|
keep_simple_function_one_line: false
|
||||||
|
align_args: true
|
||||||
|
break_after_functioncall_lp: false
|
||||||
|
break_before_functioncall_rp: false
|
||||||
|
align_parameter: true
|
||||||
|
chop_down_parameter: true
|
||||||
|
break_after_functiondef_lp: false
|
||||||
|
break_before_functiondef_rp: false
|
||||||
|
align_table_field: true
|
||||||
|
break_after_table_lb: true
|
||||||
|
break_before_table_rb: true
|
||||||
|
chop_down_table: true
|
||||||
|
chop_down_kv_table: true
|
||||||
|
column_table_limit: 500
|
||||||
|
table_sep: ','
|
||||||
|
extra_sep_at_table_end: true
|
||||||
|
break_after_operator: true
|
||||||
|
single_quote_to_double_quote: false
|
||||||
|
double_quote_to_single_quote: false
|
||||||
|
spaces_before_call: 1
|
||||||
|
spaces_inside_functiondef_parens: true
|
||||||
|
spaces_inside_functioncall_parens: true
|
||||||
|
spaces_inside_table_braces: true
|
||||||
|
spaces_around_equals_in_field: true
|
||||||
|
line_breaks_after_function_body: 1
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -585,7 +585,7 @@ function AI_AIR:onafterRTB( AIGroup, From, Event, To )
|
|||||||
|
|
||||||
if AIGroup and AIGroup:IsAlive() then
|
if AIGroup and AIGroup:IsAlive() then
|
||||||
|
|
||||||
self:I( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" )
|
self:T( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" )
|
||||||
|
|
||||||
self:ClearTargetDistance()
|
self:ClearTargetDistance()
|
||||||
--AIGroup:ClearTasks()
|
--AIGroup:ClearTasks()
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
-- * The construction and inheritance of MOOSE classes.
|
-- * The construction and inheritance of MOOSE classes.
|
||||||
-- * The class naming and numbering system.
|
-- * The class naming and numbering system.
|
||||||
-- * The class hierarchy search system.
|
-- * The class hierarchy search system.
|
||||||
-- * The tracing of information or objects during mission execution for debuggin purposes.
|
-- * The tracing of information or objects during mission execution for debugging purposes.
|
||||||
-- * The subscription to DCS events for event handling in MOOSE objects.
|
-- * The subscription to DCS events for event handling in MOOSE objects.
|
||||||
-- * Object inspection.
|
-- * Object inspection.
|
||||||
--
|
--
|
||||||
@@ -49,7 +49,8 @@ local _ClassID = 0
|
|||||||
-- # 2. Trace information for debugging.
|
-- # 2. Trace information for debugging.
|
||||||
--
|
--
|
||||||
-- The BASE class contains trace methods to trace progress within a mission execution of a certain object.
|
-- The BASE class contains trace methods to trace progress within a mission execution of a certain object.
|
||||||
-- These trace methods are inherited by each MOOSE class interiting BASE, soeach object created from derived class from BASE can use the tracing methods to trace its execution.
|
-- These trace methods are inherited by each MOOSE class inheriting BASE, thus all objects created from
|
||||||
|
-- a class derived from BASE can use the tracing methods to trace its execution.
|
||||||
--
|
--
|
||||||
-- Any type of information can be passed to these tracing methods. See the following examples:
|
-- Any type of information can be passed to these tracing methods. See the following examples:
|
||||||
--
|
--
|
||||||
@@ -111,7 +112,6 @@ local _ClassID = 0
|
|||||||
--
|
--
|
||||||
-- The method @{#BASE.IsTrace}() will validate if tracing is activated or not.
|
-- The method @{#BASE.IsTrace}() will validate if tracing is activated or not.
|
||||||
--
|
--
|
||||||
--
|
|
||||||
-- # 3. DCS simulator Event Handling.
|
-- # 3. DCS simulator Event Handling.
|
||||||
--
|
--
|
||||||
-- The BASE class provides methods to catch DCS Events. These are events that are triggered from within the DCS simulator,
|
-- The BASE class provides methods to catch DCS Events. These are events that are triggered from within the DCS simulator,
|
||||||
@@ -157,8 +157,6 @@ local _ClassID = 0
|
|||||||
-- self:SmokeBlue()
|
-- self:SmokeBlue()
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
--
|
|
||||||
--
|
|
||||||
-- See the @{Event} module for more information about event handling.
|
-- See the @{Event} module for more information about event handling.
|
||||||
--
|
--
|
||||||
-- # 4. Class identification methods.
|
-- # 4. Class identification methods.
|
||||||
@@ -203,13 +201,12 @@ BASE = {
|
|||||||
Scheduler = nil,
|
Scheduler = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--- @field #BASE.__
|
--- @field #BASE.__
|
||||||
BASE.__ = {}
|
BASE.__ = {}
|
||||||
|
|
||||||
--- @field #BASE._
|
--- @field #BASE._
|
||||||
BASE._ = {
|
BASE._ = {
|
||||||
Schedules = {} --- Contains the Schedulers Active
|
Schedules = {}, --- Contains the Schedulers Active
|
||||||
}
|
}
|
||||||
|
|
||||||
--- The Formation Class
|
--- The Formation Class
|
||||||
@@ -217,11 +214,9 @@ BASE._ = {
|
|||||||
-- @field Cone A cone formation.
|
-- @field Cone A cone formation.
|
||||||
FORMATION = {
|
FORMATION = {
|
||||||
Cone = "Cone",
|
Cone = "Cone",
|
||||||
Vee = "Vee"
|
Vee = "Vee",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- BASE constructor.
|
--- BASE constructor.
|
||||||
--
|
--
|
||||||
-- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE.
|
-- This is an example how to use the BASE:New() constructor in a new class definition when inheriting from BASE.
|
||||||
@@ -241,9 +236,9 @@ function BASE:New()
|
|||||||
|
|
||||||
-- This is for "private" methods...
|
-- This is for "private" methods...
|
||||||
-- When a __ is passed to a method as "self", the __index will search for the method on the public method list too!
|
-- When a __ is passed to a method as "self", the __index will search for the method on the public method list too!
|
||||||
-- if rawget( self, "__" ) then
|
-- if rawget( self, "__" ) then
|
||||||
--setmetatable( self, { __index = self.__ } )
|
-- setmetatable( self, { __index = self.__ } )
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -269,13 +264,12 @@ function BASE:Inherit( Child, Parent )
|
|||||||
setmetatable( Child, { __index = Parent } )
|
setmetatable( Child, { __index = Parent } )
|
||||||
end
|
end
|
||||||
|
|
||||||
--Child:_SetDestructor()
|
-- Child:_SetDestructor()
|
||||||
end
|
end
|
||||||
|
|
||||||
return Child
|
return Child
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function getParent( Child )
|
local function getParent( Child )
|
||||||
local Parent = nil
|
local Parent = nil
|
||||||
|
|
||||||
@@ -291,7 +285,6 @@ local function getParent( Child )
|
|||||||
return Parent
|
return Parent
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- This is the worker method to retrieve the Parent class.
|
--- This is the worker method to retrieve the Parent class.
|
||||||
-- Note that the Parent class must be passed to call the parent class method.
|
-- Note that the Parent class must be passed to call the parent class method.
|
||||||
--
|
--
|
||||||
@@ -304,19 +297,18 @@ end
|
|||||||
-- @return #BASE
|
-- @return #BASE
|
||||||
function BASE:GetParent( Child, FromClass )
|
function BASE:GetParent( Child, FromClass )
|
||||||
|
|
||||||
|
|
||||||
local Parent
|
local Parent
|
||||||
-- BASE class has no parent
|
-- BASE class has no parent
|
||||||
if Child.ClassName == 'BASE' then
|
if Child.ClassName == 'BASE' then
|
||||||
Parent = nil
|
Parent = nil
|
||||||
else
|
else
|
||||||
|
|
||||||
--self:E({FromClass = FromClass})
|
-- self:E({FromClass = FromClass})
|
||||||
--self:E({Child = Child.ClassName})
|
-- self:E({Child = Child.ClassName})
|
||||||
if FromClass then
|
if FromClass then
|
||||||
while( Child.ClassName ~= "BASE" and Child.ClassName ~= FromClass.ClassName ) do
|
while (Child.ClassName ~= "BASE" and Child.ClassName ~= FromClass.ClassName) do
|
||||||
Child = getParent( Child )
|
Child = getParent( Child )
|
||||||
--self:E({Child.ClassName})
|
-- self:E({Child.ClassName})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if Child.ClassName == 'BASE' then
|
if Child.ClassName == 'BASE' then
|
||||||
@@ -325,7 +317,7 @@ function BASE:GetParent( Child, FromClass )
|
|||||||
Parent = getParent( Child )
|
Parent = getParent( Child )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--self:E({Parent.ClassName})
|
-- self:E({Parent.ClassName})
|
||||||
return Parent
|
return Parent
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -358,7 +350,7 @@ function BASE:IsInstanceOf( ClassName )
|
|||||||
else
|
else
|
||||||
|
|
||||||
-- I'm not sure if this should take advantage of MOOSE logging function, or throw an error for pcall
|
-- I'm not sure if this should take advantage of MOOSE logging function, or throw an error for pcall
|
||||||
local err_str = 'className parameter should be a string; parameter received: '..type( ClassName )
|
local err_str = 'className parameter should be a string; parameter received: ' .. type( ClassName )
|
||||||
self:E( err_str )
|
self:E( err_str )
|
||||||
-- error( err_str )
|
-- error( err_str )
|
||||||
return false
|
return false
|
||||||
@@ -372,7 +364,7 @@ function BASE:IsInstanceOf( ClassName )
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
local Parent = getParent(self)
|
local Parent = getParent( self )
|
||||||
|
|
||||||
while Parent do
|
while Parent do
|
||||||
|
|
||||||
@@ -419,7 +411,6 @@ do -- Event Handling
|
|||||||
return _EVENTDISPATCHER
|
return _EVENTDISPATCHER
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get the Class @{Event} processing Priority.
|
--- Get the Class @{Event} processing Priority.
|
||||||
-- The Event processing Priority is a number from 1 to 10,
|
-- The Event processing Priority is a number from 1 to 10,
|
||||||
-- reflecting the order of the classes subscribed to the Event to be processed.
|
-- reflecting the order of the classes subscribed to the Event to be processed.
|
||||||
@@ -474,35 +465,35 @@ do -- Event Handling
|
|||||||
|
|
||||||
-- Event handling function prototypes
|
-- Event handling function prototypes
|
||||||
|
|
||||||
--- Occurs whenever any unit in a mission fires a weapon. But not any machine gun or autocannon based weapon, those are handled by EVENT.ShootingStart.
|
--- Occurs whenever any unit in a mission fires a weapon. But not any machine gun or auto cannon based weapon, those are handled by EVENT.ShootingStart.
|
||||||
-- @function [parent=#BASE] OnEventShot
|
-- @function [parent=#BASE] OnEventShot
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs whenever an object is hit by a weapon.
|
--- Occurs whenever an object is hit by a weapon.
|
||||||
-- initiator : The unit object the fired the weapon
|
-- initiator : The unit object the fired the weapon.
|
||||||
-- weapon: Weapon object that hit the target
|
-- weapon: Weapon object that hit the target.
|
||||||
-- target: The Object that was hit.
|
-- target: The Object that was hit.
|
||||||
-- @function [parent=#BASE] OnEventHit
|
-- @function [parent=#BASE] OnEventHit
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when an aircraft takes off from an airbase, farp, or ship.
|
--- Occurs when an aircraft takes off from an airbase, farp, or ship.
|
||||||
-- initiator : The unit that tookoff
|
-- initiator : The unit that took off.
|
||||||
-- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships
|
-- place: Object from where the AI took-off from. Can be an Airbase Object, FARP, or Ships.
|
||||||
-- @function [parent=#BASE] OnEventTakeoff
|
-- @function [parent=#BASE] OnEventTakeoff
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when an aircraft lands at an airbase, farp or ship
|
--- Occurs when an aircraft lands at an airbase, farp or ship
|
||||||
-- initiator : The unit that has landed
|
-- initiator : The unit that has landed.
|
||||||
-- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships
|
-- place: Object that the unit landed on. Can be an Airbase Object, FARP, or Ships.
|
||||||
-- @function [parent=#BASE] OnEventLand
|
-- @function [parent=#BASE] OnEventLand
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when any aircraft crashes into the ground and is completely destroyed.
|
--- Occurs when any aircraft crashes into the ground and is completely destroyed.
|
||||||
-- initiator : The unit that has crashed
|
-- initiator : The unit that has crashed.
|
||||||
-- @function [parent=#BASE] OnEventCrash
|
-- @function [parent=#BASE] OnEventCrash
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
@@ -538,18 +529,18 @@ do -- Event Handling
|
|||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when a ground unit captures either an airbase or a farp.
|
--- Occurs when a ground unit captures either an airbase or a farp.
|
||||||
-- initiator : The unit that captured the base
|
-- initiator : The unit that captured the base.
|
||||||
-- place: The airbase that was captured, can be a FARP or Airbase. When calling place:getCoalition() the faction will already be the new owning faction.
|
-- place: The airbase that was captured, can be a FARP or Airbase. When calling place:getCoalition() the faction will already be the new owning faction.
|
||||||
-- @function [parent=#BASE] OnEventBaseCaptured
|
-- @function [parent=#BASE] OnEventBaseCaptured
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when a mission starts
|
--- Occurs when a mission starts.
|
||||||
-- @function [parent=#BASE] OnEventMissionStart
|
-- @function [parent=#BASE] OnEventMissionStart
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when a mission ends
|
--- Occurs when a mission ends.
|
||||||
-- @function [parent=#BASE] OnEventMissionEnd
|
-- @function [parent=#BASE] OnEventMissionEnd
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
@@ -561,25 +552,25 @@ do -- Event Handling
|
|||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when any object is spawned into the mission.
|
--- Occurs when any object is spawned into the mission.
|
||||||
-- initiator : The unit that was spawned
|
-- initiator : The unit that was spawned.
|
||||||
-- @function [parent=#BASE] OnEventBirth
|
-- @function [parent=#BASE] OnEventBirth
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when any system fails on a human controlled aircraft.
|
--- Occurs when any system fails on a human controlled aircraft.
|
||||||
-- initiator : The unit that had the failure
|
-- initiator : The unit that had the failure.
|
||||||
-- @function [parent=#BASE] OnEventHumanFailure
|
-- @function [parent=#BASE] OnEventHumanFailure
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when any aircraft starts its engines.
|
--- Occurs when any aircraft starts its engines.
|
||||||
-- initiator : The unit that is starting its engines.
|
-- initiator : The unit that is starting its engines..
|
||||||
-- @function [parent=#BASE] OnEventEngineStartup
|
-- @function [parent=#BASE] OnEventEngineStartup
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when any aircraft shuts down its engines.
|
--- Occurs when any aircraft shuts down its engines.
|
||||||
-- initiator : The unit that is stopping its engines.
|
-- initiator : The unit that is stopping its engines..
|
||||||
-- @function [parent=#BASE] OnEventEngineShutdown
|
-- @function [parent=#BASE] OnEventEngineShutdown
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
@@ -596,7 +587,7 @@ do -- Event Handling
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
--- Occurs when any unit begins firing a weapon that has a high rate of fire. Most common with aircraft cannons (GAU-8), autocannons, and machine guns.
|
--- Occurs when any unit begins firing a weapon that has a high rate of fire. Most common with aircraft cannons (GAU-8), auto cannons, and machine guns.
|
||||||
-- initiator : The unit that is doing the shooting.
|
-- initiator : The unit that is doing the shooting.
|
||||||
-- target: The unit that is being targeted.
|
-- target: The unit that is being targeted.
|
||||||
-- @function [parent=#BASE] OnEventShootingStart
|
-- @function [parent=#BASE] OnEventShootingStart
|
||||||
@@ -627,7 +618,6 @@ do -- Event Handling
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
|
|
||||||
--- Unknown precisely what creates this event, likely tied into newer damage model. Will update this page when new information become available.
|
--- Unknown precisely what creates this event, likely tied into newer damage model. Will update this page when new information become available.
|
||||||
--
|
--
|
||||||
-- * initiator: The unit that had the failure.
|
-- * initiator: The unit that had the failure.
|
||||||
@@ -644,7 +634,7 @@ do -- Event Handling
|
|||||||
|
|
||||||
--- Occurs on the death of a unit. Contains more and different information. Similar to unit_lost it will occur for aircraft before the aircraft crash event occurs.
|
--- Occurs on the death of a unit. Contains more and different information. Similar to unit_lost it will occur for aircraft before the aircraft crash event occurs.
|
||||||
--
|
--
|
||||||
-- * initiator: The unit that killed the target
|
-- * initiator: The unit that killed the target.
|
||||||
-- * target: Target Object
|
-- * target: Target Object
|
||||||
-- * weapon: Weapon Object
|
-- * weapon: Weapon Object
|
||||||
--
|
--
|
||||||
@@ -706,7 +696,6 @@ do -- Event Handling
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||||
|
|
||||||
|
|
||||||
--- Occurs when a player enters a slot and takes control of an aircraft.
|
--- Occurs when a player enters a slot and takes control of an aircraft.
|
||||||
-- **NOTE**: This is a workaround of a long standing DCS bug with the PLAYER_ENTER_UNIT event.
|
-- **NOTE**: This is a workaround of a long standing DCS bug with the PLAYER_ENTER_UNIT event.
|
||||||
-- initiator : The unit that is being taken control of.
|
-- initiator : The unit that is being taken control of.
|
||||||
@@ -716,7 +705,6 @@ do -- Event Handling
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Creation of a Birth Event.
|
--- Creation of a Birth Event.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param DCS#Time EventTime The time stamp of the event.
|
-- @param DCS#Time EventTime The time stamp of the event.
|
||||||
@@ -733,7 +721,7 @@ function BASE:CreateEventBirth( EventTime, Initiator, IniUnitName, place, subpla
|
|||||||
initiator = Initiator,
|
initiator = Initiator,
|
||||||
IniUnitName = IniUnitName,
|
IniUnitName = IniUnitName,
|
||||||
place = place,
|
place = place,
|
||||||
subplace = subplace
|
subplace = subplace,
|
||||||
}
|
}
|
||||||
|
|
||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
@@ -803,30 +791,30 @@ function BASE:CreateEventTakeoff( EventTime, Initiator )
|
|||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Creation of a `S_EVENT_PLAYER_ENTER_AIRCRAFT` event.
|
--- Creation of a `S_EVENT_PLAYER_ENTER_AIRCRAFT` event.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit The aircraft unit the player entered.
|
-- @param Wrapper.Unit#UNIT PlayerUnit The aircraft unit the player entered.
|
||||||
function BASE:CreateEventPlayerEnterAircraft( PlayerUnit )
|
function BASE:CreateEventPlayerEnterAircraft( PlayerUnit )
|
||||||
self:F( { PlayerUnit } )
|
self:F( { PlayerUnit } )
|
||||||
|
|
||||||
local Event = {
|
local Event = {
|
||||||
id = EVENTS.PlayerEnterAircraft,
|
id = EVENTS.PlayerEnterAircraft,
|
||||||
time = timer.getTime(),
|
time = timer.getTime(),
|
||||||
initiator = PlayerUnit:GetDCSObject()
|
initiator = PlayerUnit:GetDCSObject(),
|
||||||
}
|
}
|
||||||
|
|
||||||
world.onEvent(Event)
|
world.onEvent( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Complete DCS#Event structure.
|
-- TODO: Complete DCS#Event structure.
|
||||||
--- The main event handling function... This function captures all events generated for the class.
|
--- The main event handling function... This function captures all events generated for the class.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param DCS#Event event
|
-- @param DCS#Event event
|
||||||
function BASE:onEvent(event)
|
function BASE:onEvent( event )
|
||||||
|
|
||||||
if self then
|
if self then
|
||||||
|
|
||||||
for EventID, EventObject in pairs(self.Events) do
|
for EventID, EventObject in pairs( self.Events ) do
|
||||||
if EventObject.EventEnabled then
|
if EventObject.EventEnabled then
|
||||||
|
|
||||||
if event.id == EventObject.Event then
|
if event.id == EventObject.Event then
|
||||||
@@ -881,7 +869,7 @@ do -- Scheduling
|
|||||||
nil
|
nil
|
||||||
)
|
)
|
||||||
|
|
||||||
self._.Schedules[#self._.Schedules+1] = ScheduleID
|
self._.Schedules[#self._.Schedules + 1] = ScheduleID
|
||||||
|
|
||||||
return self._.Schedules[#self._.Schedules]
|
return self._.Schedules[#self._.Schedules]
|
||||||
end
|
end
|
||||||
@@ -919,7 +907,7 @@ do -- Scheduling
|
|||||||
4
|
4
|
||||||
)
|
)
|
||||||
|
|
||||||
self._.Schedules[#self._.Schedules+1] = ScheduleID
|
self._.Schedules[#self._.Schedules + 1] = ScheduleID
|
||||||
|
|
||||||
return self._.Schedules[#self._.Schedules]
|
return self._.Schedules[#self._.Schedules]
|
||||||
end
|
end
|
||||||
@@ -938,9 +926,8 @@ do -- Scheduling
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set a state or property of the Object given a Key and a Value.
|
--- Set a state or property of the Object given a Key and a Value.
|
||||||
-- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone.
|
-- Note that if the Object is destroyed, set to nil, or garbage collected, then the Values and Keys will also be gone.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Object The object that will hold the Value set by the Key.
|
-- @param Object The object that will hold the Value set by the Key.
|
||||||
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
|
-- @param Key The key that is used as a reference of the value. Note that the key can be a #string, but it can also be any other type!
|
||||||
@@ -956,9 +943,8 @@ function BASE:SetState( Object, Key, Value )
|
|||||||
return self.States[ClassNameAndID][Key]
|
return self.States[ClassNameAndID][Key]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get a Value given a Key from the Object.
|
--- Get a Value given a Key from the Object.
|
||||||
-- Note that if the Object is destroyed, nillified or garbage collected, then the Values and Keys will also be gone.
|
-- Note that if the Object is destroyed, set to nil, or garbage collected, then the Values and Keys will also be gone.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Object The object that holds the Value set by the Key.
|
-- @param Object The object that holds the Value set by the Key.
|
||||||
-- @param Key The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type!
|
-- @param Key The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type!
|
||||||
@@ -1010,8 +996,6 @@ function BASE:TraceOff()
|
|||||||
self:TraceOnOff( false )
|
self:TraceOnOff( false )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Set trace on or off
|
--- Set trace on or off
|
||||||
-- Note that when trace is off, no BASE.Debug statement is performed, increasing performance!
|
-- Note that when trace is off, no BASE.Debug statement is performed, increasing performance!
|
||||||
-- When Moose is loaded statically, (as one file), tracing is switched off by default.
|
-- When Moose is loaded statically, (as one file), tracing is switched off by default.
|
||||||
@@ -1020,13 +1004,15 @@ end
|
|||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param #boolean TraceOnOff Switch the tracing on or off.
|
-- @param #boolean TraceOnOff Switch the tracing on or off.
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Switch the tracing On
|
-- -- Switch the tracing On
|
||||||
-- BASE:TraceOnOff( true )
|
-- BASE:TraceOnOff( true )
|
||||||
--
|
--
|
||||||
-- -- Switch the tracing Off
|
-- -- Switch the tracing Off
|
||||||
-- BASE:TraceOnOff( false )
|
-- BASE:TraceOnOff( false )
|
||||||
|
--
|
||||||
function BASE:TraceOnOff( TraceOnOff )
|
function BASE:TraceOnOff( TraceOnOff )
|
||||||
if TraceOnOff==false then
|
if TraceOnOff == false then
|
||||||
self:I( "Tracing in MOOSE is OFF" )
|
self:I( "Tracing in MOOSE is OFF" )
|
||||||
_TraceOnOff = false
|
_TraceOnOff = false
|
||||||
else
|
else
|
||||||
@@ -1035,13 +1021,12 @@ function BASE:TraceOnOff( TraceOnOff )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Enquires if tracing is on (for the class).
|
--- Enquires if tracing is on (for the class).
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function BASE:IsTrace()
|
function BASE:IsTrace()
|
||||||
|
|
||||||
if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
if BASE.Debug and (_TraceAll == true) or (_TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName]) then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@@ -1061,8 +1046,8 @@ end
|
|||||||
-- @param #boolean TraceAll true = trace all methods in MOOSE.
|
-- @param #boolean TraceAll true = trace all methods in MOOSE.
|
||||||
function BASE:TraceAll( TraceAll )
|
function BASE:TraceAll( TraceAll )
|
||||||
|
|
||||||
if TraceAll==false then
|
if TraceAll == false then
|
||||||
_TraceAll=false
|
_TraceAll = false
|
||||||
else
|
else
|
||||||
_TraceAll = true
|
_TraceAll = true
|
||||||
end
|
end
|
||||||
@@ -1101,7 +1086,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
||||||
|
|
||||||
if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
if BASE.Debug and (_TraceAll == true) or (_TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName]) then
|
||||||
|
|
||||||
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" )
|
||||||
@@ -1120,7 +1105,7 @@ function BASE:_F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
|||||||
if DebugInfoFrom then
|
if DebugInfoFrom then
|
||||||
LineFrom = DebugInfoFrom.currentline
|
LineFrom = DebugInfoFrom.currentline
|
||||||
end
|
end
|
||||||
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1140,7 +1125,6 @@ function BASE:F( Arguments )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Trace a function call level 2. Must be at the beginning of the function logic.
|
--- Trace a function call level 2. Must be at the beginning of the function logic.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
@@ -1176,7 +1160,7 @@ end
|
|||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
||||||
|
|
||||||
if BASE.Debug and ( _TraceAll == true ) or ( _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName] ) then
|
if BASE.Debug and (_TraceAll == true) or (_TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName]) then
|
||||||
|
|
||||||
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" )
|
local DebugInfoCurrent = DebugInfoCurrentParam and DebugInfoCurrentParam or BASE.Debug.getinfo( 2, "nl" )
|
||||||
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" )
|
local DebugInfoFrom = DebugInfoFromParam and DebugInfoFromParam or BASE.Debug.getinfo( 3, "l" )
|
||||||
@@ -1195,7 +1179,7 @@ function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
|
|||||||
if DebugInfoFrom then
|
if DebugInfoFrom then
|
||||||
LineFrom = DebugInfoFrom.currentline
|
LineFrom = DebugInfoFrom.currentline
|
||||||
end
|
end
|
||||||
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s", LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1215,7 +1199,6 @@ function BASE:T( Arguments )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Trace a function logic level 2. Can be anywhere within the function logic.
|
--- Trace a function logic level 2. Can be anywhere within the function logic.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
@@ -1266,14 +1249,13 @@ function BASE:E( Arguments )
|
|||||||
LineFrom = DebugInfoFrom.currentline
|
LineFrom = DebugInfoFrom.currentline
|
||||||
end
|
end
|
||||||
|
|
||||||
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
else
|
else
|
||||||
env.info( string.format( "%1s:%30s%05d(%s)" , "E", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
env.info( string.format( "%1s:%30s%05d(%s)", "E", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Log an information which will be traced always. Can be anywhere within the function logic.
|
--- Log an information which will be traced always. Can be anywhere within the function logic.
|
||||||
-- @param #BASE self
|
-- @param #BASE self
|
||||||
-- @param Arguments A #table or any field.
|
-- @param Arguments A #table or any field.
|
||||||
@@ -1294,26 +1276,23 @@ function BASE:I( Arguments )
|
|||||||
LineFrom = DebugInfoFrom.currentline
|
LineFrom = DebugInfoFrom.currentline
|
||||||
end
|
end
|
||||||
|
|
||||||
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)" , LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
env.info( string.format( "%6d(%6d)/%1s:%30s%05d.%s(%s)", LineCurrent, LineFrom, "I", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
else
|
else
|
||||||
env.info( string.format( "%1s:%30s%05d(%s)" , "I", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
env.info( string.format( "%1s:%30s%05d(%s)", "I", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- old stuff
|
--- old stuff
|
||||||
|
|
||||||
--function BASE:_Destructor()
|
-- function BASE:_Destructor()
|
||||||
-- --self:E("_Destructor")
|
-- --self:E("_Destructor")
|
||||||
--
|
--
|
||||||
-- --self:EventRemoveAll()
|
-- --self:EventRemoveAll()
|
||||||
--end
|
-- end
|
||||||
|
|
||||||
|
|
||||||
-- THIS IS WHY WE NEED LUA 5.2 ...
|
-- THIS IS WHY WE NEED LUA 5.2 ...
|
||||||
--function BASE:_SetDestructor()
|
-- function BASE:_SetDestructor()
|
||||||
--
|
--
|
||||||
-- -- TODO: Okay, this is really technical...
|
-- -- TODO: Okay, this is really technical...
|
||||||
-- -- When you set a proxy to a table to catch __gc, weak tables don't behave like weak...
|
-- -- When you set a proxy to a table to catch __gc, weak tables don't behave like weak...
|
||||||
@@ -1334,4 +1313,4 @@ end
|
|||||||
-- -- will be invoked and the destructor called
|
-- -- will be invoked and the destructor called
|
||||||
-- rawset( self, '__proxy', proxy )
|
-- rawset( self, '__proxy', proxy )
|
||||||
--
|
--
|
||||||
--end
|
-- end
|
||||||
|
|||||||
@@ -95,11 +95,11 @@ BEACON.Type={
|
|||||||
-- @field #number TACAN TACtical Air Navigation system on ground.
|
-- @field #number TACAN TACtical Air Navigation system on ground.
|
||||||
-- @field #number TACAN_TANKER_X TACtical Air Navigation system for tankers on X band.
|
-- @field #number TACAN_TANKER_X TACtical Air Navigation system for tankers on X band.
|
||||||
-- @field #number TACAN_TANKER_Y TACtical Air Navigation system for tankers on Y band.
|
-- @field #number TACAN_TANKER_Y TACtical Air Navigation system for tankers on Y band.
|
||||||
-- @field #number VOR Very High Frequency Omni-Directional Range
|
-- @field #number VOR Very High Frequency Omnidirectional Range
|
||||||
-- @field #number ILS_LOCALIZER ILS localizer
|
-- @field #number ILS_LOCALIZER ILS localizer
|
||||||
-- @field #number ILS_GLIDESLOPE ILS glideslope.
|
-- @field #number ILS_GLIDESLOPE ILS glide slope.
|
||||||
-- @field #number PRGM_LOCALIZER PRGM localizer.
|
-- @field #number PRGM_LOCALIZER PRGM localizer.
|
||||||
-- @field #number PRGM_GLIDESLOPE PRGM glideslope.
|
-- @field #number PRGM_GLIDESLOPE PRGM glide slope.
|
||||||
-- @field #number BROADCAST_STATION Broadcast station.
|
-- @field #number BROADCAST_STATION Broadcast station.
|
||||||
-- @field #number VORTAC Radio-based navigational aid for aircraft pilots consisting of a co-located VHF omnidirectional range (VOR) beacon and a tactical air navigation system (TACAN) beacon.
|
-- @field #number VORTAC Radio-based navigational aid for aircraft pilots consisting of a co-located VHF omnidirectional range (VOR) beacon and a tactical air navigation system (TACAN) beacon.
|
||||||
-- @field #number TACAN_AA_MODE_X TACtical Air Navigation for aircraft on X band.
|
-- @field #number TACAN_AA_MODE_X TACtical Air Navigation for aircraft on X band.
|
||||||
@@ -131,28 +131,27 @@ BEACON.System={
|
|||||||
-- If you want to create a BEACON, you probably should use @{Wrapper.Positionable#POSITIONABLE.GetBeacon}() instead.
|
-- If you want to create a BEACON, you probably should use @{Wrapper.Positionable#POSITIONABLE.GetBeacon}() instead.
|
||||||
-- @param #BEACON self
|
-- @param #BEACON self
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Positionable} that will receive radio capabilities.
|
-- @param Wrapper.Positionable#POSITIONABLE Positionable The @{Positionable} that will receive radio capabilities.
|
||||||
-- @return #BEACON Beacon object or #nil if the positionable is invalid.
|
-- @return #BEACON Beacon object or #nil if the POSITIONABLE is invalid.
|
||||||
function BEACON:New(Positionable)
|
function BEACON:New( Positionable )
|
||||||
|
|
||||||
-- Inherit BASE.
|
-- Inherit BASE.
|
||||||
local self=BASE:Inherit(self, BASE:New()) --#BEACON
|
local self = BASE:Inherit( self, BASE:New() ) -- #BEACON
|
||||||
|
|
||||||
-- Debug.
|
-- Debug.
|
||||||
self:F(Positionable)
|
self:F( Positionable )
|
||||||
|
|
||||||
-- Set positionable.
|
-- Set positionable.
|
||||||
if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure positionable is valid
|
if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure POSITIONABLE is valid
|
||||||
self.Positionable = Positionable
|
self.Positionable = Positionable
|
||||||
self.name=Positionable:GetName()
|
self.name = Positionable:GetName()
|
||||||
self:I(string.format("New BEACON %s", tostring(self.name)))
|
self:I( string.format( "New BEACON %s", tostring( self.name ) ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
self:E({"The passed positionable is invalid, no BEACON created", Positionable})
|
self:E( { "The passed POSITIONABLE is invalid, no BEACON created", Positionable } )
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Activates a TACAN BEACON.
|
--- Activates a TACAN BEACON.
|
||||||
-- @param #BEACON self
|
-- @param #BEACON self
|
||||||
-- @param #number Channel TACAN channel, i.e. the "10" part in "10Y".
|
-- @param #number Channel TACAN channel, i.e. the "10" part in "10Y".
|
||||||
@@ -162,51 +161,53 @@ end
|
|||||||
-- @param #number Duration How long will the beacon last in seconds. Omit for forever.
|
-- @param #number Duration How long will the beacon last in seconds. Omit for forever.
|
||||||
-- @return #BEACON self
|
-- @return #BEACON self
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Let's create a TACAN Beacon for a tanker
|
-- -- Let's create a TACAN Beacon for a tanker
|
||||||
-- local myUnit = UNIT:FindByName("MyUnit")
|
-- local myUnit = UNIT:FindByName("MyUnit")
|
||||||
-- local myBeacon = myUnit:GetBeacon() -- Creates the beacon
|
-- local myBeacon = myUnit:GetBeacon() -- Creates the beacon
|
||||||
--
|
--
|
||||||
-- myBeacon:ActivateTACAN(20, "Y", "TEXACO", true) -- Activate the beacon
|
-- myBeacon:ActivateTACAN(20, "Y", "TEXACO", true) -- Activate the beacon
|
||||||
function BEACON:ActivateTACAN(Channel, Mode, Message, Bearing, Duration)
|
--
|
||||||
self:T({channel=Channel, mode=Mode, callsign=Message, bearing=Bearing, duration=Duration})
|
function BEACON:ActivateTACAN( Channel, Mode, Message, Bearing, Duration )
|
||||||
|
self:T( { channel = Channel, mode = Mode, callsign = Message, bearing = Bearing, duration = Duration } )
|
||||||
|
|
||||||
-- Get frequency.
|
-- Get frequency.
|
||||||
local Frequency=UTILS.TACANToFrequency(Channel, Mode)
|
local Frequency = UTILS.TACANToFrequency( Channel, Mode )
|
||||||
|
|
||||||
-- Check.
|
-- Check.
|
||||||
if not Frequency then
|
if not Frequency then
|
||||||
self:E({"The passed TACAN channel is invalid, the BEACON is not emitting"})
|
self:E( { "The passed TACAN channel is invalid, the BEACON is not emitting" } )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Beacon type.
|
-- Beacon type.
|
||||||
local Type=BEACON.Type.TACAN
|
local Type = BEACON.Type.TACAN
|
||||||
|
|
||||||
-- Beacon system.
|
-- Beacon system.
|
||||||
local System=BEACON.System.TACAN
|
local System = BEACON.System.TACAN
|
||||||
|
|
||||||
-- Check if unit is an aircraft and set system accordingly.
|
-- Check if unit is an aircraft and set system accordingly.
|
||||||
local AA=self.Positionable:IsAir()
|
local AA = self.Positionable:IsAir()
|
||||||
if AA then
|
if AA then
|
||||||
System=5 --NOTE: 5 is how you cat the correct tanker behaviour! --BEACON.System.TACAN_TANKER
|
System = 5 -- NOTE: 5 is how you cat the correct tanker behaviour! --BEACON.System.TACAN_TANKER
|
||||||
-- Check if "Y" mode is selected for aircraft.
|
-- Check if "Y" mode is selected for aircraft.
|
||||||
if Mode~="Y" then
|
if Mode ~= "Y" then
|
||||||
self:E({"WARNING: The POSITIONABLE you want to attach the AA Tacan Beacon is an aircraft: Mode should Y !The BEACON is not emitting.", self.Positionable})
|
self:E( { "WARNING: The POSITIONABLE you want to attach the AA TACAN Beacon is an aircraft: Mode should Y! The BEACON is not emitting.", self.Positionable } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Attached unit.
|
-- Attached unit.
|
||||||
local UnitID=self.Positionable:GetID()
|
local UnitID = self.Positionable:GetID()
|
||||||
|
|
||||||
-- Debug.
|
-- Debug.
|
||||||
self:I({string.format("BEACON Activating TACAN %s: Channel=%d%s, Morse=%s, Bearing=%s, Duration=%s!", tostring(self.name), Channel, Mode, Message, tostring(Bearing), tostring(Duration))})
|
self:I( { string.format( "BEACON Activating TACAN %s: Channel=%d%s, Morse=%s, Bearing=%s, Duration=%s!", tostring( self.name ), Channel, Mode, Message, tostring( Bearing ), tostring( Duration ) ) } )
|
||||||
|
|
||||||
-- Start beacon.
|
-- Start beacon.
|
||||||
self.Positionable:CommandActivateBeacon(Type, System, Frequency, UnitID, Channel, Mode, AA, Message, Bearing)
|
self.Positionable:CommandActivateBeacon( Type, System, Frequency, UnitID, Channel, Mode, AA, Message, Bearing )
|
||||||
|
|
||||||
-- Stop sheduler.
|
-- Stop scheduler.
|
||||||
if Duration then
|
if Duration then
|
||||||
self.Positionable:DeactivateBeacon(Duration)
|
self.Positionable:DeactivateBeacon( Duration )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -218,21 +219,21 @@ end
|
|||||||
-- @param #string Callsign The Message that is going to be coded in Morse and broadcasted by the beacon.
|
-- @param #string Callsign The Message that is going to be coded in Morse and broadcasted by the beacon.
|
||||||
-- @param #number Duration How long will the beacon last in seconds. Omit for forever.
|
-- @param #number Duration How long will the beacon last in seconds. Omit for forever.
|
||||||
-- @return #BEACON self
|
-- @return #BEACON self
|
||||||
function BEACON:ActivateICLS(Channel, Callsign, Duration)
|
function BEACON:ActivateICLS( Channel, Callsign, Duration )
|
||||||
self:F({Channel=Channel, Callsign=Callsign, Duration=Duration})
|
self:F( { Channel = Channel, Callsign = Callsign, Duration = Duration } )
|
||||||
|
|
||||||
-- Attached unit.
|
-- Attached unit.
|
||||||
local UnitID=self.Positionable:GetID()
|
local UnitID = self.Positionable:GetID()
|
||||||
|
|
||||||
-- Debug
|
-- Debug
|
||||||
self:T2({"ICLS BEACON started!"})
|
self:T2( { "ICLS BEACON started!" } )
|
||||||
|
|
||||||
-- Start beacon.
|
-- Start beacon.
|
||||||
self.Positionable:CommandActivateICLS(Channel, UnitID, Callsign)
|
self.Positionable:CommandActivateICLS( Channel, UnitID, Callsign )
|
||||||
|
|
||||||
-- Stop sheduler
|
-- Stop scheduler
|
||||||
if Duration then -- Schedule the stop of the BEACON if asked by the MD
|
if Duration then -- Schedule the stop of the BEACON if asked by the MD
|
||||||
self.Positionable:DeactivateBeacon(Duration)
|
self.Positionable:DeactivateBeacon( Duration )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -246,24 +247,26 @@ end
|
|||||||
-- @param #number BeaconDuration How long will the beacon last in seconds. Omit for forever.
|
-- @param #number BeaconDuration How long will the beacon last in seconds. Omit for forever.
|
||||||
-- @return #BEACON self
|
-- @return #BEACON self
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Let's create a TACAN Beacon for a tanker
|
-- -- Let's create a TACAN Beacon for a tanker
|
||||||
-- local myUnit = UNIT:FindByName("MyUnit")
|
-- local myUnit = UNIT:FindByName("MyUnit")
|
||||||
-- local myBeacon = myUnit:GetBeacon() -- Creates the beacon
|
-- local myBeacon = myUnit:GetBeacon() -- Creates the beacon
|
||||||
--
|
--
|
||||||
-- myBeacon:AATACAN(20, "TEXACO", true) -- Activate the beacon
|
-- myBeacon:AATACAN(20, "TEXACO", true) -- Activate the beacon
|
||||||
function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
|
--
|
||||||
self:F({TACANChannel, Message, Bearing, BeaconDuration})
|
function BEACON:AATACAN( TACANChannel, Message, Bearing, BeaconDuration )
|
||||||
|
self:F( { TACANChannel, Message, Bearing, BeaconDuration } )
|
||||||
|
|
||||||
local IsValid = true
|
local IsValid = true
|
||||||
|
|
||||||
if not self.Positionable:IsAir() then
|
if not self.Positionable:IsAir() then
|
||||||
self:E({"The POSITIONABLE you want to attach the AA Tacan Beacon is not an aircraft ! The BEACON is not emitting", self.Positionable})
|
self:E( { "The POSITIONABLE you want to attach the AA TACAN Beacon is not an aircraft! The BEACON is not emitting", self.Positionable } )
|
||||||
IsValid = false
|
IsValid = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local Frequency = self:_TACANToFrequency(TACANChannel, "Y")
|
local Frequency = self:_TACANToFrequency( TACANChannel, "Y" )
|
||||||
if not Frequency then
|
if not Frequency then
|
||||||
self:E({"The passed TACAN channel is invalid, the BEACON is not emitting"})
|
self:E( { "The passed TACAN channel is invalid, the BEACON is not emitting" } )
|
||||||
IsValid = false
|
IsValid = false
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -277,22 +280,21 @@ function BEACON:AATACAN(TACANChannel, Message, Bearing, BeaconDuration)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if IsValid then -- Starts the BEACON
|
if IsValid then -- Starts the BEACON
|
||||||
self:T2({"AA TACAN BEACON started !"})
|
self:T2( { "AA TACAN BEACON started !" } )
|
||||||
self.Positionable:SetCommand({
|
self.Positionable:SetCommand( {
|
||||||
id = "ActivateBeacon",
|
id = "ActivateBeacon",
|
||||||
params = {
|
params = {
|
||||||
type = 4,
|
type = 4,
|
||||||
system = System,
|
system = System,
|
||||||
callsign = Message,
|
callsign = Message,
|
||||||
frequency = Frequency,
|
frequency = Frequency,
|
||||||
}
|
},
|
||||||
})
|
} )
|
||||||
|
|
||||||
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
|
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
|
||||||
SCHEDULER:New(nil,
|
SCHEDULER:New( nil, function()
|
||||||
function()
|
|
||||||
self:StopAATACAN()
|
self:StopAATACAN()
|
||||||
end, {}, BeaconDuration)
|
end, {}, BeaconDuration )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -305,18 +307,16 @@ end
|
|||||||
function BEACON:StopAATACAN()
|
function BEACON:StopAATACAN()
|
||||||
self:F()
|
self:F()
|
||||||
if not self.Positionable then
|
if not self.Positionable then
|
||||||
self:E({"Start the beacon first before stoping it !"})
|
self:E( { "Start the beacon first before stopping it!" } )
|
||||||
else
|
else
|
||||||
self.Positionable:SetCommand({
|
self.Positionable:SetCommand( {
|
||||||
id = 'DeactivateBeacon',
|
id = 'DeactivateBeacon',
|
||||||
params = {
|
params = {},
|
||||||
}
|
} )
|
||||||
})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Activates a general purpose Radio Beacon
|
||||||
--- Activates a general pupose Radio Beacon
|
|
||||||
-- This uses the very generic singleton function "trigger.action.radioTransmission()" provided by DCS to broadcast a sound file on a specific frequency.
|
-- This uses the very generic singleton function "trigger.action.radioTransmission()" provided by DCS to broadcast a sound file on a specific frequency.
|
||||||
-- Although any frequency could be used, only 2 DCS Modules can home on radio beacons at the time of writing : the Huey and the Mi-8.
|
-- Although any frequency could be used, only 2 DCS Modules can home on radio beacons at the time of writing : the Huey and the Mi-8.
|
||||||
-- They can home in on these specific frequencies :
|
-- They can home in on these specific frequencies :
|
||||||
@@ -342,53 +342,52 @@ end
|
|||||||
--
|
--
|
||||||
-- -- Set the beacon and start it
|
-- -- Set the beacon and start it
|
||||||
-- UnitBeacon:RadioBeacon("MySoundFileSOS.ogg", 40, radio.modulation.FM, 20, 5*60)
|
-- UnitBeacon:RadioBeacon("MySoundFileSOS.ogg", 40, radio.modulation.FM, 20, 5*60)
|
||||||
function BEACON:RadioBeacon(FileName, Frequency, Modulation, Power, BeaconDuration)
|
function BEACON:RadioBeacon( FileName, Frequency, Modulation, Power, BeaconDuration )
|
||||||
self:F({FileName, Frequency, Modulation, Power, BeaconDuration})
|
self:F( { FileName, Frequency, Modulation, Power, BeaconDuration } )
|
||||||
local IsValid = false
|
local IsValid = false
|
||||||
|
|
||||||
-- Check the filename
|
-- Check the filename
|
||||||
if type(FileName) == "string" then
|
if type( FileName ) == "string" then
|
||||||
if FileName:find(".ogg") or FileName:find(".wav") then
|
if FileName:find( ".ogg" ) or FileName:find( ".wav" ) then
|
||||||
if not FileName:find("l10n/DEFAULT/") then
|
if not FileName:find( "l10n/DEFAULT/" ) then
|
||||||
FileName = "l10n/DEFAULT/" .. FileName
|
FileName = "l10n/DEFAULT/" .. FileName
|
||||||
end
|
end
|
||||||
IsValid = true
|
IsValid = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not IsValid then
|
if not IsValid then
|
||||||
self:E({"File name invalid. Maybe something wrong with the extension ? ", FileName})
|
self:E( { "File name invalid. Maybe something wrong with the extension? ", FileName } )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check the Frequency
|
-- Check the Frequency
|
||||||
if type(Frequency) ~= "number" and IsValid then
|
if type( Frequency ) ~= "number" and IsValid then
|
||||||
self:E({"Frequency invalid. ", Frequency})
|
self:E( { "Frequency invalid. ", Frequency } )
|
||||||
IsValid = false
|
IsValid = false
|
||||||
end
|
end
|
||||||
Frequency = Frequency * 1000000 -- Conversion to Hz
|
Frequency = Frequency * 1000000 -- Conversion to Hz
|
||||||
|
|
||||||
-- Check the modulation
|
-- Check the modulation
|
||||||
if Modulation ~= radio.modulation.AM and Modulation ~= radio.modulation.FM and IsValid then --TODO Maybe make this future proof if ED decides to add an other modulation ?
|
if Modulation ~= radio.modulation.AM and Modulation ~= radio.modulation.FM and IsValid then -- TODO: Maybe make this future proof if ED decides to add an other modulation ?
|
||||||
self:E({"Modulation is invalid. Use DCS's enum radio.modulation.", Modulation})
|
self:E( { "Modulation is invalid. Use DCS's enum radio.modulation.", Modulation } )
|
||||||
IsValid = false
|
IsValid = false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check the Power
|
-- Check the Power
|
||||||
if type(Power) ~= "number" and IsValid then
|
if type( Power ) ~= "number" and IsValid then
|
||||||
self:E({"Power is invalid. ", Power})
|
self:E( { "Power is invalid. ", Power } )
|
||||||
IsValid = false
|
IsValid = false
|
||||||
end
|
end
|
||||||
Power = math.floor(math.abs(Power)) --TODO Find what is the maximum power allowed by DCS and limit power to that
|
Power = math.floor( math.abs( Power ) ) -- TODO: Find what is the maximum power allowed by DCS and limit power to that
|
||||||
|
|
||||||
if IsValid then
|
if IsValid then
|
||||||
self:T2({"Activating Beacon on ", Frequency, Modulation})
|
self:T2( { "Activating Beacon on ", Frequency, Modulation } )
|
||||||
-- Note that this is looped. I have to give this transmission a unique name, I use the class ID
|
-- Note that this is looped. I have to give this transmission a unique name, I use the class ID
|
||||||
trigger.action.radioTransmission(FileName, self.Positionable:GetPositionVec3(), Modulation, true, Frequency, Power, tostring(self.ID))
|
trigger.action.radioTransmission( FileName, self.Positionable:GetPositionVec3(), Modulation, true, Frequency, Power, tostring( self.ID ) )
|
||||||
|
|
||||||
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
|
if BeaconDuration then -- Schedule the stop of the BEACON if asked by the MD
|
||||||
SCHEDULER:New( nil,
|
SCHEDULER:New( nil, function()
|
||||||
function()
|
|
||||||
self:StopRadioBeacon()
|
self:StopRadioBeacon()
|
||||||
end, {}, BeaconDuration)
|
end, {}, BeaconDuration )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -399,7 +398,7 @@ end
|
|||||||
function BEACON:StopRadioBeacon()
|
function BEACON:StopRadioBeacon()
|
||||||
self:F()
|
self:F()
|
||||||
-- The unique name of the transmission is the class ID
|
-- The unique name of the transmission is the class ID
|
||||||
trigger.action.stopRadioTransmission(tostring(self.ID))
|
trigger.action.stopRadioTransmission( tostring( self.ID ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -407,19 +406,19 @@ end
|
|||||||
-- @param #BEACON self
|
-- @param #BEACON self
|
||||||
-- @param #number TACANChannel
|
-- @param #number TACANChannel
|
||||||
-- @param #string TACANMode
|
-- @param #string TACANMode
|
||||||
-- @return #number Frequecy
|
-- @return #number Frequency
|
||||||
-- @return #nil if parameters are invalid
|
-- @return #nil if parameters are invalid
|
||||||
function BEACON:_TACANToFrequency(TACANChannel, TACANMode)
|
function BEACON:_TACANToFrequency( TACANChannel, TACANMode )
|
||||||
self:F3({TACANChannel, TACANMode})
|
self:F3( { TACANChannel, TACANMode } )
|
||||||
|
|
||||||
if type(TACANChannel) ~= "number" then
|
if type( TACANChannel ) ~= "number" then
|
||||||
if TACANMode ~= "X" and TACANMode ~= "Y" then
|
if TACANMode ~= "X" and TACANMode ~= "Y" then
|
||||||
return nil -- error in arguments
|
return nil -- error in arguments
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- This code is largely based on ED's code, in DCS World\Scripts\World\Radio\BeaconTypes.lua, line 137.
|
-- This code is largely based on ED's code, in DCS World\Scripts\World\Radio\BeaconTypes.lua, line 137.
|
||||||
-- I have no idea what it does but it seems to work
|
-- I have no idea what it does but it seems to work
|
||||||
local A = 1151 -- 'X', channel >= 64
|
local A = 1151 -- 'X', channel >= 64
|
||||||
local B = 64 -- channel >= 64
|
local B = 64 -- channel >= 64
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
-- @module Core.Database
|
-- @module Core.Database
|
||||||
-- @image Core_Database.JPG
|
-- @image Core_Database.JPG
|
||||||
|
|
||||||
|
|
||||||
--- @type DATABASE
|
--- @type DATABASE
|
||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
-- @field #table Templates Templates: Units, Groups, Statics, ClientsByName, ClientsByID.
|
-- @field #table Templates Templates: Units, Groups, Statics, ClientsByName, ClientsByID.
|
||||||
@@ -51,7 +50,7 @@
|
|||||||
-- * PLAYERS
|
-- * PLAYERS
|
||||||
-- * CARGOS
|
-- * CARGOS
|
||||||
--
|
--
|
||||||
-- On top, for internal MOOSE administration purposes, the DATBASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
|
-- On top, for internal MOOSE administration purposes, the DATABASE administers the Unit and Group TEMPLATES as defined within the Mission Editor.
|
||||||
--
|
--
|
||||||
-- The singleton object **_DATABASE** is automatically created by MOOSE, that administers all objects within the mission.
|
-- The singleton object **_DATABASE** is automatically created by MOOSE, that administers all objects within the mission.
|
||||||
-- Moose refers to **_DATABASE** within the framework extensively, but you can also refer to the _DATABASE object within your missions if required.
|
-- Moose refers to **_DATABASE** within the framework extensively, but you can also refer to the _DATABASE object within your missions if required.
|
||||||
@@ -90,22 +89,19 @@ DATABASE = {
|
|||||||
FLIGHTCONTROLS = {},
|
FLIGHTCONTROLS = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECoalition =
|
local _DATABASECoalition = {
|
||||||
{
|
|
||||||
[1] = "Red",
|
[1] = "Red",
|
||||||
[2] = "Blue",
|
[2] = "Blue",
|
||||||
[3] = "Neutral",
|
[3] = "Neutral",
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECategory =
|
local _DATABASECategory = {
|
||||||
{
|
|
||||||
["plane"] = Unit.Category.AIRPLANE,
|
["plane"] = Unit.Category.AIRPLANE,
|
||||||
["helicopter"] = Unit.Category.HELICOPTER,
|
["helicopter"] = Unit.Category.HELICOPTER,
|
||||||
["vehicle"] = Unit.Category.GROUND_UNIT,
|
["vehicle"] = Unit.Category.GROUND_UNIT,
|
||||||
["ship"] = Unit.Category.SHIP,
|
["ship"] = Unit.Category.SHIP,
|
||||||
["static"] = Unit.Category.STRUCTURE,
|
["static"] = Unit.Category.STRUCTURE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--- Creates a new DATABASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
--- Creates a new DATABASE object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
@@ -129,15 +125,15 @@ function DATABASE:New()
|
|||||||
self:HandleEvent( EVENTS.DeleteCargo )
|
self:HandleEvent( EVENTS.DeleteCargo )
|
||||||
self:HandleEvent( EVENTS.NewZone )
|
self:HandleEvent( EVENTS.NewZone )
|
||||||
self:HandleEvent( EVENTS.DeleteZone )
|
self:HandleEvent( EVENTS.DeleteZone )
|
||||||
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
-- self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit ) -- This is not working anymore!, handling this through the birth event.
|
||||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
||||||
|
|
||||||
self:_RegisterTemplates()
|
self:_RegisterTemplates()
|
||||||
self:_RegisterGroupsAndUnits()
|
self:_RegisterGroupsAndUnits()
|
||||||
self:_RegisterClients()
|
self:_RegisterClients()
|
||||||
self:_RegisterStatics()
|
self:_RegisterStatics()
|
||||||
self:_RegisterAirbases()
|
-- self:_RegisterAirbases()
|
||||||
--self:_RegisterPlayers()
|
-- self:_RegisterPlayers()
|
||||||
|
|
||||||
self.UNITS_Position = 0
|
self.UNITS_Position = 0
|
||||||
|
|
||||||
@@ -154,7 +150,6 @@ function DATABASE:FindUnit( UnitName )
|
|||||||
return UnitFound
|
return UnitFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Adds a Unit based on the Unit Name in the DATABASE.
|
--- Adds a Unit based on the Unit Name in the DATABASE.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string DCSUnitName Unit name.
|
-- @param #string DCSUnitName Unit name.
|
||||||
@@ -166,19 +161,18 @@ function DATABASE:AddUnit( DCSUnitName )
|
|||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T( { "Add UNIT:", DCSUnitName } )
|
self:T( { "Add UNIT:", DCSUnitName } )
|
||||||
|
|
||||||
--local UnitRegister = UNIT:Register( DCSUnitName )
|
-- local UnitRegister = UNIT:Register( DCSUnitName )
|
||||||
|
|
||||||
-- Register unit
|
-- Register unit
|
||||||
self.UNITS[DCSUnitName]=UNIT:Register(DCSUnitName)
|
self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName )
|
||||||
|
|
||||||
-- This is not used anywhere in MOOSE as far as I can see so I remove it until there comes an error somewhere.
|
-- This is not used anywhere in MOOSE as far as I can see so I remove it until there comes an error somewhere.
|
||||||
--table.insert(self.UNITS_Index, DCSUnitName )
|
-- table.insert(self.UNITS_Index, DCSUnitName )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.UNITS[DCSUnitName]
|
return self.UNITS[DCSUnitName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Deletes a Unit from the DATABASE based on the Unit Name.
|
--- Deletes a Unit from the DATABASE based on the Unit Name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
function DATABASE:DeleteUnit( DCSUnitName )
|
function DATABASE:DeleteUnit( DCSUnitName )
|
||||||
@@ -200,7 +194,6 @@ function DATABASE:AddStatic( DCSStaticName )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Deletes a Static from the DATABASE based on the Static Name.
|
--- Deletes a Static from the DATABASE based on the Static Name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
function DATABASE:DeleteStatic( DCSStaticName )
|
function DATABASE:DeleteStatic( DCSStaticName )
|
||||||
@@ -240,7 +233,6 @@ function DATABASE:AddAirbase( AirbaseName )
|
|||||||
return self.AIRBASES[AirbaseName]
|
return self.AIRBASES[AirbaseName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Deletes a Airbase from the DATABASE based on the Airbase Name.
|
--- Deletes a Airbase from the DATABASE based on the Airbase Name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string AirbaseName The name of the airbase
|
-- @param #string AirbaseName The name of the airbase
|
||||||
@@ -259,7 +251,6 @@ function DATABASE:FindAirbase( AirbaseName )
|
|||||||
return AirbaseFound
|
return AirbaseFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- Zones
|
do -- Zones
|
||||||
|
|
||||||
--- Finds a @{Zone} based on the zone name.
|
--- Finds a @{Zone} based on the zone name.
|
||||||
@@ -283,7 +274,6 @@ do -- Zones
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Deletes a @{Zone} from the DATABASE based on the zone name.
|
--- Deletes a @{Zone} from the DATABASE based on the zone name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string ZoneName The name of the zone.
|
-- @param #string ZoneName The name of the zone.
|
||||||
@@ -292,30 +282,29 @@ do -- Zones
|
|||||||
self.ZONES[ZoneName] = nil
|
self.ZONES[ZoneName] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Private method that registers new ZONE_BASE derived objects within the DATABASE Object.
|
--- Private method that registers new ZONE_BASE derived objects within the DATABASE Object.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
function DATABASE:_RegisterZones()
|
function DATABASE:_RegisterZones()
|
||||||
|
|
||||||
for ZoneID, ZoneData in pairs(env.mission.triggers.zones) do
|
for ZoneID, ZoneData in pairs( env.mission.triggers.zones ) do
|
||||||
local ZoneName = ZoneData.name
|
local ZoneName = ZoneData.name
|
||||||
|
|
||||||
-- Color
|
-- Color
|
||||||
local color=ZoneData.color or {1, 0, 0, 0.15}
|
local color = ZoneData.color or { 1, 0, 0, 0.15 }
|
||||||
|
|
||||||
-- Create new Zone
|
-- Create new Zone
|
||||||
local Zone=nil --Core.Zone#ZONE_BASE
|
local Zone = nil -- Core.Zone#ZONE_BASE
|
||||||
|
|
||||||
if ZoneData.type==0 then
|
if ZoneData.type == 0 then
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Circular zone
|
-- Circular zone
|
||||||
---
|
---
|
||||||
|
|
||||||
self:I(string.format("Register ZONE: %s (Circular)", ZoneName))
|
self:I( string.format( "Register ZONE: %s (Circular)", ZoneName ) )
|
||||||
|
|
||||||
Zone=ZONE:New(ZoneName)
|
Zone = ZONE:New( ZoneName )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
@@ -323,27 +312,27 @@ do -- Zones
|
|||||||
-- Quad-point zone
|
-- Quad-point zone
|
||||||
---
|
---
|
||||||
|
|
||||||
self:I(string.format("Register ZONE: %s (Polygon, Quad)", ZoneName))
|
self:I( string.format( "Register ZONE: %s (Polygon, Quad)", ZoneName ) )
|
||||||
|
|
||||||
Zone=ZONE_POLYGON_BASE:New(ZoneName, ZoneData.verticies)
|
Zone = ZONE_POLYGON_BASE:New( ZoneName, ZoneData.verticies )
|
||||||
|
|
||||||
--for i,vec2 in pairs(ZoneData.verticies) do
|
-- for i,vec2 in pairs(ZoneData.verticies) do
|
||||||
-- local coord=COORDINATE:NewFromVec2(vec2)
|
-- local coord=COORDINATE:NewFromVec2(vec2)
|
||||||
-- coord:MarkToAll(string.format("%s Point %d", ZoneName, i))
|
-- coord:MarkToAll(string.format("%s Point %d", ZoneName, i))
|
||||||
--end
|
-- end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if Zone then
|
if Zone then
|
||||||
|
|
||||||
-- Store color of zone.
|
-- Store color of zone.
|
||||||
Zone.Color=color
|
Zone.Color = color
|
||||||
|
|
||||||
-- Store in DB.
|
-- Store in DB.
|
||||||
self.ZONENAMES[ZoneName] = ZoneName
|
self.ZONENAMES[ZoneName] = ZoneName
|
||||||
|
|
||||||
-- Add zone.
|
-- Add zone.
|
||||||
self:AddZone(ZoneName, Zone)
|
self:AddZone( ZoneName, Zone )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -351,20 +340,20 @@ do -- Zones
|
|||||||
|
|
||||||
-- Polygon zones defined by late activated groups.
|
-- Polygon zones defined by late activated groups.
|
||||||
for ZoneGroupName, ZoneGroup in pairs( self.GROUPS ) do
|
for ZoneGroupName, ZoneGroup in pairs( self.GROUPS ) do
|
||||||
if ZoneGroupName:match("#ZONE_POLYGON") then
|
if ZoneGroupName:match( "#ZONE_POLYGON" ) then
|
||||||
|
|
||||||
local ZoneName1 = ZoneGroupName:match("(.*)#ZONE_POLYGON")
|
local ZoneName1 = ZoneGroupName:match( "(.*)#ZONE_POLYGON" )
|
||||||
local ZoneName2 = ZoneGroupName:match(".*#ZONE_POLYGON(.*)")
|
local ZoneName2 = ZoneGroupName:match( ".*#ZONE_POLYGON(.*)" )
|
||||||
local ZoneName = ZoneName1 .. ( ZoneName2 or "" )
|
local ZoneName = ZoneName1 .. (ZoneName2 or "")
|
||||||
|
|
||||||
-- Debug output
|
-- Debug output
|
||||||
self:I(string.format("Register ZONE: %s (Polygon)", ZoneName))
|
self:I( string.format( "Register ZONE: %s (Polygon)", ZoneName ) )
|
||||||
|
|
||||||
-- Create a new polygon zone.
|
-- Create a new polygon zone.
|
||||||
local Zone_Polygon = ZONE_POLYGON:New( ZoneName, ZoneGroup )
|
local Zone_Polygon = ZONE_POLYGON:New( ZoneName, ZoneGroup )
|
||||||
|
|
||||||
-- Set color.
|
-- Set color.
|
||||||
Zone_Polygon:SetColor({1, 0, 0}, 0.15)
|
Zone_Polygon:SetColor( { 1, 0, 0 }, 0.15 )
|
||||||
|
|
||||||
-- Store name in DB.
|
-- Store name in DB.
|
||||||
self.ZONENAMES[ZoneName] = ZoneName
|
self.ZONENAMES[ZoneName] = ZoneName
|
||||||
@@ -376,7 +365,6 @@ do -- Zones
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end -- zone
|
end -- zone
|
||||||
|
|
||||||
do -- Zone_Goal
|
do -- Zone_Goal
|
||||||
@@ -402,7 +390,6 @@ do -- Zone_Goal
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Deletes a @{Zone} from the DATABASE based on the zone name.
|
--- Deletes a @{Zone} from the DATABASE based on the zone name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string ZoneName The name of the zone.
|
-- @param #string ZoneName The name of the zone.
|
||||||
@@ -424,7 +411,6 @@ do -- cargo
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Deletes a Cargo from the DATABASE based on the Cargo Name.
|
--- Deletes a Cargo from the DATABASE based on the Cargo Name.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string CargoName The name of the airbase
|
-- @param #string CargoName The name of the airbase
|
||||||
@@ -466,38 +452,38 @@ do -- cargo
|
|||||||
|
|
||||||
for CargoGroupName, CargoGroup in pairs( Groups ) do
|
for CargoGroupName, CargoGroup in pairs( Groups ) do
|
||||||
if self:IsCargo( CargoGroupName ) then
|
if self:IsCargo( CargoGroupName ) then
|
||||||
local CargoInfo = CargoGroupName:match("#CARGO(.*)")
|
local CargoInfo = CargoGroupName:match( "#CARGO(.*)" )
|
||||||
local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)")
|
local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)" )
|
||||||
local CargoName1 = CargoGroupName:match("(.*)#CARGO%(.*%)")
|
local CargoName1 = CargoGroupName:match( "(.*)#CARGO%(.*%)" )
|
||||||
local CargoName2 = CargoGroupName:match(".*#CARGO%(.*%)(.*)")
|
local CargoName2 = CargoGroupName:match( ".*#CARGO%(.*%)(.*)" )
|
||||||
local CargoName = CargoName1 .. ( CargoName2 or "" )
|
local CargoName = CargoName1 .. (CargoName2 or "")
|
||||||
local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?")
|
local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?" )
|
||||||
local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") or CargoName
|
local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?" ) or CargoName
|
||||||
local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?") )
|
local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?" ) )
|
||||||
local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?") )
|
local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?" ) )
|
||||||
|
|
||||||
self:I({"Register CargoGroup:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius})
|
self:I( { "Register CargoGroup:", Type = Type, Name = Name, LoadRadius = LoadRadius, NearRadius = NearRadius } )
|
||||||
CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius, NearRadius )
|
CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius, NearRadius )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for CargoStaticName, CargoStatic in pairs( self.STATICS ) do
|
for CargoStaticName, CargoStatic in pairs( self.STATICS ) do
|
||||||
if self:IsCargo( CargoStaticName ) then
|
if self:IsCargo( CargoStaticName ) then
|
||||||
local CargoInfo = CargoStaticName:match("#CARGO(.*)")
|
local CargoInfo = CargoStaticName:match( "#CARGO(.*)" )
|
||||||
local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)")
|
local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)" )
|
||||||
local CargoName = CargoStaticName:match("(.*)#CARGO")
|
local CargoName = CargoStaticName:match( "(.*)#CARGO" )
|
||||||
local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?")
|
local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?" )
|
||||||
local Category = CargoParam and CargoParam:match( "C=([%a%d ]+),?")
|
local Category = CargoParam and CargoParam:match( "C=([%a%d ]+),?" )
|
||||||
local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") or CargoName
|
local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?" ) or CargoName
|
||||||
local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?") )
|
local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?" ) )
|
||||||
local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?") )
|
local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?" ) )
|
||||||
|
|
||||||
if Category == "SLING" then
|
if Category == "SLING" then
|
||||||
self:I({"Register CargoSlingload:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius})
|
self:I( { "Register CargoSlingload:", Type = Type, Name = Name, LoadRadius = LoadRadius, NearRadius = NearRadius } )
|
||||||
CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
||||||
else
|
else
|
||||||
if Category == "CRATE" then
|
if Category == "CRATE" then
|
||||||
self:I({"Register CargoCrate:",Type=Type,Name=Name,LoadRadius=LoadRadius,NearRadius=NearRadius})
|
self:I( { "Register CargoCrate:", Type = Type, Name = Name, LoadRadius = LoadRadius, NearRadius = NearRadius } )
|
||||||
CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -518,7 +504,6 @@ function DATABASE:FindClient( ClientName )
|
|||||||
return ClientFound
|
return ClientFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Adds a CLIENT based on the ClientName in the DATABASE.
|
--- Adds a CLIENT based on the ClientName in the DATABASE.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string ClientName Name of the Client unit.
|
-- @param #string ClientName Name of the Client unit.
|
||||||
@@ -532,7 +517,6 @@ function DATABASE:AddClient( ClientName )
|
|||||||
return self.CLIENTS[ClientName]
|
return self.CLIENTS[ClientName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Finds a GROUP based on the GroupName.
|
--- Finds a GROUP based on the GroupName.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string GroupName
|
-- @param #string GroupName
|
||||||
@@ -543,7 +527,6 @@ function DATABASE:FindGroup( GroupName )
|
|||||||
return GroupFound
|
return GroupFound
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Adds a GROUP based on the GroupName in the DATABASE.
|
--- Adds a GROUP based on the GroupName in the DATABASE.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
function DATABASE:AddGroup( GroupName )
|
function DATABASE:AddGroup( GroupName )
|
||||||
@@ -591,7 +574,6 @@ function DATABASE:GetPlayers()
|
|||||||
return self.PLAYERS
|
return self.PLAYERS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get the player table from the DATABASE, which contains all UNIT objects.
|
--- Get the player table from the DATABASE, which contains all UNIT objects.
|
||||||
-- The player table contains all UNIT objects of the player with the key the name of the player (PlayerName).
|
-- The player table contains all UNIT objects of the player with the key the name of the player (PlayerName).
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
@@ -604,7 +586,6 @@ function DATABASE:GetPlayerUnits()
|
|||||||
return self.PLAYERUNITS
|
return self.PLAYERUNITS
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get the player table from the DATABASE which have joined in the mission historically.
|
--- Get the player table from the DATABASE which have joined in the mission historically.
|
||||||
-- The player table contains all UNIT objects with the key the name of the player (PlayerName).
|
-- The player table contains all UNIT objects with the key the name of the player (PlayerName).
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
@@ -617,7 +598,6 @@ function DATABASE:GetPlayersJoined()
|
|||||||
return self.PLAYERSJOINED
|
return self.PLAYERSJOINED
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Instantiate new Groups within the DCSRTE.
|
--- Instantiate new Groups within the DCSRTE.
|
||||||
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
|
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
|
||||||
-- SpawnCountryID, SpawnCategoryID
|
-- SpawnCountryID, SpawnCategoryID
|
||||||
@@ -722,7 +702,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
|
|||||||
|
|
||||||
for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do
|
for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do
|
||||||
|
|
||||||
UnitTemplate.name = env.getValueDictByKey(UnitTemplate.name)
|
UnitTemplate.name = env.getValueDictByKey( UnitTemplate.name )
|
||||||
|
|
||||||
self.Templates.Units[UnitTemplate.name] = {}
|
self.Templates.Units[UnitTemplate.name] = {}
|
||||||
self.Templates.Units[UnitTemplate.name].UnitName = UnitTemplate.name
|
self.Templates.Units[UnitTemplate.name].UnitName = UnitTemplate.name
|
||||||
@@ -742,7 +722,7 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
|
|||||||
self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate
|
||||||
end
|
end
|
||||||
|
|
||||||
UnitNames[#UnitNames+1] = self.Templates.Units[UnitTemplate.name].UnitName
|
UnitNames[#UnitNames + 1] = self.Templates.Units[UnitTemplate.name].UnitName
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
@@ -750,9 +730,8 @@ function DATABASE:_RegisterGroupTemplate( GroupTemplate, CoalitionSide, Category
|
|||||||
Coalition = self.Templates.Groups[GroupTemplateName].CoalitionID,
|
Coalition = self.Templates.Groups[GroupTemplateName].CoalitionID,
|
||||||
Category = self.Templates.Groups[GroupTemplateName].CategoryID,
|
Category = self.Templates.Groups[GroupTemplateName].CategoryID,
|
||||||
Country = self.Templates.Groups[GroupTemplateName].CountryID,
|
Country = self.Templates.Groups[GroupTemplateName].CountryID,
|
||||||
Units = UnitNames
|
Units = UnitNames,
|
||||||
}
|
} )
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get group template.
|
--- Get group template.
|
||||||
@@ -778,7 +757,7 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
|
|||||||
|
|
||||||
local StaticTemplate = UTILS.DeepCopy( StaticTemplate )
|
local StaticTemplate = UTILS.DeepCopy( StaticTemplate )
|
||||||
|
|
||||||
local StaticTemplateName = env.getValueDictByKey(StaticTemplate.name)
|
local StaticTemplateName = env.getValueDictByKey( StaticTemplate.name )
|
||||||
|
|
||||||
self.Templates.Statics[StaticTemplateName] = self.Templates.Statics[StaticTemplateName] or {}
|
self.Templates.Statics[StaticTemplateName] = self.Templates.Statics[StaticTemplateName] or {}
|
||||||
|
|
||||||
@@ -797,9 +776,8 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category
|
|||||||
self:T( { Static = self.Templates.Statics[StaticTemplateName].StaticName,
|
self:T( { Static = self.Templates.Statics[StaticTemplateName].StaticName,
|
||||||
Coalition = self.Templates.Statics[StaticTemplateName].CoalitionID,
|
Coalition = self.Templates.Statics[StaticTemplateName].CoalitionID,
|
||||||
Category = self.Templates.Statics[StaticTemplateName].CategoryID,
|
Category = self.Templates.Statics[StaticTemplateName].CategoryID,
|
||||||
Country = self.Templates.Statics[StaticTemplateName].CountryID
|
Country = self.Templates.Statics[StaticTemplateName].CountryID,
|
||||||
}
|
} )
|
||||||
)
|
|
||||||
|
|
||||||
self:AddStatic( StaticTemplateName )
|
self:AddStatic( StaticTemplateName )
|
||||||
|
|
||||||
@@ -815,7 +793,7 @@ function DATABASE:GetStaticGroupTemplate( StaticName )
|
|||||||
local StaticTemplate = self.Templates.Statics[StaticName].GroupTemplate
|
local StaticTemplate = self.Templates.Statics[StaticName].GroupTemplate
|
||||||
return StaticTemplate, self.Templates.Statics[StaticName].CoalitionID, self.Templates.Statics[StaticName].CategoryID, self.Templates.Statics[StaticName].CountryID
|
return StaticTemplate, self.Templates.Statics[StaticName].CoalitionID, self.Templates.Statics[StaticName].CategoryID, self.Templates.Statics[StaticName].CountryID
|
||||||
else
|
else
|
||||||
self:E("ERROR: Static group template does NOT exist for static "..tostring(StaticName))
|
self:E( "ERROR: Static group template does NOT exist for static " .. tostring( StaticName ) )
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -829,7 +807,7 @@ function DATABASE:GetStaticUnitTemplate( StaticName )
|
|||||||
local UnitTemplate = self.Templates.Statics[StaticName].UnitTemplate
|
local UnitTemplate = self.Templates.Statics[StaticName].UnitTemplate
|
||||||
return UnitTemplate, self.Templates.Statics[StaticName].CoalitionID, self.Templates.Statics[StaticName].CategoryID, self.Templates.Statics[StaticName].CountryID
|
return UnitTemplate, self.Templates.Statics[StaticName].CoalitionID, self.Templates.Statics[StaticName].CategoryID, self.Templates.Statics[StaticName].CountryID
|
||||||
else
|
else
|
||||||
self:E("ERROR: Static unit template does NOT exist for static "..tostring(StaticName))
|
self:E( "ERROR: Static unit template does NOT exist for static " .. tostring( StaticName ) )
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -842,7 +820,7 @@ function DATABASE:GetGroupNameFromUnitName( UnitName )
|
|||||||
if self.Templates.Units[UnitName] then
|
if self.Templates.Units[UnitName] then
|
||||||
return self.Templates.Units[UnitName].GroupName
|
return self.Templates.Units[UnitName].GroupName
|
||||||
else
|
else
|
||||||
self:E("ERROR: Unit template does not exist for unit "..tostring(UnitName))
|
self:E( "ERROR: Unit template does not exist for unit " .. tostring( UnitName ) )
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -855,7 +833,7 @@ function DATABASE:GetGroupTemplateFromUnitName( UnitName )
|
|||||||
if self.Templates.Units[UnitName] then
|
if self.Templates.Units[UnitName] then
|
||||||
return self.Templates.Units[UnitName].GroupTemplate
|
return self.Templates.Units[UnitName].GroupTemplate
|
||||||
else
|
else
|
||||||
self:E("ERROR: Unit template does not exist for unit "..tostring(UnitName))
|
self:E( "ERROR: Unit template does not exist for unit " .. tostring( UnitName ) )
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -902,8 +880,6 @@ function DATABASE:GetCategoryFromAirbase( AirbaseName )
|
|||||||
return self.AIRBASES[AirbaseName]:GetCategory()
|
return self.AIRBASES[AirbaseName]:GetCategory()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Private method that registers all alive players in the mission.
|
--- Private method that registers all alive players in the mission.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
@@ -927,7 +903,6 @@ function DATABASE:_RegisterPlayers()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Private method that registers all Groups and Units within in the mission.
|
--- Private method that registers all Groups and Units within in the mission.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
@@ -945,7 +920,7 @@ function DATABASE:_RegisterGroupsAndUnits()
|
|||||||
local DCSGroupName = DCSGroup:getName()
|
local DCSGroupName = DCSGroup:getName()
|
||||||
|
|
||||||
-- Add group.
|
-- Add group.
|
||||||
self:I(string.format("Register Group: %s", tostring(DCSGroupName)))
|
self:I( string.format( "Register Group: %s", tostring( DCSGroupName ) ) )
|
||||||
self:AddGroup( DCSGroupName )
|
self:AddGroup( DCSGroupName )
|
||||||
|
|
||||||
-- Loop over units in group.
|
-- Loop over units in group.
|
||||||
@@ -955,12 +930,12 @@ function DATABASE:_RegisterGroupsAndUnits()
|
|||||||
local DCSUnitName = DCSUnit:getName()
|
local DCSUnitName = DCSUnit:getName()
|
||||||
|
|
||||||
-- Add unit.
|
-- Add unit.
|
||||||
self:I(string.format("Register Unit: %s", tostring(DCSUnitName)))
|
self:I( string.format( "Register Unit: %s", tostring( DCSUnitName ) ) )
|
||||||
self:AddUnit( DCSUnitName )
|
self:AddUnit( DCSUnitName )
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E({"Group does not exist: ", DCSGroup})
|
self:E( { "Group does not exist: ", DCSGroup } )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -975,7 +950,7 @@ end
|
|||||||
function DATABASE:_RegisterClients()
|
function DATABASE:_RegisterClients()
|
||||||
|
|
||||||
for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do
|
for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do
|
||||||
self:I(string.format("Register Client: %s", tostring(ClientName)))
|
self:I( string.format( "Register Client: %s", tostring( ClientName ) ) )
|
||||||
self:AddClient( ClientName )
|
self:AddClient( ClientName )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -985,7 +960,7 @@ end
|
|||||||
--- @param #DATABASE self
|
--- @param #DATABASE self
|
||||||
function DATABASE:_RegisterStatics()
|
function DATABASE:_RegisterStatics()
|
||||||
|
|
||||||
local CoalitionsData={GroupsRed=coalition.getStaticObjects(coalition.side.RED), GroupsBlue=coalition.getStaticObjects(coalition.side.BLUE), GroupsNeutral=coalition.getStaticObjects(coalition.side.NEUTRAL)}
|
local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ), GroupsNeutral = coalition.getStaticObjects( coalition.side.NEUTRAL ) }
|
||||||
|
|
||||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||||
for DCSStaticId, DCSStatic in pairs( CoalitionData ) do
|
for DCSStaticId, DCSStatic in pairs( CoalitionData ) do
|
||||||
@@ -993,7 +968,7 @@ function DATABASE:_RegisterStatics()
|
|||||||
if DCSStatic:isExist() then
|
if DCSStatic:isExist() then
|
||||||
local DCSStaticName = DCSStatic:getName()
|
local DCSStaticName = DCSStatic:getName()
|
||||||
|
|
||||||
self:I(string.format("Register Static: %s", tostring(DCSStaticName)))
|
self:I( string.format( "Register Static: %s", tostring( DCSStaticName ) ) )
|
||||||
self:AddStatic( DCSStaticName )
|
self:AddStatic( DCSStaticName )
|
||||||
else
|
else
|
||||||
self:E( { "Static does not exist: ", DCSStatic } )
|
self:E( { "Static does not exist: ", DCSStatic } )
|
||||||
@@ -1009,33 +984,33 @@ end
|
|||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
function DATABASE:_RegisterAirbases()
|
function DATABASE:_RegisterAirbases()
|
||||||
|
|
||||||
for DCSAirbaseId, DCSAirbase in pairs(world.getAirbases()) do
|
for DCSAirbaseId, DCSAirbase in pairs( world.getAirbases() ) do
|
||||||
|
|
||||||
-- Get the airbase name.
|
-- Get the airbase name.
|
||||||
local DCSAirbaseName = DCSAirbase:getName()
|
local DCSAirbaseName = DCSAirbase:getName()
|
||||||
|
|
||||||
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
|
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
|
||||||
local airbaseID=DCSAirbase:getID()
|
local airbaseID = DCSAirbase:getID()
|
||||||
|
|
||||||
-- Add and register airbase.
|
-- Add and register airbase.
|
||||||
local airbase=self:AddAirbase( DCSAirbaseName )
|
local airbase = self:AddAirbase( DCSAirbaseName )
|
||||||
|
|
||||||
-- Unique ID.
|
-- Unique ID.
|
||||||
local airbaseUID=airbase:GetID(true)
|
local airbaseUID = airbase:GetID( true )
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
local text=string.format("Register %s: %s (ID=%d UID=%d), parking=%d [", AIRBASE.CategoryName[airbase.category], tostring(DCSAirbaseName), airbaseID, airbaseUID, airbase.NparkingTotal)
|
local text = string.format( "Register %s: %s (ID=%d UID=%d), parking=%d [", AIRBASE.CategoryName[airbase.category], tostring( DCSAirbaseName ), airbaseID, airbaseUID, airbase.NparkingTotal )
|
||||||
for _,terminalType in pairs(AIRBASE.TerminalType) do
|
for _, terminalType in pairs( AIRBASE.TerminalType ) do
|
||||||
if airbase.NparkingTerminal and airbase.NparkingTerminal[terminalType] then
|
if airbase.NparkingTerminal and airbase.NparkingTerminal[terminalType] then
|
||||||
text=text..string.format("%d=%d ", terminalType, airbase.NparkingTerminal[terminalType])
|
text = text .. string.format( "%d=%d ", terminalType, airbase.NparkingTerminal[terminalType] )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
text=text.."]"
|
text = text .. "]"
|
||||||
self:I(text)
|
self:I( text )
|
||||||
|
|
||||||
-- Check for DCS bug IDs.
|
-- Check for DCS bug IDs.
|
||||||
if airbaseID~=airbase:GetID() then
|
if airbaseID ~= airbase:GetID() then
|
||||||
--self:E("WARNING: :getID does NOT match :GetID!")
|
-- self:E("WARNING: :getID does NOT match :GetID!")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1043,7 +1018,6 @@ function DATABASE:_RegisterAirbases()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Events
|
--- Events
|
||||||
|
|
||||||
--- Handles the OnBirth event for the alive units set.
|
--- Handles the OnBirth event for the alive units set.
|
||||||
@@ -1066,10 +1040,10 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
self:AddGroup( Event.IniDCSGroupName )
|
self:AddGroup( Event.IniDCSGroupName )
|
||||||
|
|
||||||
-- Add airbase if it was spawned later in the mission.
|
-- Add airbase if it was spawned later in the mission.
|
||||||
local DCSAirbase = Airbase.getByName(Event.IniDCSUnitName)
|
local DCSAirbase = Airbase.getByName( Event.IniDCSUnitName )
|
||||||
if DCSAirbase then
|
if DCSAirbase then
|
||||||
self:I(string.format("Adding airbase %s", tostring(Event.IniDCSUnitName)))
|
self:I( string.format( "Adding airbase %s", tostring( Event.IniDCSUnitName ) ) )
|
||||||
self:AddAirbase(Event.IniDCSUnitName)
|
self:AddAirbase( Event.IniDCSUnitName )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1081,7 +1055,7 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
Event.IniGroup = self:FindGroup( Event.IniDCSGroupName )
|
Event.IniGroup = self:FindGroup( Event.IniDCSGroupName )
|
||||||
|
|
||||||
-- Client
|
-- Client
|
||||||
local client=self.CLIENTS[Event.IniDCSUnitName] --Wrapper.Client#CLIENT
|
local client = self.CLIENTS[Event.IniDCSUnitName] -- Wrapper.Client#CLIENT
|
||||||
|
|
||||||
if client then
|
if client then
|
||||||
-- TODO: create event ClientAlive
|
-- TODO: create event ClientAlive
|
||||||
@@ -1093,15 +1067,15 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
if PlayerName then
|
if PlayerName then
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:I(string.format("Player '%s' joint unit '%s' of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName)))
|
self:I( string.format( "Player '%s' joint unit '%s' of group '%s'", tostring( PlayerName ), tostring( Event.IniDCSUnitName ), tostring( Event.IniDCSGroupName ) ) )
|
||||||
|
|
||||||
-- Add client in case it does not exist already.
|
-- Add client in case it does not exist already.
|
||||||
if not client then
|
if not client then
|
||||||
client=self:AddClient(Event.IniDCSUnitName)
|
client = self:AddClient( Event.IniDCSUnitName )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add player.
|
-- Add player.
|
||||||
client:AddPlayer(PlayerName)
|
client:AddPlayer( PlayerName )
|
||||||
|
|
||||||
-- Add player.
|
-- Add player.
|
||||||
if not self.PLAYERS[PlayerName] then
|
if not self.PLAYERS[PlayerName] then
|
||||||
@@ -1110,10 +1084,10 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
|
|
||||||
-- Player settings.
|
-- Player settings.
|
||||||
local Settings = SETTINGS:Set( PlayerName )
|
local Settings = SETTINGS:Set( PlayerName )
|
||||||
Settings:SetPlayerMenu(Event.IniUnit)
|
Settings:SetPlayerMenu( Event.IniUnit )
|
||||||
|
|
||||||
-- Create an event.
|
-- Create an event.
|
||||||
self:CreateEventPlayerEnterAircraft(Event.IniUnit)
|
self:CreateEventPlayerEnterAircraft( Event.IniUnit )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1123,7 +1097,6 @@ function DATABASE:_EventOnBirth( Event )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnDead or OnCrash event for alive units set.
|
--- Handles the OnDead or OnCrash event for alive units set.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
@@ -1131,7 +1104,7 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
local name=Event.IniDCSUnitName
|
local name = Event.IniDCSUnitName
|
||||||
|
|
||||||
if Event.IniObjectCategory == 3 then
|
if Event.IniObjectCategory == 3 then
|
||||||
|
|
||||||
@@ -1153,11 +1126,11 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
|
|
||||||
-- Delete unit.
|
-- Delete unit.
|
||||||
if self.UNITS[Event.IniDCSUnitName] then
|
if self.UNITS[Event.IniDCSUnitName] then
|
||||||
self:DeleteUnit(Event.IniDCSUnitName)
|
self:DeleteUnit( Event.IniDCSUnitName )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Remove client players.
|
-- Remove client players.
|
||||||
local client=self.CLIENTS[name] --Wrapper.Client#CLIENT
|
local client = self.CLIENTS[name] -- Wrapper.Client#CLIENT
|
||||||
|
|
||||||
if client then
|
if client then
|
||||||
client:RemovePlayers()
|
client:RemovePlayers()
|
||||||
@@ -1167,9 +1140,9 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Add airbase if it was spawned later in the mission.
|
-- Add airbase if it was spawned later in the mission.
|
||||||
local airbase=self.AIRBASES[Event.IniDCSUnitName] --Wrapper.Airbase#AIRBASE
|
local airbase = self.AIRBASES[Event.IniDCSUnitName] -- Wrapper.Airbase#AIRBASE
|
||||||
if airbase and (airbase:IsHelipad() or airbase:IsShip()) then
|
if airbase and (airbase:IsHelipad() or airbase:IsShip()) then
|
||||||
self:DeleteAirbase(Event.IniDCSUnitName)
|
self:DeleteAirbase( Event.IniDCSUnitName )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1178,7 +1151,6 @@ function DATABASE:_EventOnDeadOrCrash( Event )
|
|||||||
self:AccountDestroys( Event )
|
self:AccountDestroys( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).
|
--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
@@ -1210,13 +1182,12 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
|
|||||||
Settings:SetPlayerMenu( Event.IniUnit )
|
Settings:SetPlayerMenu( Event.IniUnit )
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E("ERROR: getPlayerName() returned nil for event PlayerEnterUnit")
|
self:E( "ERROR: getPlayerName() returned nil for event PlayerEnterUnit" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
|
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
@@ -1230,22 +1201,22 @@ function DATABASE:_EventOnPlayerLeaveUnit( Event )
|
|||||||
-- Try to get the player name. This can be buggy for multicrew aircraft!
|
-- Try to get the player name. This can be buggy for multicrew aircraft!
|
||||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||||
|
|
||||||
if PlayerName then --and self.PLAYERS[PlayerName] then
|
if PlayerName then -- and self.PLAYERS[PlayerName] then
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:I(string.format("Player '%s' left unit %s", tostring(PlayerName), tostring(Event.IniUnitName)))
|
self:I( string.format( "Player '%s' left unit %s", tostring( PlayerName ), tostring( Event.IniUnitName ) ) )
|
||||||
|
|
||||||
-- Remove player menu.
|
-- Remove player menu.
|
||||||
local Settings = SETTINGS:Set( PlayerName )
|
local Settings = SETTINGS:Set( PlayerName )
|
||||||
Settings:RemovePlayerMenu(Event.IniUnit)
|
Settings:RemovePlayerMenu( Event.IniUnit )
|
||||||
|
|
||||||
-- Delete player.
|
-- Delete player.
|
||||||
self:DeletePlayer(Event.IniUnit, PlayerName)
|
self:DeletePlayer( Event.IniUnit, PlayerName )
|
||||||
|
|
||||||
-- Client stuff.
|
-- Client stuff.
|
||||||
local client=self.CLIENTS[Event.IniDCSUnitName] --Wrapper.Client#CLIENT
|
local client = self.CLIENTS[Event.IniDCSUnitName] -- Wrapper.Client#CLIENT
|
||||||
if client then
|
if client then
|
||||||
client:RemovePlayer(PlayerName)
|
client:RemovePlayer( PlayerName )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1268,19 +1239,19 @@ function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set )
|
|||||||
self:T2( Object )
|
self:T2( Object )
|
||||||
IteratorFunction( Object, unpack( arg ) )
|
IteratorFunction( Object, unpack( arg ) )
|
||||||
Count = Count + 1
|
Count = Count + 1
|
||||||
-- if Count % 100 == 0 then
|
-- if Count % 100 == 0 then
|
||||||
-- coroutine.yield( false )
|
-- coroutine.yield( false )
|
||||||
-- end
|
-- end
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- local co = coroutine.create( CoRoutine )
|
-- local co = coroutine.create( CoRoutine )
|
||||||
local co = CoRoutine
|
local co = CoRoutine
|
||||||
|
|
||||||
local function Schedule()
|
local function Schedule()
|
||||||
|
|
||||||
-- local status, res = coroutine.resume( co )
|
-- local status, res = coroutine.resume( co )
|
||||||
local status, res = co()
|
local status, res = co()
|
||||||
self:T3( { status, res } )
|
self:T3( { status, res } )
|
||||||
|
|
||||||
@@ -1296,18 +1267,17 @@ function DATABASE:ForEach( IteratorFunction, FinalizeFunction, arg, Set )
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
--local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 )
|
-- local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 )
|
||||||
Schedule()
|
Schedule()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Iterate the DATABASE and call an iterator function for each **alive** STATIC, providing the STATIC and optional parameters.
|
--- Iterate the DATABASE and call an iterator function for each **alive** STATIC, providing the STATIC and optional parameters.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a STATIC parameter.
|
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a STATIC parameter.
|
||||||
-- @return #DATABASE self
|
-- @return #DATABASE self
|
||||||
function DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... ) --R2.1
|
function DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... ) -- R2.1
|
||||||
self:F2( arg )
|
self:F2( arg )
|
||||||
|
|
||||||
self:ForEach( IteratorFunction, FinalizeFunction, arg, self.STATICS )
|
self:ForEach( IteratorFunction, FinalizeFunction, arg, self.STATICS )
|
||||||
@@ -1315,7 +1285,6 @@ function DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... ) --R2
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters.
|
--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter.
|
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter.
|
||||||
@@ -1328,7 +1297,6 @@ function DATABASE:ForEachUnit( IteratorFunction, FinalizeFunction, ... )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters.
|
--- Iterate the DATABASE and call an iterator function for each **alive** GROUP, providing the GROUP and optional parameters.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a GROUP parameter.
|
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a GROUP parameter.
|
||||||
@@ -1341,7 +1309,6 @@ function DATABASE:ForEachGroup( IteratorFunction, FinalizeFunction, ... )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Iterate the DATABASE and call an iterator function for each **ALIVE** player, providing the player name and optional parameters.
|
--- Iterate the DATABASE and call an iterator function for each **ALIVE** player, providing the player name and optional parameters.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept the player name.
|
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept the player name.
|
||||||
@@ -1354,7 +1321,6 @@ function DATABASE:ForEachPlayer( IteratorFunction, FinalizeFunction, ... )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Iterate the DATABASE and call an iterator function for each player who has joined the mission, providing the Unit of the player and optional parameters.
|
--- Iterate the DATABASE and call an iterator function for each player who has joined the mission, providing the Unit of the player and optional parameters.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter.
|
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter.
|
||||||
@@ -1379,7 +1345,6 @@ function DATABASE:ForEachPlayerUnit( IteratorFunction, FinalizeFunction, ... )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters.
|
--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #function IteratorFunction The function that will be called object in the database. The function needs to accept a CLIENT parameter.
|
-- @param #function IteratorFunction The function that will be called object in the database. The function needs to accept a CLIENT parameter.
|
||||||
@@ -1404,7 +1369,6 @@ function DATABASE:ForEachCargo( IteratorFunction, ... )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnEventNewCargo event.
|
--- Handles the OnEventNewCargo event.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
@@ -1416,7 +1380,6 @@ function DATABASE:OnEventNewCargo( EventData )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnEventDeleteCargo.
|
--- Handles the OnEventDeleteCargo.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
@@ -1428,7 +1391,6 @@ function DATABASE:OnEventDeleteCargo( EventData )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnEventNewZone event.
|
--- Handles the OnEventNewZone event.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
@@ -1440,7 +1402,6 @@ function DATABASE:OnEventNewZone( EventData )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Handles the OnEventDeleteZone.
|
--- Handles the OnEventDeleteZone.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
@@ -1452,8 +1413,6 @@ function DATABASE:OnEventDeleteZone( EventData )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Gets the player settings
|
--- Gets the player settings
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string PlayerName
|
-- @param #string PlayerName
|
||||||
@@ -1463,7 +1422,6 @@ function DATABASE:GetPlayerSettings( PlayerName )
|
|||||||
return self.PLAYERSETTINGS[PlayerName]
|
return self.PLAYERSETTINGS[PlayerName]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Sets the player settings
|
--- Sets the player settings
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string PlayerName
|
-- @param #string PlayerName
|
||||||
@@ -1477,21 +1435,21 @@ end
|
|||||||
--- Add a flight group to the data base.
|
--- Add a flight group to the data base.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup
|
-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup
|
||||||
function DATABASE:AddFlightGroup(flightgroup)
|
function DATABASE:AddFlightGroup( flightgroup )
|
||||||
self:I({NewFlightGroup=flightgroup.groupname})
|
self:I( { NewFlightGroup = flightgroup.groupname } )
|
||||||
self.FLIGHTGROUPS[flightgroup.groupname]=flightgroup
|
self.FLIGHTGROUPS[flightgroup.groupname] = flightgroup
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get a flight group from the data base.
|
--- Get a flight group from the data base.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string groupname Group name of the flight group. Can also be passed as GROUP object.
|
-- @param #string groupname Group name of the flight group. Can also be passed as GROUP object.
|
||||||
-- @return Ops.FlightGroup#FLIGHTGROUP Flight group object.
|
-- @return Ops.FlightGroup#FLIGHTGROUP Flight group object.
|
||||||
function DATABASE:GetFlightGroup(groupname)
|
function DATABASE:GetFlightGroup( groupname )
|
||||||
|
|
||||||
-- Get group and group name.
|
-- Get group and group name.
|
||||||
if type(groupname)=="string" then
|
if type( groupname ) == "string" then
|
||||||
else
|
else
|
||||||
groupname=groupname:GetName()
|
groupname = groupname:GetName()
|
||||||
end
|
end
|
||||||
|
|
||||||
return self.FLIGHTGROUPS[groupname]
|
return self.FLIGHTGROUPS[groupname]
|
||||||
@@ -1500,16 +1458,16 @@ end
|
|||||||
--- Add a flight control to the data base.
|
--- Add a flight control to the data base.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol
|
-- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol
|
||||||
function DATABASE:AddFlightControl(flightcontrol)
|
function DATABASE:AddFlightControl( flightcontrol )
|
||||||
self:F2( { flightcontrol } )
|
self:F2( { flightcontrol } )
|
||||||
self.FLIGHTCONTROLS[flightcontrol.airbasename]=flightcontrol
|
self.FLIGHTCONTROLS[flightcontrol.airbasename] = flightcontrol
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get a flight control object from the data base.
|
--- Get a flight control object from the data base.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param #string airbasename Name of the associated airbase.
|
-- @param #string airbasename Name of the associated airbase.
|
||||||
-- @return Ops.FlightControl#FLIGHTCONTROL The FLIGHTCONTROL object.s
|
-- @return Ops.FlightControl#FLIGHTCONTROL The FLIGHTCONTROL object.s
|
||||||
function DATABASE:GetFlightControl(airbasename)
|
function DATABASE:GetFlightControl( airbasename )
|
||||||
return self.FLIGHTCONTROLS[airbasename]
|
return self.FLIGHTCONTROLS[airbasename]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1519,29 +1477,29 @@ function DATABASE:_RegisterTemplates()
|
|||||||
|
|
||||||
self.Navpoints = {}
|
self.Navpoints = {}
|
||||||
self.UNITS = {}
|
self.UNITS = {}
|
||||||
--Build routines.db.units and self.Navpoints
|
-- Build routines.db.units and self.Navpoints
|
||||||
for CoalitionName, coa_data in pairs(env.mission.coalition) do
|
for CoalitionName, coa_data in pairs( env.mission.coalition ) do
|
||||||
self:T({CoalitionName=CoalitionName})
|
self:T( { CoalitionName = CoalitionName } )
|
||||||
|
|
||||||
if (CoalitionName == 'red' or CoalitionName == 'blue' or CoalitionName == 'neutrals') and type(coa_data) == 'table' then
|
if (CoalitionName == 'red' or CoalitionName == 'blue' or CoalitionName == 'neutrals') and type( coa_data ) == 'table' then
|
||||||
--self.Units[coa_name] = {}
|
-- self.Units[coa_name] = {}
|
||||||
|
|
||||||
local CoalitionSide = coalition.side[string.upper(CoalitionName)]
|
local CoalitionSide = coalition.side[string.upper( CoalitionName )]
|
||||||
if CoalitionName=="red" then
|
if CoalitionName == "red" then
|
||||||
CoalitionSide=coalition.side.RED
|
CoalitionSide = coalition.side.RED
|
||||||
elseif CoalitionName=="blue" then
|
elseif CoalitionName == "blue" then
|
||||||
CoalitionSide=coalition.side.BLUE
|
CoalitionSide = coalition.side.BLUE
|
||||||
else
|
else
|
||||||
CoalitionSide=coalition.side.NEUTRAL
|
CoalitionSide = coalition.side.NEUTRAL
|
||||||
end
|
end
|
||||||
|
|
||||||
-- build nav points DB
|
-- build nav points DB
|
||||||
self.Navpoints[CoalitionName] = {}
|
self.Navpoints[CoalitionName] = {}
|
||||||
if coa_data.nav_points then --navpoints
|
if coa_data.nav_points then -- navpoints
|
||||||
for nav_ind, nav_data in pairs(coa_data.nav_points) do
|
for nav_ind, nav_data in pairs( coa_data.nav_points ) do
|
||||||
|
|
||||||
if type(nav_data) == 'table' then
|
if type( nav_data ) == 'table' then
|
||||||
self.Navpoints[CoalitionName][nav_ind] = routines.utils.deepCopy(nav_data)
|
self.Navpoints[CoalitionName][nav_ind] = routines.utils.deepCopy( nav_data )
|
||||||
|
|
||||||
self.Navpoints[CoalitionName][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory.
|
self.Navpoints[CoalitionName][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory.
|
||||||
self.Navpoints[CoalitionName][nav_ind]['point'] = {} -- point is used by SSE, support it.
|
self.Navpoints[CoalitionName][nav_ind]['point'] = {} -- point is used by SSE, support it.
|
||||||
@@ -1553,58 +1511,58 @@ function DATABASE:_RegisterTemplates()
|
|||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------
|
-------------------------------------------------
|
||||||
if coa_data.country then --there is a country table
|
if coa_data.country then -- there is a country table
|
||||||
for cntry_id, cntry_data in pairs(coa_data.country) do
|
for cntry_id, cntry_data in pairs( coa_data.country ) do
|
||||||
|
|
||||||
local CountryName = string.upper(cntry_data.name)
|
local CountryName = string.upper( cntry_data.name )
|
||||||
local CountryID = cntry_data.id
|
local CountryID = cntry_data.id
|
||||||
|
|
||||||
self.COUNTRY_ID[CountryName] = CountryID
|
self.COUNTRY_ID[CountryName] = CountryID
|
||||||
self.COUNTRY_NAME[CountryID] = CountryName
|
self.COUNTRY_NAME[CountryID] = CountryName
|
||||||
|
|
||||||
--self.Units[coa_name][countryName] = {}
|
-- self.Units[coa_name][countryName] = {}
|
||||||
--self.Units[coa_name][countryName]["countryId"] = cntry_data.id
|
-- self.Units[coa_name][countryName]["countryId"] = cntry_data.id
|
||||||
|
|
||||||
if type(cntry_data) == 'table' then --just making sure
|
if type( cntry_data ) == 'table' then -- just making sure
|
||||||
|
|
||||||
for obj_type_name, obj_type_data in pairs(cntry_data) do
|
for obj_type_name, obj_type_data in pairs( cntry_data ) do
|
||||||
|
|
||||||
if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check
|
if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then -- should be an unncessary check
|
||||||
|
|
||||||
local CategoryName = obj_type_name
|
local CategoryName = obj_type_name
|
||||||
|
|
||||||
if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group!
|
if ((type( obj_type_data ) == 'table') and obj_type_data.group and (type( obj_type_data.group ) == 'table') and (#obj_type_data.group > 0)) then -- there's a group!
|
||||||
|
|
||||||
--self.Units[coa_name][countryName][category] = {}
|
-- self.Units[coa_name][countryName][category] = {}
|
||||||
|
|
||||||
for group_num, Template in pairs(obj_type_data.group) do
|
for group_num, Template in pairs( obj_type_data.group ) do
|
||||||
|
|
||||||
if obj_type_name ~= "static" and Template and Template.units and type(Template.units) == 'table' then --making sure again- this is a valid group
|
if obj_type_name ~= "static" and Template and Template.units and type( Template.units ) == 'table' then -- making sure again- this is a valid group
|
||||||
|
|
||||||
self:_RegisterGroupTemplate(Template, CoalitionSide, _DATABASECategory[string.lower(CategoryName)], CountryID)
|
self:_RegisterGroupTemplate( Template, CoalitionSide, _DATABASECategory[string.lower( CategoryName )], CountryID )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
self:_RegisterStaticTemplate(Template, CoalitionSide, _DATABASECategory[string.lower(CategoryName)], CountryID)
|
self:_RegisterStaticTemplate( Template, CoalitionSide, _DATABASECategory[string.lower( CategoryName )], CountryID )
|
||||||
|
|
||||||
end --if GroupTemplate and GroupTemplate.units then
|
end -- if GroupTemplate and GroupTemplate.units then
|
||||||
end --for group_num, GroupTemplate in pairs(obj_type_data.group) do
|
end -- for group_num, GroupTemplate in pairs(obj_type_data.group) do
|
||||||
end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then
|
end -- if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then
|
||||||
end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then
|
end -- if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then
|
||||||
end --for obj_type_name, obj_type_data in pairs(cntry_data) do
|
end -- for obj_type_name, obj_type_data in pairs(cntry_data) do
|
||||||
end --if type(cntry_data) == 'table' then
|
end -- if type(cntry_data) == 'table' then
|
||||||
end --for cntry_id, cntry_data in pairs(coa_data.country) do
|
end -- for cntry_id, cntry_data in pairs(coa_data.country) do
|
||||||
end --if coa_data.country then --there is a country table
|
end -- if coa_data.country then --there is a country table
|
||||||
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
end -- if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
||||||
end --for coa_name, coa_data in pairs(mission.coalition) do
|
end -- for coa_name, coa_data in pairs(mission.coalition) do
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Account the Hits of the Players.
|
--- Account the Hits of the Players.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function DATABASE:AccountHits( Event )
|
function DATABASE:AccountHits( Event )
|
||||||
self:F( { Event } )
|
self:F( { Event } )
|
||||||
|
|
||||||
if Event.IniPlayerName ~= nil then -- It is a player that is hitting something
|
if Event.IniPlayerName ~= nil then -- It is a player that is hitting something
|
||||||
@@ -1641,12 +1599,12 @@ end
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Account the destroys.
|
--- Account the destroys.
|
||||||
-- @param #DATABASE self
|
-- @param #DATABASE self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function DATABASE:AccountDestroys( Event )
|
function DATABASE:AccountDestroys( Event )
|
||||||
self:F( { Event } )
|
self:F( { Event } )
|
||||||
|
|
||||||
local TargetUnit = nil
|
local TargetUnit = nil
|
||||||
@@ -1670,8 +1628,8 @@ end
|
|||||||
TargetPlayerName = Event.IniPlayerName
|
TargetPlayerName = Event.IniPlayerName
|
||||||
|
|
||||||
TargetCoalition = Event.IniCoalition
|
TargetCoalition = Event.IniCoalition
|
||||||
--TargetCategory = TargetUnit:getCategory()
|
-- TargetCategory = TargetUnit:getCategory()
|
||||||
--TargetCategory = TargetUnit:getDesc().category -- Workaround
|
-- TargetCategory = TargetUnit:getDesc().category -- Workaround
|
||||||
TargetCategory = Event.IniCategory
|
TargetCategory = Event.IniCategory
|
||||||
TargetType = Event.IniTypeName
|
TargetType = Event.IniTypeName
|
||||||
|
|
||||||
@@ -1687,4 +1645,4 @@ end
|
|||||||
self.DESTROYS[Event.IniUnitName] = self.DESTROYS[Event.IniUnitName] or {}
|
self.DESTROYS[Event.IniUnitName] = self.DESTROYS[Event.IniUnitName] or {}
|
||||||
self.DESTROYS[Event.IniUnitName] = true
|
self.DESTROYS[Event.IniUnitName] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
-- Within a running mission, various DCS events occur. Units are dynamically created, crash, die, shoot stuff, get hit etc.
|
-- Within a running mission, various DCS events occur. Units are dynamically created, crash, die, shoot stuff, get hit etc.
|
||||||
-- This module provides a mechanism to dispatch those events occuring within your running mission, to the different objects orchestrating your mission.
|
-- This module provides a mechanism to dispatch those events occurring within your running mission, to the different objects orchestrating your mission.
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
--
|
--
|
||||||
@@ -141,7 +141,6 @@
|
|||||||
-- EventData.IniUnit:SmokeGreen()
|
-- EventData.IniUnit:SmokeGreen()
|
||||||
-- end
|
-- end
|
||||||
--
|
--
|
||||||
--
|
|
||||||
-- Find below an overview which events populate which information categories:
|
-- Find below an overview which events populate which information categories:
|
||||||
--
|
--
|
||||||
-- 
|
-- 
|
||||||
@@ -172,7 +171,6 @@
|
|||||||
-- @module Core.Event
|
-- @module Core.Event
|
||||||
-- @image Core_Event.JPG
|
-- @image Core_Event.JPG
|
||||||
|
|
||||||
|
|
||||||
--- @type EVENT
|
--- @type EVENT
|
||||||
-- @field #EVENT.Events Events
|
-- @field #EVENT.Events Events
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
@@ -194,7 +192,6 @@ world.event.S_EVENT_DELETE_ZONE_GOAL = world.event.S_EVENT_MAX + 1005
|
|||||||
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006
|
world.event.S_EVENT_REMOVE_UNIT = world.event.S_EVENT_MAX + 1006
|
||||||
world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007
|
world.event.S_EVENT_PLAYER_ENTER_AIRCRAFT = world.event.S_EVENT_MAX + 1007
|
||||||
|
|
||||||
|
|
||||||
--- The different types of events supported by MOOSE.
|
--- The different types of events supported by MOOSE.
|
||||||
-- Use this structure to subscribe to events using the @{Core.Base#BASE.HandleEvent}() method.
|
-- Use this structure to subscribe to events using the @{Core.Base#BASE.HandleEvent}() method.
|
||||||
-- @type EVENTS
|
-- @type EVENTS
|
||||||
@@ -304,8 +301,6 @@ EVENTS = {
|
|||||||
-- @field Core.ZONE#ZONE Zone The zone object.
|
-- @field Core.ZONE#ZONE Zone The zone object.
|
||||||
-- @field #string ZoneName The name of the zone.
|
-- @field #string ZoneName The name of the zone.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local _EVENTMETA = {
|
local _EVENTMETA = {
|
||||||
[world.event.S_EVENT_SHOT] = {
|
[world.event.S_EVENT_SHOT] = {
|
||||||
Order = 1,
|
Order = 1,
|
||||||
@@ -562,7 +557,6 @@ local _EVENTMETA = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--- The Events structure
|
--- The Events structure
|
||||||
-- @type EVENT.Events
|
-- @type EVENT.Events
|
||||||
-- @field #number IniUnit
|
-- @field #number IniUnit
|
||||||
@@ -576,12 +570,11 @@ function EVENT:New()
|
|||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
|
|
||||||
-- Add world event handler.
|
-- Add world event handler.
|
||||||
self.EventHandler = world.addEventHandler(self)
|
self.EventHandler = world.addEventHandler( self )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Initializes the Events structure for the event.
|
--- Initializes the Events structure for the event.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param DCS#world.event EventID Event ID.
|
-- @param DCS#world.event EventID Event ID.
|
||||||
@@ -595,7 +588,7 @@ function EVENT:Init( EventID, EventClass )
|
|||||||
self.Events[EventID] = {}
|
self.Events[EventID] = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Each event has a subtable of EventClasses, ordered by EventPriority.
|
-- Each event has a sub-table of EventClasses, ordered by EventPriority.
|
||||||
local EventPriority = EventClass:GetEventPriority()
|
local EventPriority = EventClass:GetEventPriority()
|
||||||
|
|
||||||
if not self.Events[EventID][EventPriority] then
|
if not self.Events[EventID][EventPriority] then
|
||||||
@@ -638,7 +631,7 @@ end
|
|||||||
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
||||||
-- @param DCS#world.event EventID Event ID.
|
-- @param DCS#world.event EventID Event ID.
|
||||||
-- @return #EVENT.Events
|
-- @return #EVENT.Events
|
||||||
function EVENT:Reset( EventObject ) --R2.1
|
function EVENT:Reset( EventObject ) -- R2.1
|
||||||
|
|
||||||
self:F( { "Resetting subscriptions for class: ", EventObject:GetClassNameAndID() } )
|
self:F( { "Resetting subscriptions for class: ", EventObject:GetClassNameAndID() } )
|
||||||
|
|
||||||
@@ -657,12 +650,11 @@ function EVENT:Reset( EventObject ) --R2.1
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
--- Clears all event subscriptions for a @{Core.Base#BASE} derived object.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param Core.Base#BASE EventClass The self class object for which the events are removed.
|
-- @param Core.Base#BASE EventClass The self class object for which the events are removed.
|
||||||
-- @return #EVENT self
|
-- @return #EVENT self
|
||||||
function EVENT:RemoveAll(EventClass)
|
function EVENT:RemoveAll( EventClass )
|
||||||
|
|
||||||
local EventClassName = EventClass:GetClassNameAndID()
|
local EventClassName = EventClass:GetClassNameAndID()
|
||||||
|
|
||||||
@@ -676,8 +668,6 @@ function EVENT:RemoveAll(EventClass)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Create an OnDead event handler for a group
|
--- Create an OnDead event handler for a group
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param #table EventTemplate
|
-- @param #table EventTemplate
|
||||||
@@ -709,7 +699,6 @@ function EVENT:OnEventGeneric( EventFunction, EventClass, EventID )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set a new listener for an `S_EVENT_X` event for a UNIT.
|
--- Set a new listener for an `S_EVENT_X` event for a UNIT.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param #string UnitName The name of the UNIT.
|
-- @param #string UnitName The name of the UNIT.
|
||||||
@@ -797,7 +786,6 @@ do -- OnDead
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- OnLand
|
do -- OnLand
|
||||||
|
|
||||||
--- Create an OnLand event handler for a group
|
--- Create an OnLand event handler for a group
|
||||||
@@ -929,7 +917,6 @@ do -- Event Creation
|
|||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Creation of a ZoneGoal Deletion Event.
|
--- Creation of a ZoneGoal Deletion Event.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created.
|
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal created.
|
||||||
@@ -945,7 +932,6 @@ do -- Event Creation
|
|||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event.
|
--- Creation of a S_EVENT_PLAYER_ENTER_UNIT Event.
|
||||||
-- @param #EVENT self
|
-- @param #EVENT self
|
||||||
-- @param Wrapper.Unit#UNIT PlayerUnit.
|
-- @param Wrapper.Unit#UNIT PlayerUnit.
|
||||||
@@ -955,7 +941,7 @@ do -- Event Creation
|
|||||||
local Event = {
|
local Event = {
|
||||||
id = EVENTS.PlayerEnterUnit,
|
id = EVENTS.PlayerEnterUnit,
|
||||||
time = timer.getTime(),
|
time = timer.getTime(),
|
||||||
initiator = PlayerUnit:GetDCSObject()
|
initiator = PlayerUnit:GetDCSObject(),
|
||||||
}
|
}
|
||||||
|
|
||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
@@ -970,7 +956,7 @@ do -- Event Creation
|
|||||||
local Event = {
|
local Event = {
|
||||||
id = EVENTS.PlayerEnterAircraft,
|
id = EVENTS.PlayerEnterAircraft,
|
||||||
time = timer.getTime(),
|
time = timer.getTime(),
|
||||||
initiator = PlayerUnit:GetDCSObject()
|
initiator = PlayerUnit:GetDCSObject(),
|
||||||
}
|
}
|
||||||
|
|
||||||
world.onEvent( Event )
|
world.onEvent( Event )
|
||||||
@@ -993,14 +979,13 @@ function EVENT:onEvent( Event )
|
|||||||
return errmsg
|
return errmsg
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Get event meta data.
|
-- Get event meta data.
|
||||||
local EventMeta = _EVENTMETA[Event.id]
|
local EventMeta = _EVENTMETA[Event.id]
|
||||||
|
|
||||||
-- Check if this is a known event?
|
-- Check if this is a known event?
|
||||||
if EventMeta then
|
if EventMeta then
|
||||||
|
|
||||||
if self and self.Events and self.Events[Event.id] and self.MissionEnd==false and (Event.initiator~=nil or (Event.initiator==nil and Event.id~=EVENTS.PlayerLeaveUnit)) then
|
if self and self.Events and self.Events[Event.id] and self.MissionEnd == false and (Event.initiator ~= nil or (Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit)) then
|
||||||
|
|
||||||
if Event.id and Event.id == EVENTS.MissionEnd then
|
if Event.id and Event.id == EVENTS.MissionEnd then
|
||||||
self.MissionEnd = true
|
self.MissionEnd = true
|
||||||
@@ -1024,9 +1009,9 @@ function EVENT:onEvent( Event )
|
|||||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
--if Event.IniGroup then
|
-- if Event.IniGroup then
|
||||||
Event.IniGroupName = Event.IniDCSGroupName
|
Event.IniGroupName = Event.IniDCSGroupName
|
||||||
--end
|
-- end
|
||||||
end
|
end
|
||||||
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
|
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
|
||||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||||
@@ -1036,20 +1021,20 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
if Event.IniObjectCategory == Object.Category.STATIC then
|
if Event.IniObjectCategory == Object.Category.STATIC then
|
||||||
|
|
||||||
if Event.id==31 then
|
if Event.id == 31 then
|
||||||
|
|
||||||
-- Event.initiator is a Static object representing the pilot. But getName() errors due to DCS bug.
|
-- Event.initiator is a Static object representing the pilot. But getName() errors due to DCS bug.
|
||||||
Event.IniDCSUnit = Event.initiator
|
Event.IniDCSUnit = Event.initiator
|
||||||
local ID=Event.initiator.id_
|
local ID = Event.initiator.id_
|
||||||
Event.IniDCSUnitName = string.format("Ejected Pilot ID %s", tostring(ID))
|
Event.IniDCSUnitName = string.format( "Ejected Pilot ID %s", tostring( ID ) )
|
||||||
Event.IniUnitName = Event.IniDCSUnitName
|
Event.IniUnitName = Event.IniDCSUnitName
|
||||||
Event.IniCoalition = 0
|
Event.IniCoalition = 0
|
||||||
Event.IniCategory = 0
|
Event.IniCategory = 0
|
||||||
Event.IniTypeName = "Ejected Pilot"
|
Event.IniTypeName = "Ejected Pilot"
|
||||||
elseif Event.id == 33 then -- ejection seat discarded
|
elseif Event.id == 33 then -- ejection seat discarded
|
||||||
Event.IniDCSUnit = Event.initiator
|
Event.IniDCSUnit = Event.initiator
|
||||||
local ID=Event.initiator.id_
|
local ID = Event.initiator.id_
|
||||||
Event.IniDCSUnitName = string.format("Ejection Seat ID %s", tostring(ID))
|
Event.IniDCSUnitName = string.format( "Ejection Seat ID %s", tostring( ID ) )
|
||||||
Event.IniUnitName = Event.IniDCSUnitName
|
Event.IniUnitName = Event.IniDCSUnitName
|
||||||
Event.IniCoalition = 0
|
Event.IniCoalition = 0
|
||||||
Event.IniCategory = 0
|
Event.IniCategory = 0
|
||||||
@@ -1088,7 +1073,7 @@ function EVENT:onEvent( Event )
|
|||||||
Event.IniDCSUnit = Event.initiator
|
Event.IniDCSUnit = Event.initiator
|
||||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||||
Event.IniUnitName = Event.IniDCSUnitName
|
Event.IniUnitName = Event.IniDCSUnitName
|
||||||
Event.IniUnit = AIRBASE:FindByName(Event.IniDCSUnitName)
|
Event.IniUnit = AIRBASE:FindByName( Event.IniDCSUnitName )
|
||||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||||
@@ -1109,9 +1094,9 @@ function EVENT:onEvent( Event )
|
|||||||
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
|
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
|
||||||
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
|
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
|
||||||
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||||
--if Event.TgtGroup then
|
-- if Event.TgtGroup then
|
||||||
Event.TgtGroupName = Event.TgtDCSGroupName
|
Event.TgtGroupName = Event.TgtDCSGroupName
|
||||||
--end
|
-- end
|
||||||
end
|
end
|
||||||
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
|
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
|
||||||
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
||||||
@@ -1130,18 +1115,18 @@ function EVENT:onEvent( Event )
|
|||||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||||
else
|
else
|
||||||
Event.TgtDCSUnitName = string.format("No target object for Event ID %s", tostring(Event.id))
|
Event.TgtDCSUnitName = string.format( "No target object for Event ID %s", tostring( Event.id ) )
|
||||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||||
Event.TgtUnit = nil
|
Event.TgtUnit = nil
|
||||||
Event.TgtCoalition = 0
|
Event.TgtCoalition = 0
|
||||||
Event.TgtCategory = 0
|
Event.TgtCategory = 0
|
||||||
if Event.id == 6 then
|
if Event.id == 6 then
|
||||||
Event.TgtTypeName = "Ejected Pilot"
|
Event.TgtTypeName = "Ejected Pilot"
|
||||||
Event.TgtDCSUnitName = string.format("Ejected Pilot ID %s", tostring(Event.IniDCSUnitName))
|
Event.TgtDCSUnitName = string.format( "Ejected Pilot ID %s", tostring( Event.IniDCSUnitName ) )
|
||||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||||
elseif Event.id == 33 then
|
elseif Event.id == 33 then
|
||||||
Event.TgtTypeName = "Ejection Seat"
|
Event.TgtTypeName = "Ejection Seat"
|
||||||
Event.TgtDCSUnitName = string.format("Ejection Seat ID %s", tostring(Event.IniDCSUnitName))
|
Event.TgtDCSUnitName = string.format( "Ejection Seat ID %s", tostring( Event.IniDCSUnitName ) )
|
||||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||||
else
|
else
|
||||||
Event.TgtTypeName = "Static"
|
Event.TgtTypeName = "Static"
|
||||||
@@ -1167,29 +1152,29 @@ function EVENT:onEvent( Event )
|
|||||||
Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition()
|
Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition()
|
||||||
Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category
|
Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category
|
||||||
Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName()
|
Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName()
|
||||||
--Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
|
-- Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase.
|
-- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase.
|
||||||
if Event.place then
|
if Event.place then
|
||||||
if Event.id==EVENTS.LandingAfterEjection then
|
if Event.id == EVENTS.LandingAfterEjection then
|
||||||
-- Place is here the UNIT of which the pilot ejected.
|
-- Place is here the UNIT of which the pilot ejected.
|
||||||
--local name=Event.place:getName() -- This returns a DCS error "Airbase doesn't exit" :(
|
-- local name=Event.place:getName() -- This returns a DCS error "Airbase doesn't exit" :(
|
||||||
-- However, this is not a big thing, as the aircraft the pilot ejected from is usually long crashed before the ejected pilot touches the ground.
|
-- However, this is not a big thing, as the aircraft the pilot ejected from is usually long crashed before the ejected pilot touches the ground.
|
||||||
--Event.Place=UNIT:Find(Event.place)
|
-- Event.Place=UNIT:Find(Event.place)
|
||||||
else
|
else
|
||||||
Event.Place=AIRBASE:Find(Event.place)
|
Event.Place = AIRBASE:Find( Event.place )
|
||||||
Event.PlaceName=Event.Place:GetName()
|
Event.PlaceName = Event.Place:GetName()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Mark points.
|
-- Mark points.
|
||||||
if Event.idx then
|
if Event.idx then
|
||||||
Event.MarkID=Event.idx
|
Event.MarkID = Event.idx
|
||||||
Event.MarkVec3=Event.pos
|
Event.MarkVec3 = Event.pos
|
||||||
Event.MarkCoordinate=COORDINATE:NewFromVec3(Event.pos)
|
Event.MarkCoordinate = COORDINATE:NewFromVec3( Event.pos )
|
||||||
Event.MarkText=Event.text
|
Event.MarkText = Event.text
|
||||||
Event.MarkCoalition=Event.coalition
|
Event.MarkCoalition = Event.coalition
|
||||||
Event.MarkGroupID = Event.groupID
|
Event.MarkGroupID = Event.groupID
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1218,9 +1203,9 @@ function EVENT:onEvent( Event )
|
|||||||
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
||||||
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
|
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
|
||||||
|
|
||||||
--if Event.IniObjectCategory ~= Object.Category.STATIC then
|
-- if Event.IniObjectCategory ~= Object.Category.STATIC then
|
||||||
-- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
|
-- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
|
||||||
--end
|
-- end
|
||||||
|
|
||||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||||
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||||
@@ -1237,8 +1222,8 @@ function EVENT:onEvent( Event )
|
|||||||
|
|
||||||
local UnitName = EventClass:GetName()
|
local UnitName = EventClass:GetName()
|
||||||
|
|
||||||
if ( EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName ) or
|
if (EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName) or
|
||||||
( EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName ) then
|
(EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName) then
|
||||||
|
|
||||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||||
if EventData.EventFunction then
|
if EventData.EventFunction then
|
||||||
@@ -1247,15 +1232,14 @@ function EVENT:onEvent( Event )
|
|||||||
self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall( function()
|
||||||
function()
|
|
||||||
return EventData.EventFunction( EventClass, Event )
|
return EventData.EventFunction( EventClass, Event )
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||||
local EventFunction = EventClass[ EventMeta.Event ]
|
local EventFunction = EventClass[EventMeta.Event]
|
||||||
if EventFunction and type( EventFunction ) == "function" then
|
if EventFunction and type( EventFunction ) == "function" then
|
||||||
|
|
||||||
-- Now call the default event function.
|
-- Now call the default event function.
|
||||||
@@ -1263,8 +1247,7 @@ function EVENT:onEvent( Event )
|
|||||||
self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall( function()
|
||||||
function()
|
|
||||||
return EventFunction( EventClass, Event )
|
return EventFunction( EventClass, Event )
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
end
|
end
|
||||||
@@ -1290,8 +1273,8 @@ function EVENT:onEvent( Event )
|
|||||||
-- We can get the name of the EventClass, which is now always a GROUP object.
|
-- We can get the name of the EventClass, which is now always a GROUP object.
|
||||||
local GroupName = EventClass:GetName()
|
local GroupName = EventClass:GetName()
|
||||||
|
|
||||||
if ( EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName ) or
|
if (EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName) or
|
||||||
( EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName ) then
|
(EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName) then
|
||||||
|
|
||||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||||
if EventData.EventFunction then
|
if EventData.EventFunction then
|
||||||
@@ -1300,15 +1283,14 @@ function EVENT:onEvent( Event )
|
|||||||
self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall( function()
|
||||||
function()
|
|
||||||
return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||||
local EventFunction = EventClass[ EventMeta.Event ]
|
local EventFunction = EventClass[EventMeta.Event]
|
||||||
if EventFunction and type( EventFunction ) == "function" then
|
if EventFunction and type( EventFunction ) == "function" then
|
||||||
|
|
||||||
-- Now call the default event function.
|
-- Now call the default event function.
|
||||||
@@ -1316,8 +1298,7 @@ function EVENT:onEvent( Event )
|
|||||||
self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
|
self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall( function()
|
||||||
function()
|
|
||||||
return EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
return EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
end
|
end
|
||||||
@@ -1325,7 +1306,7 @@ function EVENT:onEvent( Event )
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
|
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
|
||||||
--self:RemoveEvent( EventClass, Event.id )
|
-- self:RemoveEvent( EventClass, Event.id )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
||||||
@@ -1340,14 +1321,13 @@ function EVENT:onEvent( Event )
|
|||||||
if Event.IniObjectCategory ~= 3 then
|
if Event.IniObjectCategory ~= 3 then
|
||||||
self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
end
|
end
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall( function()
|
||||||
function()
|
|
||||||
return EventData.EventFunction( EventClass, Event )
|
return EventData.EventFunction( EventClass, Event )
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
else
|
else
|
||||||
|
|
||||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||||
local EventFunction = EventClass[ EventMeta.Event ]
|
local EventFunction = EventClass[EventMeta.Event]
|
||||||
if EventFunction and type( EventFunction ) == "function" then
|
if EventFunction and type( EventFunction ) == "function" then
|
||||||
|
|
||||||
-- Now call the default event function.
|
-- Now call the default event function.
|
||||||
@@ -1355,8 +1335,7 @@ function EVENT:onEvent( Event )
|
|||||||
self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||||
end
|
end
|
||||||
|
|
||||||
local Result, Value = xpcall(
|
local Result, Value = xpcall( function()
|
||||||
function()
|
|
||||||
local Result, Value = EventFunction( EventClass, Event )
|
local Result, Value = EventFunction( EventClass, Event )
|
||||||
return Result, Value
|
return Result, Value
|
||||||
end, ErrorHandler )
|
end, ErrorHandler )
|
||||||
@@ -1383,7 +1362,7 @@ function EVENT:onEvent( Event )
|
|||||||
self:T( { EventMeta.Text, Event } )
|
self:T( { EventMeta.Text, Event } )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:E(string.format("WARNING: Could not get EVENTMETA data for event ID=%d! Is this an unknown/new DCS event?", tostring(Event.id)))
|
self:E( string.format( "WARNING: Could not get EVENTMETA data for event ID=%d! Is this an unknown/new DCS event?", tostring( Event.id ) ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
Event = nil
|
Event = nil
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
--
|
--
|
||||||
-- Detailed explanations and API specifics are further below clarified and FSM derived class specifics are described in those class documentation sections.
|
-- Detailed explanations and API specifics are further below clarified and FSM derived class specifics are described in those class documentation sections.
|
||||||
--
|
--
|
||||||
-- ##__Dislaimer:__
|
-- ##__Disclaimer:__
|
||||||
-- The FSM class development is based on a finite state machine implementation made by Conroy Kyle.
|
-- The FSM class development is based on a finite state machine implementation made by Conroy Kyle.
|
||||||
-- The state machine can be found on [github](https://github.com/kyleconroy/lua-state-machine)
|
-- The state machine can be found on [github](https://github.com/kyleconroy/lua-state-machine)
|
||||||
-- I've reworked this development (taken the concept), and created a **hierarchical state machine** out of it, embedded within the DCS simulator.
|
-- I've reworked this development (taken the concept), and created a **hierarchical state machine** out of it, embedded within the DCS simulator.
|
||||||
@@ -69,7 +69,6 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
--
|
|
||||||
-- ### Author: **FlightControl**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions: **funkyfranky**
|
-- ### Contributions: **funkyfranky**
|
||||||
--
|
--
|
||||||
@@ -89,7 +88,6 @@ do -- FSM
|
|||||||
-- @field #string current Current state name.
|
-- @field #string current Current state name.
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
--- A Finite State Machine (FSM) models a process flow that transitions between various **States** through triggered **Events**.
|
--- A Finite State Machine (FSM) models a process flow that transitions between various **States** through triggered **Events**.
|
||||||
--
|
--
|
||||||
-- A FSM can only be in one of a finite number of states.
|
-- A FSM can only be in one of a finite number of states.
|
||||||
@@ -145,12 +143,12 @@ do -- FSM
|
|||||||
-- Most of the time, these Event Triggers are used within the Transition Handler methods, so that a workflow is created running through the state machine.
|
-- Most of the time, these Event Triggers are used within the Transition Handler methods, so that a workflow is created running through the state machine.
|
||||||
--
|
--
|
||||||
-- As explained above, a FSM supports **Linear State Transitions** and **Hierarchical State Transitions**, and both can be mixed to make a comprehensive FSM implementation.
|
-- As explained above, a FSM supports **Linear State Transitions** and **Hierarchical State Transitions**, and both can be mixed to make a comprehensive FSM implementation.
|
||||||
-- The below documentation has a seperate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**.
|
-- The below documentation has a separate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**.
|
||||||
--
|
--
|
||||||
-- ## FSM Linear Transitions
|
-- ## FSM Linear Transitions
|
||||||
--
|
--
|
||||||
-- Linear Transitions are Transition Rules allowing an FSM to transition from one or multiple possible **From** state(s) towards a **To** state upon a Triggered **Event**.
|
-- Linear Transitions are Transition Rules allowing an FSM to transition from one or multiple possible **From** state(s) towards a **To** state upon a Triggered **Event**.
|
||||||
-- The Lineair transition rule evaluation will always be done from the **current state** of the FSM.
|
-- The Linear transition rule evaluation will always be done from the **current state** of the FSM.
|
||||||
-- If no valid Transition Rule can be found in the FSM, the FSM will log an error and stop.
|
-- If no valid Transition Rule can be found in the FSM, the FSM will log an error and stop.
|
||||||
--
|
--
|
||||||
-- ### FSM Transition Rules
|
-- ### FSM Transition Rules
|
||||||
@@ -185,7 +183,7 @@ do -- FSM
|
|||||||
-- * The From states can be **a table of strings**, indicating that the transition rule will be valid **if the current state** of the FSM will be **one of the given From states**.
|
-- * The From states can be **a table of strings**, indicating that the transition rule will be valid **if the current state** of the FSM will be **one of the given From states**.
|
||||||
-- * The From state can be a **"*"**, indicating that **the transition rule will always be valid**, regardless of the current state of the FSM.
|
-- * The From state can be a **"*"**, indicating that **the transition rule will always be valid**, regardless of the current state of the FSM.
|
||||||
--
|
--
|
||||||
-- The below code snippet shows how the two last lines can be rewritten and consensed.
|
-- The below code snippet shows how the two last lines can be rewritten and condensed.
|
||||||
--
|
--
|
||||||
-- FsmSwitch:AddTransition( { "On", "Middle" }, "SwitchOff", "Off" )
|
-- FsmSwitch:AddTransition( { "On", "Middle" }, "SwitchOff", "Off" )
|
||||||
--
|
--
|
||||||
@@ -221,7 +219,7 @@ do -- FSM
|
|||||||
-- * The method **FSM:Event()** triggers an Event that will be processed **synchronously** or **immediately**.
|
-- * The method **FSM:Event()** triggers an Event that will be processed **synchronously** or **immediately**.
|
||||||
-- * The method **FSM:__Event( __seconds__ )** triggers an Event that will be processed **asynchronously** over time, waiting __x seconds__.
|
-- * The method **FSM:__Event( __seconds__ )** triggers an Event that will be processed **asynchronously** over time, waiting __x seconds__.
|
||||||
--
|
--
|
||||||
-- The destinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time.
|
-- The distinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time.
|
||||||
-- Processing will just continue. Synchronous Event Trigger methods are useful to change states of the FSM immediately, but may have a larger processing impact.
|
-- Processing will just continue. Synchronous Event Trigger methods are useful to change states of the FSM immediately, but may have a larger processing impact.
|
||||||
--
|
--
|
||||||
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
|
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
|
||||||
@@ -345,7 +343,6 @@ do -- FSM
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- @field #FSM
|
-- @field #FSM
|
||||||
--
|
|
||||||
FSM = {
|
FSM = {
|
||||||
ClassName = "FSM",
|
ClassName = "FSM",
|
||||||
}
|
}
|
||||||
@@ -379,7 +376,6 @@ do -- FSM
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Sets the start state of the FSM.
|
--- Sets the start state of the FSM.
|
||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @param #string State A string defining the start state.
|
-- @param #string State A string defining the start state.
|
||||||
@@ -388,7 +384,6 @@ do -- FSM
|
|||||||
self.current = State
|
self.current = State
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns the start state of the FSM.
|
--- Returns the start state of the FSM.
|
||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @return #string A string containing the start state.
|
-- @return #string A string containing the start state.
|
||||||
@@ -416,7 +411,6 @@ do -- FSM
|
|||||||
self:_eventmap( self.Events, Transition )
|
self:_eventmap( self.Events, Transition )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns a table of the transition rules defined within the FSM.
|
--- Returns a table of the transition rules defined within the FSM.
|
||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @return #table Transitions.
|
-- @return #table Transitions.
|
||||||
@@ -450,7 +444,6 @@ do -- FSM
|
|||||||
return Process
|
return Process
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns a table of the SubFSM rules defined within the FSM.
|
--- Returns a table of the SubFSM rules defined within the FSM.
|
||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @return #table Sub processes.
|
-- @return #table Sub processes.
|
||||||
@@ -499,7 +492,6 @@ do -- FSM
|
|||||||
return self._EndStates or {}
|
return self._EndStates or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Adds a score for the FSM to be achieved.
|
--- Adds a score for the FSM to be achieved.
|
||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @param #string State is the state of the process when the score needs to be given. (See the relevant state descriptions of the process).
|
-- @param #string State is the state of the process when the score needs to be given. (See the relevant state descriptions of the process).
|
||||||
@@ -572,8 +564,8 @@ do -- FSM
|
|||||||
local Event = EventStructure.Event
|
local Event = EventStructure.Event
|
||||||
local __Event = "__" .. EventStructure.Event
|
local __Event = "__" .. EventStructure.Event
|
||||||
|
|
||||||
self[Event] = self[Event] or self:_create_transition(Event)
|
self[Event] = self[Event] or self:_create_transition( Event )
|
||||||
self[__Event] = self[__Event] or self:_delayed_transition(Event)
|
self[__Event] = self[__Event] or self:_delayed_transition( Event )
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
self:T2( "Added methods: " .. Event .. ", " .. __Event )
|
self:T2( "Added methods: " .. Event .. ", " .. __Event )
|
||||||
@@ -613,7 +605,7 @@ do -- FSM
|
|||||||
-- @param #string EventName Event name.
|
-- @param #string EventName Event name.
|
||||||
-- @return Value.
|
-- @return Value.
|
||||||
function FSM:_call_handler( step, trigger, params, EventName )
|
function FSM:_call_handler( step, trigger, params, EventName )
|
||||||
--env.info(string.format("FF T=%.3f _call_handler step=%s, trigger=%s, event=%s", timer.getTime(), step, trigger, EventName))
|
-- env.info(string.format("FF T=%.3f _call_handler step=%s, trigger=%s, event=%s", timer.getTime(), step, trigger, EventName))
|
||||||
|
|
||||||
local handler = step .. trigger
|
local handler = step .. trigger
|
||||||
|
|
||||||
@@ -644,10 +636,12 @@ do -- FSM
|
|||||||
return errmsg
|
return errmsg
|
||||||
end
|
end
|
||||||
|
|
||||||
--return self[handler](self, unpack( params ))
|
-- return self[handler](self, unpack( params ))
|
||||||
|
|
||||||
-- Protected call.
|
-- Protected call.
|
||||||
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler )
|
local Result, Value = xpcall( function()
|
||||||
|
return self[handler]( self, unpack( params ) )
|
||||||
|
end, ErrorHandler )
|
||||||
return Value
|
return Value
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -673,15 +667,14 @@ do -- FSM
|
|||||||
-- Parameters.
|
-- Parameters.
|
||||||
local Params = { From, EventName, To, ... }
|
local Params = { From, EventName, To, ... }
|
||||||
|
|
||||||
|
if self["onleave" .. From] or
|
||||||
if self["onleave".. From] or
|
self["OnLeave" .. From] or
|
||||||
self["OnLeave".. From] or
|
self["onbefore" .. EventName] or
|
||||||
self["onbefore".. EventName] or
|
self["OnBefore" .. EventName] or
|
||||||
self["OnBefore".. EventName] or
|
self["onafter" .. EventName] or
|
||||||
self["onafter".. EventName] or
|
self["OnAfter" .. EventName] or
|
||||||
self["OnAfter".. EventName] or
|
self["onenter" .. To] or
|
||||||
self["onenter".. To] or
|
self["OnEnter" .. To] then
|
||||||
self["OnEnter".. To] then
|
|
||||||
|
|
||||||
if self:_call_handler( "onbefore", EventName, Params, EventName ) == false then
|
if self:_call_handler( "onbefore", EventName, Params, EventName ) == false then
|
||||||
self:T( "*** FSM *** Cancel" .. " *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** onbefore" .. EventName )
|
self:T( "*** FSM *** Cancel" .. " *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** onbefore" .. EventName )
|
||||||
@@ -733,10 +726,10 @@ do -- FSM
|
|||||||
|
|
||||||
for _, sub in pairs( subtable ) do
|
for _, sub in pairs( subtable ) do
|
||||||
|
|
||||||
--if sub.nextevent then
|
-- if sub.nextevent then
|
||||||
-- self:F2( "nextevent = " .. sub.nextevent )
|
-- self:F2( "nextevent = " .. sub.nextevent )
|
||||||
-- self[sub.nextevent]( self )
|
-- self[sub.nextevent]( self )
|
||||||
--end
|
-- end
|
||||||
|
|
||||||
self:T( "*** FSM *** Sub *** " .. sub.StartEvent )
|
self:T( "*** FSM *** Sub *** " .. sub.StartEvent )
|
||||||
|
|
||||||
@@ -753,11 +746,11 @@ do -- FSM
|
|||||||
|
|
||||||
self:T( "*** FSM *** End *** " .. Event )
|
self:T( "*** FSM *** End *** " .. Event )
|
||||||
|
|
||||||
self:_call_handler("onenter", To, Params, EventName )
|
self:_call_handler( "onenter", To, Params, EventName )
|
||||||
self:_call_handler("OnEnter", To, Params, EventName )
|
self:_call_handler( "OnEnter", To, Params, EventName )
|
||||||
self:_call_handler("onafter", EventName, Params, EventName )
|
self:_call_handler( "onafter", EventName, Params, EventName )
|
||||||
self:_call_handler("OnAfter", EventName, Params, EventName )
|
self:_call_handler( "OnAfter", EventName, Params, EventName )
|
||||||
self:_call_handler("onstate", "change", Params, EventName )
|
self:_call_handler( "onstate", "change", Params, EventName )
|
||||||
|
|
||||||
fsmparent[Event]( fsmparent )
|
fsmparent[Event]( fsmparent )
|
||||||
|
|
||||||
@@ -766,13 +759,13 @@ do -- FSM
|
|||||||
|
|
||||||
if execute then
|
if execute then
|
||||||
|
|
||||||
self:_call_handler("onafter", EventName, Params, EventName )
|
self:_call_handler( "onafter", EventName, Params, EventName )
|
||||||
self:_call_handler("OnAfter", EventName, Params, EventName )
|
self:_call_handler( "OnAfter", EventName, Params, EventName )
|
||||||
|
|
||||||
self:_call_handler("onenter", To, Params, EventName )
|
self:_call_handler( "onenter", To, Params, EventName )
|
||||||
self:_call_handler("OnEnter", To, Params, EventName )
|
self:_call_handler( "OnEnter", To, Params, EventName )
|
||||||
|
|
||||||
self:_call_handler("onstate", "change", Params, EventName )
|
self:_call_handler( "onstate", "change", Params, EventName )
|
||||||
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -809,16 +802,16 @@ do -- FSM
|
|||||||
self._EventSchedules[EventName] = CallID
|
self._EventSchedules[EventName] = CallID
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
self:T2(string.format("NEGATIVE Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring(CallID)))
|
self:T2( string.format( "NEGATIVE Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring( CallID ) ) )
|
||||||
else
|
else
|
||||||
self:T2(string.format("NEGATIVE Event %s delayed by %.1f sec CANCELLED as we already have such an event in the queue.", EventName, DelaySeconds))
|
self:T2( string.format( "NEGATIVE Event %s delayed by %.1f sec CANCELLED as we already have such an event in the queue.", EventName, DelaySeconds ) )
|
||||||
-- reschedule
|
-- reschedule
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
||||||
CallID = self.CallScheduler:Schedule( self, self._handler, { EventName, ... }, DelaySeconds or 1, nil, nil, nil, 4, true )
|
CallID = self.CallScheduler:Schedule( self, self._handler, { EventName, ... }, DelaySeconds or 1, nil, nil, nil, 4, true )
|
||||||
|
|
||||||
self:T2(string.format("Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring(CallID)))
|
self:T2( string.format( "Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring( CallID ) ) )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error( "FSM: An asynchronous event trigger requires a DelaySeconds parameter!!! This can be positive or negative! Sorry, but will not process this." )
|
error( "FSM: An asynchronous event trigger requires a DelaySeconds parameter!!! This can be positive or negative! Sorry, but will not process this." )
|
||||||
@@ -835,7 +828,9 @@ do -- FSM
|
|||||||
-- @param #string EventName Event name.
|
-- @param #string EventName Event name.
|
||||||
-- @return #function Function.
|
-- @return #function Function.
|
||||||
function FSM:_create_transition( EventName )
|
function FSM:_create_transition( EventName )
|
||||||
return function( self, ... ) return self._handler( self, EventName , ... ) end
|
return function( self, ... )
|
||||||
|
return self._handler( self, EventName, ... )
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Go sub.
|
--- Go sub.
|
||||||
@@ -862,16 +857,16 @@ do -- FSM
|
|||||||
local FSMParent = self.fsmparent
|
local FSMParent = self.fsmparent
|
||||||
|
|
||||||
if FSMParent and self.endstates[Current] then
|
if FSMParent and self.endstates[Current] then
|
||||||
--self:T( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
-- self:T( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||||
FSMParent.current = Current
|
FSMParent.current = Current
|
||||||
local ParentFrom = FSMParent.current
|
local ParentFrom = FSMParent.current
|
||||||
--self:T( { ParentFrom, self.ReturnEvents } )
|
-- self:T( { ParentFrom, self.ReturnEvents } )
|
||||||
local Event = self.ReturnEvents[Current]
|
local Event = self.ReturnEvents[Current]
|
||||||
--self:T( { Event } )
|
-- self:T( { Event } )
|
||||||
if Event then
|
if Event then
|
||||||
return FSMParent, Event
|
return FSMParent, Event
|
||||||
else
|
else
|
||||||
--self:T( { "Could not find parent event name for state ", ParentFrom } )
|
-- self:T( { "Could not find parent event name for state ", ParentFrom } )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -885,10 +880,10 @@ do -- FSM
|
|||||||
function FSM:_add_to_map( Map, Event )
|
function FSM:_add_to_map( Map, Event )
|
||||||
self:F3( { Map, Event } )
|
self:F3( { Map, Event } )
|
||||||
|
|
||||||
if type(Event.From) == 'string' then
|
if type( Event.From ) == 'string' then
|
||||||
Map[Event.From] = Event.To
|
Map[Event.From] = Event.To
|
||||||
else
|
else
|
||||||
for _, From in ipairs(Event.From) do
|
for _, From in ipairs( Event.From ) do
|
||||||
Map[From] = Event.To
|
Map[From] = Event.To
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -922,7 +917,7 @@ do -- FSM
|
|||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @param #string State State name.
|
-- @param #string State State name.
|
||||||
-- @param #boolean If true, FSM is in this state.
|
-- @param #boolean If true, FSM is in this state.
|
||||||
function FSM:is(state)
|
function FSM:is( state )
|
||||||
return self.current == state
|
return self.current == state
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -931,11 +926,11 @@ do -- FSM
|
|||||||
-- @param #string e Event name.
|
-- @param #string e Event name.
|
||||||
-- @return #boolean If true, FSM can do the event.
|
-- @return #boolean If true, FSM can do the event.
|
||||||
-- @return #string To state.
|
-- @return #string To state.
|
||||||
function FSM:can(e)
|
function FSM:can( e )
|
||||||
|
|
||||||
local Event = self.Events[e]
|
local Event = self.Events[e]
|
||||||
|
|
||||||
--self:F3( { self.current, Event } )
|
-- self:F3( { self.current, Event } )
|
||||||
|
|
||||||
local To = Event and Event.map[self.current] or Event.map['*']
|
local To = Event and Event.map[self.current] or Event.map['*']
|
||||||
|
|
||||||
@@ -946,8 +941,8 @@ do -- FSM
|
|||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @param #string e Event name.
|
-- @param #string e Event name.
|
||||||
-- @return #boolean If true, FSM cannot do the event.
|
-- @return #boolean If true, FSM cannot do the event.
|
||||||
function FSM:cannot(e)
|
function FSM:cannot( e )
|
||||||
return not self:can(e)
|
return not self:can( e )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1036,7 +1031,7 @@ do -- FSM_CONTROLLABLE
|
|||||||
-- @param #string From The From State string.
|
-- @param #string From The From State string.
|
||||||
-- @param #string Event The Event string.
|
-- @param #string Event The Event string.
|
||||||
-- @param #string To The To State string.
|
-- @param #string To The To State string.
|
||||||
function FSM_CONTROLLABLE:OnAfterStop(Controllable,From,Event,To)
|
function FSM_CONTROLLABLE:OnAfterStop( Controllable, From, Event, To )
|
||||||
|
|
||||||
-- Clear all pending schedules
|
-- Clear all pending schedules
|
||||||
self.CallScheduler:Clear()
|
self.CallScheduler:Clear()
|
||||||
@@ -1047,7 +1042,7 @@ do -- FSM_CONTROLLABLE
|
|||||||
-- @param Wrapper.Controllable#CONTROLLABLE FSMControllable
|
-- @param Wrapper.Controllable#CONTROLLABLE FSMControllable
|
||||||
-- @return #FSM_CONTROLLABLE
|
-- @return #FSM_CONTROLLABLE
|
||||||
function FSM_CONTROLLABLE:SetControllable( FSMControllable )
|
function FSM_CONTROLLABLE:SetControllable( FSMControllable )
|
||||||
--self:F( FSMControllable:GetName() )
|
-- self:F( FSMControllable:GetName() )
|
||||||
self.Controllable = FSMControllable
|
self.Controllable = FSMControllable
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1075,9 +1070,11 @@ do -- FSM_CONTROLLABLE
|
|||||||
if self[handler] then
|
if self[handler] then
|
||||||
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** TaskUnit: " .. self.Controllable:GetName() )
|
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** TaskUnit: " .. self.Controllable:GetName() )
|
||||||
self._EventSchedules[EventName] = nil
|
self._EventSchedules[EventName] = nil
|
||||||
local Result, Value = xpcall( function() return self[handler]( self, self.Controllable, unpack( params ) ) end, ErrorHandler )
|
local Result, Value = xpcall( function()
|
||||||
|
return self[handler]( self, self.Controllable, unpack( params ) )
|
||||||
|
end, ErrorHandler )
|
||||||
return Value
|
return Value
|
||||||
--return self[handler]( self, self.Controllable, unpack( params ) )
|
-- return self[handler]( self, self.Controllable, unpack( params ) )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1089,16 +1086,13 @@ do -- FSM_PROCESS
|
|||||||
-- @field Tasking.Task#TASK Task
|
-- @field Tasking.Task#TASK Task
|
||||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||||
|
|
||||||
|
|
||||||
--- FSM_PROCESS class models Finite State Machines for @{Task} actions, which control @{Client}s.
|
--- FSM_PROCESS class models Finite State Machines for @{Task} actions, which control @{Client}s.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- @field #FSM_PROCESS FSM_PROCESS
|
-- @field #FSM_PROCESS FSM_PROCESS
|
||||||
--
|
--
|
||||||
FSM_PROCESS = {
|
FSM_PROCESS = { ClassName = "FSM_PROCESS" }
|
||||||
ClassName = "FSM_PROCESS",
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Creates a new FSM_PROCESS object.
|
--- Creates a new FSM_PROCESS object.
|
||||||
-- @param #FSM_PROCESS self
|
-- @param #FSM_PROCESS self
|
||||||
@@ -1107,7 +1101,7 @@ do -- FSM_PROCESS
|
|||||||
|
|
||||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- Core.Fsm#FSM_PROCESS
|
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- Core.Fsm#FSM_PROCESS
|
||||||
|
|
||||||
--self:F( Controllable )
|
-- self:F( Controllable )
|
||||||
|
|
||||||
self:Assign( Controllable, Task )
|
self:Assign( Controllable, Task )
|
||||||
|
|
||||||
@@ -1139,10 +1133,12 @@ do -- FSM_PROCESS
|
|||||||
self._EventSchedules[EventName] = nil
|
self._EventSchedules[EventName] = nil
|
||||||
local Result, Value
|
local Result, Value
|
||||||
if self.Controllable and self.Controllable:IsAlive() == true then
|
if self.Controllable and self.Controllable:IsAlive() == true then
|
||||||
Result, Value = xpcall( function() return self[handler]( self, self.Controllable, self.Task, unpack( params ) ) end, ErrorHandler )
|
Result, Value = xpcall( function()
|
||||||
|
return self[handler]( self, self.Controllable, self.Task, unpack( params ) )
|
||||||
|
end, ErrorHandler )
|
||||||
end
|
end
|
||||||
return Value
|
return Value
|
||||||
--return self[handler]( self, self.Controllable, unpack( params ) )
|
-- return self[handler]( self, self.Controllable, unpack( params ) )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1152,7 +1148,6 @@ do -- FSM_PROCESS
|
|||||||
function FSM_PROCESS:Copy( Controllable, Task )
|
function FSM_PROCESS:Copy( Controllable, Task )
|
||||||
self:T( { self:GetClassNameAndID() } )
|
self:T( { self:GetClassNameAndID() } )
|
||||||
|
|
||||||
|
|
||||||
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
|
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
|
||||||
|
|
||||||
NewFsm:Assign( Controllable, Task )
|
NewFsm:Assign( Controllable, Task )
|
||||||
@@ -1170,7 +1165,7 @@ do -- FSM_PROCESS
|
|||||||
|
|
||||||
-- Copy Processes
|
-- Copy Processes
|
||||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||||
--self:E( { Process:GetName() } )
|
-- self:E( { Process:GetName() } )
|
||||||
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
|
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1244,7 +1239,7 @@ do -- FSM_PROCESS
|
|||||||
return self:GetTask():GetMission():GetCommandCenter()
|
return self:GetTask():GetMission():GetCommandCenter()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: Need to check and fix that an FSM_PROCESS is only for a UNIT. Not for a GROUP.
|
-- TODO: Need to check and fix that an FSM_PROCESS is only for a UNIT. Not for a GROUP.
|
||||||
|
|
||||||
--- Send a message of the @{Task} to the Group of the Unit.
|
--- Send a message of the @{Task} to the Group of the Unit.
|
||||||
-- @param #FSM_PROCESS self
|
-- @param #FSM_PROCESS self
|
||||||
@@ -1263,32 +1258,29 @@ do -- FSM_PROCESS
|
|||||||
CC:MessageToGroup( Message, TaskGroup )
|
CC:MessageToGroup( Message, TaskGroup )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Assign the process to a @{Wrapper.Unit} and activate the process.
|
--- Assign the process to a @{Wrapper.Unit} and activate the process.
|
||||||
-- @param #FSM_PROCESS self
|
-- @param #FSM_PROCESS self
|
||||||
-- @param Task.Tasking#TASK Task
|
-- @param Task.Tasking#TASK Task
|
||||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||||
-- @return #FSM_PROCESS self
|
-- @return #FSM_PROCESS self
|
||||||
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
||||||
--self:T( { Task:GetName(), ProcessUnit:GetName() } )
|
-- self:T( { Task:GetName(), ProcessUnit:GetName() } )
|
||||||
|
|
||||||
self:SetControllable( ProcessUnit )
|
self:SetControllable( ProcessUnit )
|
||||||
self:SetTask( Task )
|
self:SetTask( Task )
|
||||||
|
|
||||||
--self.ProcessGroup = ProcessUnit:GetGroup()
|
-- self.ProcessGroup = ProcessUnit:GetGroup()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- function FSM_PROCESS:onenterAssigned( ProcessUnit, Task, From, Event, To )
|
-- function FSM_PROCESS:onenterAssigned( ProcessUnit, Task, From, Event, To )
|
||||||
--
|
--
|
||||||
-- if From( "Planned" ) then
|
-- if From( "Planned" ) then
|
||||||
-- self:T( "*** FSM *** Assign *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
-- self:T( "*** FSM *** Assign *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
||||||
-- self.Task:Assign()
|
-- self.Task:Assign()
|
||||||
-- end
|
-- end
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
function FSM_PROCESS:onenterFailed( ProcessUnit, Task, From, Event, To )
|
function FSM_PROCESS:onenterFailed( ProcessUnit, Task, From, Event, To )
|
||||||
self:T( "*** FSM *** Failed *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
self:T( "*** FSM *** Failed *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
||||||
@@ -1296,7 +1288,6 @@ do -- FSM_PROCESS
|
|||||||
self.Task:Fail()
|
self.Task:Fail()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- StateMachine callback function for a FSM_PROCESS
|
--- StateMachine callback function for a FSM_PROCESS
|
||||||
-- @param #FSM_PROCESS self
|
-- @param #FSM_PROCESS self
|
||||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||||
@@ -1309,10 +1300,10 @@ do -- FSM_PROCESS
|
|||||||
self:T( "*** FSM *** Change *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
self:T( "*** FSM *** Change *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if self:IsTrace() then
|
-- if self:IsTrace() then
|
||||||
-- MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
-- MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
||||||
-- self:F2( { Scores = self._Scores, To = To } )
|
-- self:F2( { Scores = self._Scores, To = To } )
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- TODO: This needs to be reworked with a callback functions allocated within Task, and set within the mission script from the Task Objects...
|
-- TODO: This needs to be reworked with a callback functions allocated within Task, and set within the mission script from the Task Objects...
|
||||||
if self._Scores[To] then
|
if self._Scores[To] then
|
||||||
@@ -1374,8 +1365,10 @@ do -- FSM_TASK
|
|||||||
if self[handler] then
|
if self[handler] then
|
||||||
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** Task: " .. self.TaskName )
|
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** Task: " .. self.TaskName )
|
||||||
self._EventSchedules[EventName] = nil
|
self._EventSchedules[EventName] = nil
|
||||||
--return self[handler]( self, unpack( params ) )
|
-- return self[handler]( self, unpack( params ) )
|
||||||
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler )
|
local Result, Value = xpcall( function()
|
||||||
|
return self[handler]( self, unpack( params ) )
|
||||||
|
end, ErrorHandler )
|
||||||
return Value
|
return Value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -1389,14 +1382,12 @@ do -- FSM_SET
|
|||||||
-- @field Core.Set#SET_BASE Set
|
-- @field Core.Set#SET_BASE Set
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
|
||||||
--- FSM_SET class models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
|
--- FSM_SET class models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
|
||||||
-- for multiple objects or the position of the state machine in the process.
|
-- for multiple objects or the position of the state machine in the process.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- @field #FSM_SET FSM_SET
|
-- @field #FSM_SET FSM_SET
|
||||||
--
|
|
||||||
FSM_SET = {
|
FSM_SET = {
|
||||||
ClassName = "FSM_SET",
|
ClassName = "FSM_SET",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,13 +22,11 @@
|
|||||||
-- @module Core.Goal
|
-- @module Core.Goal
|
||||||
-- @image Core_Goal.JPG
|
-- @image Core_Goal.JPG
|
||||||
|
|
||||||
|
|
||||||
do -- Goal
|
do -- Goal
|
||||||
|
|
||||||
--- @type GOAL
|
--- @type GOAL
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
|
||||||
--- Models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
|
--- Models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
|
||||||
--
|
--
|
||||||
-- # 1. GOAL constructor
|
-- # 1. GOAL constructor
|
||||||
@@ -105,7 +103,6 @@ do -- Goal
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
|
|
||||||
|
|
||||||
self:SetStartState( "Pending" )
|
self:SetStartState( "Pending" )
|
||||||
self:AddTransition( "*", "Achieved", "Achieved" )
|
self:AddTransition( "*", "Achieved", "Achieved" )
|
||||||
|
|
||||||
@@ -138,25 +135,22 @@ do -- Goal
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Add a new contribution by a player.
|
--- Add a new contribution by a player.
|
||||||
-- @param #GOAL self
|
-- @param #GOAL self
|
||||||
-- @param #string PlayerName The name of the player.
|
-- @param #string PlayerName The name of the player.
|
||||||
function GOAL:AddPlayerContribution( PlayerName )
|
function GOAL:AddPlayerContribution( PlayerName )
|
||||||
self:F({PlayerName})
|
self:F( { PlayerName } )
|
||||||
self.Players[PlayerName] = self.Players[PlayerName] or 0
|
self.Players[PlayerName] = self.Players[PlayerName] or 0
|
||||||
self.Players[PlayerName] = self.Players[PlayerName] + 1
|
self.Players[PlayerName] = self.Players[PlayerName] + 1
|
||||||
self.TotalContributions = self.TotalContributions + 1
|
self.TotalContributions = self.TotalContributions + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #GOAL self
|
--- @param #GOAL self
|
||||||
-- @param #number Player contribution.
|
-- @param #number Player contribution.
|
||||||
function GOAL:GetPlayerContribution( PlayerName )
|
function GOAL:GetPlayerContribution( PlayerName )
|
||||||
return self.Players[PlayerName] or 0
|
return self.Players[PlayerName] or 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get the players who contributed to achieve the goal.
|
--- Get the players who contributed to achieve the goal.
|
||||||
-- The result is a list of players, sorted by the name of the players.
|
-- The result is a list of players, sorted by the name of the players.
|
||||||
-- @param #GOAL self
|
-- @param #GOAL self
|
||||||
@@ -165,7 +159,6 @@ do -- Goal
|
|||||||
return self.Players or {}
|
return self.Players or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Gets the total contributions that happened to achieve the goal.
|
--- Gets the total contributions that happened to achieve the goal.
|
||||||
-- The result is a number.
|
-- The result is a number.
|
||||||
-- @param #GOAL self
|
-- @param #GOAL self
|
||||||
@@ -174,8 +167,6 @@ do -- Goal
|
|||||||
return self.TotalContributions or 0
|
return self.TotalContributions or 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Validates if the goal is achieved.
|
--- Validates if the goal is achieved.
|
||||||
-- @param #GOAL self
|
-- @param #GOAL self
|
||||||
-- @return #boolean true if the goal is achieved.
|
-- @return #boolean true if the goal is achieved.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
-- * Only create or delete menus when required, and keep existing menus persistent.
|
-- * Only create or delete menus when required, and keep existing menus persistent.
|
||||||
-- * Update menu structures.
|
-- * Update menu structures.
|
||||||
-- * Refresh menu structures intelligently, based on a time stamp of updates.
|
-- * Refresh menu structures intelligently, based on a time stamp of updates.
|
||||||
-- - Delete obscolete menus.
|
-- - Delete obsolete menus.
|
||||||
-- - Create new one where required.
|
-- - Create new one where required.
|
||||||
-- - Don't touch the existing ones.
|
-- - Don't touch the existing ones.
|
||||||
-- * Provide a variable amount of parameters to menus.
|
-- * Provide a variable amount of parameters to menus.
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
-- * Provide a great tool to manage menus in your code.
|
-- * Provide a great tool to manage menus in your code.
|
||||||
--
|
--
|
||||||
-- DCS Menus can be managed using the MENU classes.
|
-- DCS Menus can be managed using the MENU classes.
|
||||||
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scanerios where you need to
|
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scenarios where you need to
|
||||||
-- set menus and later remove them, and later set them again. You'll find while using use normal DCS scripting functions, that setting and removing
|
-- set menus and later remove them, and later set them again. You'll find while using use normal DCS scripting functions, that setting and removing
|
||||||
-- menus is not a easy feat if you have complex menu hierarchies defined.
|
-- menus is not a easy feat if you have complex menu hierarchies defined.
|
||||||
-- Using the MOOSE menu classes, the removal and refreshing of menus are nicely being handled within these classes, and becomes much more easy.
|
-- Using the MOOSE menu classes, the removal and refreshing of menus are nicely being handled within these classes, and becomes much more easy.
|
||||||
@@ -53,7 +53,6 @@
|
|||||||
-- @module Core.Menu
|
-- @module Core.Menu
|
||||||
-- @image Core_Menu.JPG
|
-- @image Core_Menu.JPG
|
||||||
|
|
||||||
|
|
||||||
MENU_INDEX = {}
|
MENU_INDEX = {}
|
||||||
MENU_INDEX.MenuMission = {}
|
MENU_INDEX.MenuMission = {}
|
||||||
MENU_INDEX.MenuMission.Menus = {}
|
MENU_INDEX.MenuMission.Menus = {}
|
||||||
@@ -64,8 +63,6 @@ MENU_INDEX.Coalition[coalition.side.RED] = {}
|
|||||||
MENU_INDEX.Coalition[coalition.side.RED].Menus = {}
|
MENU_INDEX.Coalition[coalition.side.RED].Menus = {}
|
||||||
MENU_INDEX.Group = {}
|
MENU_INDEX.Group = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function MENU_INDEX:ParentPath( ParentMenu, MenuText )
|
function MENU_INDEX:ParentPath( ParentMenu, MenuText )
|
||||||
|
|
||||||
local Path = ParentMenu and "@" .. table.concat( ParentMenu.MenuPath or {}, "@" ) or ""
|
local Path = ParentMenu and "@" .. table.concat( ParentMenu.MenuPath or {}, "@" ) or ""
|
||||||
@@ -98,12 +95,10 @@ function MENU_INDEX:ParentPath( ParentMenu, MenuText )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MENU_INDEX:PrepareMission()
|
function MENU_INDEX:PrepareMission()
|
||||||
self.MenuMission.Menus = self.MenuMission.Menus or {}
|
self.MenuMission.Menus = self.MenuMission.Menus or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MENU_INDEX:PrepareCoalition( CoalitionSide )
|
function MENU_INDEX:PrepareCoalition( CoalitionSide )
|
||||||
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
|
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
|
||||||
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
|
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
|
||||||
@@ -119,8 +114,6 @@ function MENU_INDEX:PrepareGroup( Group )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function MENU_INDEX:HasMissionMenu( Path )
|
function MENU_INDEX:HasMissionMenu( Path )
|
||||||
|
|
||||||
return self.MenuMission.Menus[Path]
|
return self.MenuMission.Menus[Path]
|
||||||
@@ -136,8 +129,6 @@ function MENU_INDEX:ClearMissionMenu( Path )
|
|||||||
self.MenuMission.Menus[Path] = nil
|
self.MenuMission.Menus[Path] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
|
function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
|
||||||
|
|
||||||
return self.Coalition[Coalition].Menus[Path]
|
return self.Coalition[Coalition].Menus[Path]
|
||||||
@@ -153,8 +144,6 @@ function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
|
|||||||
self.Coalition[Coalition].Menus[Path] = nil
|
self.Coalition[Coalition].Menus[Path] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function MENU_INDEX:HasGroupMenu( Group, Path )
|
function MENU_INDEX:HasGroupMenu( Group, Path )
|
||||||
if Group and Group:IsAlive() then
|
if Group and Group:IsAlive() then
|
||||||
local MenuGroupName = Group:GetName()
|
local MenuGroupName = Group:GetName()
|
||||||
@@ -166,7 +155,7 @@ end
|
|||||||
function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
|
function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
|
||||||
|
|
||||||
local MenuGroupName = Group:GetName()
|
local MenuGroupName = Group:GetName()
|
||||||
Group:F({MenuGroupName=MenuGroupName,Path=Path})
|
Group:F( { MenuGroupName = MenuGroupName, Path = Path } )
|
||||||
self.Group[MenuGroupName].Menus[Path] = Menu
|
self.Group[MenuGroupName].Menus[Path] = Menu
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -197,17 +186,10 @@ function MENU_INDEX:Refresh( Group )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do -- MENU_BASE
|
do -- MENU_BASE
|
||||||
|
|
||||||
--- @type MENU_BASE
|
--- @type MENU_BASE
|
||||||
-- @extends Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- Defines the main MENU class where other MENU classes are derived from.
|
--- Defines the main MENU class where other MENU classes are derived from.
|
||||||
-- This is an abstract class, so don't use it.
|
-- This is an abstract class, so don't use it.
|
||||||
@@ -216,10 +198,10 @@ do -- MENU_BASE
|
|||||||
ClassName = "MENU_BASE",
|
ClassName = "MENU_BASE",
|
||||||
MenuPath = nil,
|
MenuPath = nil,
|
||||||
MenuText = "",
|
MenuText = "",
|
||||||
MenuParentPath = nil
|
MenuParentPath = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Consructor
|
--- Constructor
|
||||||
-- @param #MENU_BASE
|
-- @param #MENU_BASE
|
||||||
-- @return #MENU_BASE
|
-- @return #MENU_BASE
|
||||||
function MENU_BASE:New( MenuText, ParentMenu )
|
function MENU_BASE:New( MenuText, ParentMenu )
|
||||||
@@ -235,7 +217,7 @@ do -- MENU_BASE
|
|||||||
self.MenuText = MenuText
|
self.MenuText = MenuText
|
||||||
self.ParentMenu = ParentMenu
|
self.ParentMenu = ParentMenu
|
||||||
self.MenuParentPath = MenuParentPath
|
self.MenuParentPath = MenuParentPath
|
||||||
self.Path = ( self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "" ) .. "@" .. self.MenuText
|
self.Path = (self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "") .. "@" .. self.MenuText
|
||||||
self.Menus = {}
|
self.Menus = {}
|
||||||
self.MenuCount = 0
|
self.MenuCount = 0
|
||||||
self.MenuStamp = timer.getTime()
|
self.MenuStamp = timer.getTime()
|
||||||
@@ -262,7 +244,7 @@ do -- MENU_BASE
|
|||||||
self.ParentMenu.Menus[MenuText] = nil
|
self.ParentMenu.Menus[MenuText] = nil
|
||||||
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1
|
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1
|
||||||
if self.ParentMenu.MenuCount == 0 then
|
if self.ParentMenu.MenuCount == 0 then
|
||||||
--self.ParentMenu:Remove()
|
-- self.ParentMenu:Remove()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -272,12 +254,11 @@ do -- MENU_BASE
|
|||||||
-- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}.
|
-- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}.
|
||||||
-- @return #MENU_BASE
|
-- @return #MENU_BASE
|
||||||
function MENU_BASE:SetRemoveParent( RemoveParent )
|
function MENU_BASE:SetRemoveParent( RemoveParent )
|
||||||
--self:F( { RemoveParent } )
|
-- self:F( { RemoveParent } )
|
||||||
self.MenuRemoveParent = RemoveParent
|
self.MenuRemoveParent = RemoveParent
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Gets a @{Menu} from a parent @{Menu}
|
--- Gets a @{Menu} from a parent @{Menu}
|
||||||
-- @param #MENU_BASE self
|
-- @param #MENU_BASE self
|
||||||
-- @param #string MenuText The text of the child menu.
|
-- @param #string MenuText The text of the child menu.
|
||||||
@@ -295,7 +276,6 @@ do -- MENU_BASE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Gets a menu stamp for later prevention of menu removal.
|
--- Gets a menu stamp for later prevention of menu removal.
|
||||||
-- @param #MENU_BASE self
|
-- @param #MENU_BASE self
|
||||||
-- @return MenuStamp
|
-- @return MenuStamp
|
||||||
@@ -303,7 +283,6 @@ do -- MENU_BASE
|
|||||||
return timer.getTime()
|
return timer.getTime()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Sets a time stamp for later prevention of menu removal.
|
--- Sets a time stamp for later prevention of menu removal.
|
||||||
-- @param #MENU_BASE self
|
-- @param #MENU_BASE self
|
||||||
-- @param MenuStamp
|
-- @param MenuStamp
|
||||||
@@ -394,7 +373,6 @@ do -- MENU_COMMAND_BASE
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- MENU_MISSION
|
do -- MENU_MISSION
|
||||||
|
|
||||||
--- @type MENU_MISSION
|
--- @type MENU_MISSION
|
||||||
@@ -406,13 +384,13 @@ do -- MENU_MISSION
|
|||||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION.Remove}.
|
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION.Remove}.
|
||||||
-- @field #MENU_MISSION
|
-- @field #MENU_MISSION
|
||||||
MENU_MISSION = {
|
MENU_MISSION = {
|
||||||
ClassName = "MENU_MISSION"
|
ClassName = "MENU_MISSION",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- MENU_MISSION constructor. Creates a new MENU_MISSION object and creates the menu for a complete mission file.
|
--- MENU_MISSION constructor. Creates a new MENU_MISSION object and creates the menu for a complete mission file.
|
||||||
-- @param #MENU_MISSION self
|
-- @param #MENU_MISSION self
|
||||||
-- @param #string MenuText The text for the menu.
|
-- @param #string MenuText The text for the menu.
|
||||||
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
|
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
|
||||||
-- @return #MENU_MISSION
|
-- @return #MENU_MISSION
|
||||||
function MENU_MISSION:New( MenuText, ParentMenu )
|
function MENU_MISSION:New( MenuText, ParentMenu )
|
||||||
|
|
||||||
@@ -470,7 +448,7 @@ do -- MENU_MISSION
|
|||||||
if MissionMenu == self then
|
if MissionMenu == self then
|
||||||
self:RemoveSubMenus()
|
self:RemoveSubMenus()
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
self:F( { Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Text = self.MenuText, Path = self.MenuPath } )
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
missionCommands.removeItem( self.MenuPath )
|
missionCommands.removeItem( self.MenuPath )
|
||||||
@@ -487,8 +465,6 @@ do -- MENU_MISSION
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- MENU_MISSION_COMMAND
|
do -- MENU_MISSION_COMMAND
|
||||||
@@ -503,7 +479,7 @@ do -- MENU_MISSION_COMMAND
|
|||||||
--
|
--
|
||||||
-- @field #MENU_MISSION_COMMAND
|
-- @field #MENU_MISSION_COMMAND
|
||||||
MENU_MISSION_COMMAND = {
|
MENU_MISSION_COMMAND = {
|
||||||
ClassName = "MENU_MISSION_COMMAND"
|
ClassName = "MENU_MISSION_COMMAND",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- MENU_MISSION constructor. Creates a new radio command item for a complete mission file, which can invoke a function with parameters.
|
--- MENU_MISSION constructor. Creates a new radio command item for a complete mission file, which can invoke a function with parameters.
|
||||||
@@ -556,7 +532,7 @@ do -- MENU_MISSION_COMMAND
|
|||||||
|
|
||||||
if MissionMenu == self then
|
if MissionMenu == self then
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
self:F( { Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Text = self.MenuText, Path = self.MenuPath } )
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
missionCommands.removeItem( self.MenuPath )
|
missionCommands.removeItem( self.MenuPath )
|
||||||
@@ -575,8 +551,6 @@ do -- MENU_MISSION_COMMAND
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do -- MENU_COALITION
|
do -- MENU_COALITION
|
||||||
|
|
||||||
--- @type MENU_COALITION
|
--- @type MENU_COALITION
|
||||||
@@ -627,14 +601,14 @@ do -- MENU_COALITION
|
|||||||
--
|
--
|
||||||
-- @field #MENU_COALITION
|
-- @field #MENU_COALITION
|
||||||
MENU_COALITION = {
|
MENU_COALITION = {
|
||||||
ClassName = "MENU_COALITION"
|
ClassName = "MENU_COALITION",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- MENU_COALITION constructor. Creates a new MENU_COALITION object and creates the menu for a complete coalition.
|
--- MENU_COALITION constructor. Creates a new MENU_COALITION object and creates the menu for a complete coalition.
|
||||||
-- @param #MENU_COALITION self
|
-- @param #MENU_COALITION self
|
||||||
-- @param DCS#coalition.side Coalition The coalition owning the menu.
|
-- @param DCS#coalition.side Coalition The coalition owning the menu.
|
||||||
-- @param #string MenuText The text for the menu.
|
-- @param #string MenuText The text for the menu.
|
||||||
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
|
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
|
||||||
-- @return #MENU_COALITION self
|
-- @return #MENU_COALITION self
|
||||||
function MENU_COALITION:New( Coalition, MenuText, ParentMenu )
|
function MENU_COALITION:New( Coalition, MenuText, ParentMenu )
|
||||||
|
|
||||||
@@ -693,7 +667,7 @@ do -- MENU_COALITION
|
|||||||
if CoalitionMenu == self then
|
if CoalitionMenu == self then
|
||||||
self:RemoveSubMenus()
|
self:RemoveSubMenus()
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
|
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
|
||||||
@@ -712,8 +686,6 @@ do -- MENU_COALITION
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do -- MENU_COALITION_COMMAND
|
do -- MENU_COALITION_COMMAND
|
||||||
|
|
||||||
--- @type MENU_COALITION_COMMAND
|
--- @type MENU_COALITION_COMMAND
|
||||||
@@ -726,7 +698,7 @@ do -- MENU_COALITION_COMMAND
|
|||||||
--
|
--
|
||||||
-- @field #MENU_COALITION_COMMAND
|
-- @field #MENU_COALITION_COMMAND
|
||||||
MENU_COALITION_COMMAND = {
|
MENU_COALITION_COMMAND = {
|
||||||
ClassName = "MENU_COALITION_COMMAND"
|
ClassName = "MENU_COALITION_COMMAND",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters.
|
--- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters.
|
||||||
@@ -760,7 +732,6 @@ do -- MENU_COALITION_COMMAND
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Refreshes a radio item for a coalition
|
--- Refreshes a radio item for a coalition
|
||||||
-- @param #MENU_COALITION_COMMAND self
|
-- @param #MENU_COALITION_COMMAND self
|
||||||
-- @return #MENU_COALITION_COMMAND
|
-- @return #MENU_COALITION_COMMAND
|
||||||
@@ -784,7 +755,7 @@ do -- MENU_COALITION_COMMAND
|
|||||||
|
|
||||||
if CoalitionMenu == self then
|
if CoalitionMenu == self then
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
|
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
|
||||||
@@ -803,7 +774,6 @@ do -- MENU_COALITION_COMMAND
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- MENU_GROUP
|
--- MENU_GROUP
|
||||||
|
|
||||||
do
|
do
|
||||||
@@ -817,7 +787,6 @@ do
|
|||||||
--- @type MENU_GROUP
|
--- @type MENU_GROUP
|
||||||
-- @extends Core.Menu#MENU_BASE
|
-- @extends Core.Menu#MENU_BASE
|
||||||
|
|
||||||
|
|
||||||
--- Manages the main menus for @{Wrapper.Group}s.
|
--- Manages the main menus for @{Wrapper.Group}s.
|
||||||
--
|
--
|
||||||
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
|
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
|
||||||
@@ -875,7 +844,7 @@ do
|
|||||||
--
|
--
|
||||||
-- @field #MENU_GROUP
|
-- @field #MENU_GROUP
|
||||||
MENU_GROUP = {
|
MENU_GROUP = {
|
||||||
ClassName = "MENU_GROUP"
|
ClassName = "MENU_GROUP",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- MENU_GROUP constructor. Creates a new radio menu item for a group.
|
--- MENU_GROUP constructor. Creates a new radio menu item for a group.
|
||||||
@@ -938,7 +907,6 @@ do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
|
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
|
||||||
-- @param #MENU_GROUP self
|
-- @param #MENU_GROUP self
|
||||||
-- @param MenuStamp
|
-- @param MenuStamp
|
||||||
@@ -953,7 +921,7 @@ do
|
|||||||
if GroupMenu == self then
|
if GroupMenu == self then
|
||||||
self:RemoveSubMenus( MenuStamp, MenuTag )
|
self:RemoveSubMenus( MenuStamp, MenuTag )
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||||
@@ -971,7 +939,6 @@ do
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @type MENU_GROUP_COMMAND
|
--- @type MENU_GROUP_COMMAND
|
||||||
-- @extends Core.Menu#MENU_COMMAND_BASE
|
-- @extends Core.Menu#MENU_COMMAND_BASE
|
||||||
|
|
||||||
@@ -981,7 +948,7 @@ do
|
|||||||
--
|
--
|
||||||
-- @field #MENU_GROUP_COMMAND
|
-- @field #MENU_GROUP_COMMAND
|
||||||
MENU_GROUP_COMMAND = {
|
MENU_GROUP_COMMAND = {
|
||||||
ClassName = "MENU_GROUP_COMMAND"
|
ClassName = "MENU_GROUP_COMMAND",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Creates a new radio command item for a group
|
--- Creates a new radio command item for a group
|
||||||
@@ -1043,7 +1010,7 @@ do
|
|||||||
|
|
||||||
if GroupMenu == self then
|
if GroupMenu == self then
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||||
@@ -1069,7 +1036,6 @@ do
|
|||||||
--- @type MENU_GROUP_DELAYED
|
--- @type MENU_GROUP_DELAYED
|
||||||
-- @extends Core.Menu#MENU_BASE
|
-- @extends Core.Menu#MENU_BASE
|
||||||
|
|
||||||
|
|
||||||
--- The MENU_GROUP_DELAYED class manages the main menus for groups.
|
--- The MENU_GROUP_DELAYED class manages the main menus for groups.
|
||||||
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
|
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
|
||||||
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_GROUP.Remove}.
|
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_GROUP.Remove}.
|
||||||
@@ -1079,7 +1045,7 @@ do
|
|||||||
--
|
--
|
||||||
-- @field #MENU_GROUP_DELAYED
|
-- @field #MENU_GROUP_DELAYED
|
||||||
MENU_GROUP_DELAYED = {
|
MENU_GROUP_DELAYED = {
|
||||||
ClassName = "MENU_GROUP_DELAYED"
|
ClassName = "MENU_GROUP_DELAYED",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- MENU_GROUP_DELAYED constructor. Creates a new radio menu item for a group.
|
--- MENU_GROUP_DELAYED constructor. Creates a new radio menu item for a group.
|
||||||
@@ -1116,7 +1082,6 @@ do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Refreshes a new radio item for a group and submenus
|
--- Refreshes a new radio item for a group and submenus
|
||||||
-- @param #MENU_GROUP_DELAYED self
|
-- @param #MENU_GROUP_DELAYED self
|
||||||
-- @return #MENU_GROUP_DELAYED
|
-- @return #MENU_GROUP_DELAYED
|
||||||
@@ -1135,7 +1100,6 @@ do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Refreshes a new radio item for a group and submenus
|
--- Refreshes a new radio item for a group and submenus
|
||||||
-- @param #MENU_GROUP_DELAYED self
|
-- @param #MENU_GROUP_DELAYED self
|
||||||
-- @return #MENU_GROUP_DELAYED
|
-- @return #MENU_GROUP_DELAYED
|
||||||
@@ -1167,7 +1131,6 @@ do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
|
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
|
||||||
-- @param #MENU_GROUP_DELAYED self
|
-- @param #MENU_GROUP_DELAYED self
|
||||||
-- @param MenuStamp
|
-- @param MenuStamp
|
||||||
@@ -1182,7 +1145,7 @@ do
|
|||||||
if GroupMenu == self then
|
if GroupMenu == self then
|
||||||
self:RemoveSubMenus( MenuStamp, MenuTag )
|
self:RemoveSubMenus( MenuStamp, MenuTag )
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||||
@@ -1200,7 +1163,6 @@ do
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @type MENU_GROUP_COMMAND_DELAYED
|
--- @type MENU_GROUP_COMMAND_DELAYED
|
||||||
-- @extends Core.Menu#MENU_COMMAND_BASE
|
-- @extends Core.Menu#MENU_COMMAND_BASE
|
||||||
|
|
||||||
@@ -1211,7 +1173,7 @@ do
|
|||||||
--
|
--
|
||||||
-- @field #MENU_GROUP_COMMAND_DELAYED
|
-- @field #MENU_GROUP_COMMAND_DELAYED
|
||||||
MENU_GROUP_COMMAND_DELAYED = {
|
MENU_GROUP_COMMAND_DELAYED = {
|
||||||
ClassName = "MENU_GROUP_COMMAND_DELAYED"
|
ClassName = "MENU_GROUP_COMMAND_DELAYED",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Creates a new radio command item for a group
|
--- Creates a new radio command item for a group
|
||||||
@@ -1292,7 +1254,7 @@ do
|
|||||||
|
|
||||||
if GroupMenu == self then
|
if GroupMenu == self then
|
||||||
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
if not MenuStamp or self.MenuStamp ~= MenuStamp then
|
||||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
|
||||||
if self.MenuPath ~= nil then
|
if self.MenuPath ~= nil then
|
||||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||||
|
|||||||
@@ -68,10 +68,9 @@ MESSAGE.Type = {
|
|||||||
Information = "Information",
|
Information = "Information",
|
||||||
Briefing = "Briefing Report",
|
Briefing = "Briefing Report",
|
||||||
Overview = "Overview Report",
|
Overview = "Overview Report",
|
||||||
Detailed = "Detailed Report"
|
Detailed = "Detailed Report",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
||||||
-- @param self
|
-- @param self
|
||||||
-- @param #string MessageText is the text of the Message.
|
-- @param #string MessageText is the text of the Message.
|
||||||
@@ -80,6 +79,7 @@ MESSAGE.Type = {
|
|||||||
-- @param #boolean ClearScreen (optional) Clear all previous messages if true.
|
-- @param #boolean ClearScreen (optional) Clear all previous messages if true.
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Create a series of new Messages.
|
-- -- Create a series of new Messages.
|
||||||
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
|
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
|
||||||
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
|
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
|
||||||
@@ -89,16 +89,16 @@ MESSAGE.Type = {
|
|||||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
|
||||||
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
|
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
|
||||||
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
|
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
|
||||||
|
--
|
||||||
function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen )
|
function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen )
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:F( { MessageText, MessageDuration, MessageCategory } )
|
self:F( { MessageText, MessageDuration, MessageCategory } )
|
||||||
|
|
||||||
|
|
||||||
self.MessageType = nil
|
self.MessageType = nil
|
||||||
|
|
||||||
-- When no MessageCategory is given, we don't show it as a title...
|
-- When no MessageCategory is given, we don't show it as a title...
|
||||||
if MessageCategory and MessageCategory ~= "" then
|
if MessageCategory and MessageCategory ~= "" then
|
||||||
if MessageCategory:sub(-1) ~= "\n" then
|
if MessageCategory:sub( -1 ) ~= "\n" then
|
||||||
self.MessageCategory = MessageCategory .. ": "
|
self.MessageCategory = MessageCategory .. ": "
|
||||||
else
|
else
|
||||||
self.MessageCategory = MessageCategory:sub( 1, -2 ) .. ":\n"
|
self.MessageCategory = MessageCategory:sub( 1, -2 ) .. ":\n"
|
||||||
@@ -107,14 +107,14 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
|
|||||||
self.MessageCategory = ""
|
self.MessageCategory = ""
|
||||||
end
|
end
|
||||||
|
|
||||||
self.ClearScreen=false
|
self.ClearScreen = false
|
||||||
if ClearScreen~=nil then
|
if ClearScreen ~= nil then
|
||||||
self.ClearScreen=ClearScreen
|
self.ClearScreen = ClearScreen
|
||||||
end
|
end
|
||||||
|
|
||||||
self.MessageDuration = MessageDuration or 5
|
self.MessageDuration = MessageDuration or 5
|
||||||
self.MessageTime = timer.getTime()
|
self.MessageTime = timer.getTime()
|
||||||
self.MessageText = MessageText:gsub("^\n","",1):gsub("\n$","",1)
|
self.MessageText = MessageText:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
|
||||||
|
|
||||||
self.MessageSent = false
|
self.MessageSent = false
|
||||||
self.MessageGroup = false
|
self.MessageGroup = false
|
||||||
@@ -123,7 +123,6 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Creates a new MESSAGE object of a certain type.
|
--- Creates a new MESSAGE object of a certain type.
|
||||||
-- Note that these MESSAGE objects are not yet displayed on the display panel.
|
-- Note that these MESSAGE objects are not yet displayed on the display panel.
|
||||||
-- You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
-- You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
|
||||||
@@ -134,10 +133,12 @@ end
|
|||||||
-- @param #boolean ClearScreen (optional) Clear all previous messages.
|
-- @param #boolean ClearScreen (optional) Clear all previous messages.
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- MessageAll = MESSAGE:NewType( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", MESSAGE.Type.Information )
|
-- MessageAll = MESSAGE:NewType( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", MESSAGE.Type.Information )
|
||||||
-- MessageRED = MESSAGE:NewType( "To the RED Players: You receive a penalty because you've killed one of your own units", MESSAGE.Type.Information )
|
-- MessageRED = MESSAGE:NewType( "To the RED Players: You receive a penalty because you've killed one of your own units", MESSAGE.Type.Information )
|
||||||
-- MessageClient1 = MESSAGE:NewType( "Congratulations, you've just hit a target", MESSAGE.Type.Update )
|
-- MessageClient1 = MESSAGE:NewType( "Congratulations, you've just hit a target", MESSAGE.Type.Update )
|
||||||
-- MessageClient2 = MESSAGE:NewType( "Congratulations, you've just killed a target", MESSAGE.Type.Update )
|
-- MessageClient2 = MESSAGE:NewType( "Congratulations, you've just killed a target", MESSAGE.Type.Update )
|
||||||
|
--
|
||||||
function MESSAGE:NewType( MessageText, MessageType, ClearScreen )
|
function MESSAGE:NewType( MessageText, MessageType, ClearScreen )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
@@ -145,36 +146,33 @@ function MESSAGE:NewType( MessageText, MessageType, ClearScreen )
|
|||||||
|
|
||||||
self.MessageType = MessageType
|
self.MessageType = MessageType
|
||||||
|
|
||||||
self.ClearScreen=false
|
self.ClearScreen = false
|
||||||
if ClearScreen~=nil then
|
if ClearScreen ~= nil then
|
||||||
self.ClearScreen=ClearScreen
|
self.ClearScreen = ClearScreen
|
||||||
end
|
end
|
||||||
|
|
||||||
self.MessageTime = timer.getTime()
|
self.MessageTime = timer.getTime()
|
||||||
self.MessageText = MessageText:gsub("^\n","",1):gsub("\n$","",1)
|
self.MessageText = MessageText:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Clears all previous messages from the screen before the new message is displayed. Not that this must come before all functions starting with ToX(), e.g. ToAll(), ToGroup() etc.
|
--- Clears all previous messages from the screen before the new message is displayed. Not that this must come before all functions starting with ToX(), e.g. ToAll(), ToGroup() etc.
|
||||||
-- @param #MESSAGE self
|
-- @param #MESSAGE self
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
function MESSAGE:Clear()
|
function MESSAGE:Clear()
|
||||||
self:F()
|
self:F()
|
||||||
self.ClearScreen=true
|
self.ClearScreen = true
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Sends a MESSAGE to a Client Group. Note that the Group needs to be defined within the ME with the skillset "Client" or "Player".
|
--- Sends a MESSAGE to a Client Group. Note that the Group needs to be defined within the ME with the skillset "Client" or "Player".
|
||||||
-- @param #MESSAGE self
|
-- @param #MESSAGE self
|
||||||
-- @param Wrapper.Client#CLIENT Client is the Group of the Client.
|
-- @param Wrapper.Client#CLIENT Client is the Group of the Client.
|
||||||
-- @param Core.Settings#SETTINGS Settings Settings used to display the message.
|
-- @param Core.Settings#SETTINGS Settings Settings used to display the message.
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Send the 2 messages created with the @{New} method to the Client Group.
|
-- -- Send the 2 messages created with the @{New} method to the Client Group.
|
||||||
-- -- Note that the Message of MessageClient2 is overwriting the Message of MessageClient1.
|
-- -- Note that the Message of MessageClient2 is overwriting the Message of MessageClient1.
|
||||||
-- ClientGroup = Group.getByName( "ClientGroup" )
|
-- ClientGroup = Group.getByName( "ClientGroup" )
|
||||||
@@ -189,21 +187,22 @@ end
|
|||||||
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" )
|
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" )
|
||||||
-- MessageClient1:ToClient( ClientGroup )
|
-- MessageClient1:ToClient( ClientGroup )
|
||||||
-- MessageClient2:ToClient( ClientGroup )
|
-- MessageClient2:ToClient( ClientGroup )
|
||||||
|
--
|
||||||
function MESSAGE:ToClient( Client, Settings )
|
function MESSAGE:ToClient( Client, Settings )
|
||||||
self:F( Client )
|
self:F( Client )
|
||||||
|
|
||||||
if Client and Client:GetClientGroupID() then
|
if Client and Client:GetClientGroupID() then
|
||||||
|
|
||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or (Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||||
self.MessageCategory = "" -- self.MessageType .. ": "
|
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
local ClientGroupID = Client:GetClientGroupID()
|
local ClientGroupID = Client:GetClientGroupID()
|
||||||
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
|
||||||
trigger.action.outTextForGroup( ClientGroupID, self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration , self.ClearScreen)
|
trigger.action.outTextForGroup( ClientGroupID, self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -220,14 +219,14 @@ function MESSAGE:ToGroup( Group, Settings )
|
|||||||
if Group then
|
if Group then
|
||||||
|
|
||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
local Settings = Settings or ( Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
|
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
|
||||||
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
|
||||||
self.MessageCategory = "" -- self.MessageType .. ": "
|
self.MessageCategory = "" -- self.MessageType .. ": "
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
|
||||||
trigger.action.outTextForGroup( Group:GetID(), self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
|
trigger.action.outTextForGroup( Group:GetID(), self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -237,6 +236,7 @@ end
|
|||||||
-- @param #MESSAGE self
|
-- @param #MESSAGE self
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Send a message created with the @{New} method to the BLUE coalition.
|
-- -- Send a message created with the @{New} method to the BLUE coalition.
|
||||||
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
|
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
|
||||||
-- or
|
-- or
|
||||||
@@ -244,6 +244,7 @@ end
|
|||||||
-- or
|
-- or
|
||||||
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
||||||
-- MessageBLUE:ToBlue()
|
-- MessageBLUE:ToBlue()
|
||||||
|
--
|
||||||
function MESSAGE:ToBlue()
|
function MESSAGE:ToBlue()
|
||||||
self:F()
|
self:F()
|
||||||
|
|
||||||
@@ -256,6 +257,7 @@ end
|
|||||||
-- @param #MESSAGE self
|
-- @param #MESSAGE self
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Send a message created with the @{New} method to the RED coalition.
|
-- -- Send a message created with the @{New} method to the RED coalition.
|
||||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
|
||||||
-- or
|
-- or
|
||||||
@@ -263,7 +265,8 @@ end
|
|||||||
-- or
|
-- or
|
||||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
||||||
-- MessageRED:ToRed()
|
-- MessageRED:ToRed()
|
||||||
function MESSAGE:ToRed( )
|
--
|
||||||
|
function MESSAGE:ToRed()
|
||||||
self:F()
|
self:F()
|
||||||
|
|
||||||
self:ToCoalition( coalition.side.RED )
|
self:ToCoalition( coalition.side.RED )
|
||||||
@@ -277,6 +280,7 @@ end
|
|||||||
-- @param Core.Settings#SETTINGS Settings (Optional) Settings for message display.
|
-- @param Core.Settings#SETTINGS Settings (Optional) Settings for message display.
|
||||||
-- @return #MESSAGE Message object.
|
-- @return #MESSAGE Message object.
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Send a message created with the @{New} method to the RED coalition.
|
-- -- Send a message created with the @{New} method to the RED coalition.
|
||||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
|
||||||
-- or
|
-- or
|
||||||
@@ -284,6 +288,7 @@ end
|
|||||||
-- or
|
-- or
|
||||||
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
|
||||||
-- MessageRED:ToCoalition( coalition.side.RED )
|
-- MessageRED:ToCoalition( coalition.side.RED )
|
||||||
|
--
|
||||||
function MESSAGE:ToCoalition( CoalitionSide, Settings )
|
function MESSAGE:ToCoalition( CoalitionSide, Settings )
|
||||||
self:F( CoalitionSide )
|
self:F( CoalitionSide )
|
||||||
|
|
||||||
@@ -295,8 +300,8 @@ function MESSAGE:ToCoalition( CoalitionSide, Settings )
|
|||||||
|
|
||||||
if CoalitionSide then
|
if CoalitionSide then
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
|
||||||
trigger.action.outTextForCoalition( CoalitionSide, self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
|
trigger.action.outTextForCoalition( CoalitionSide, self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -323,6 +328,7 @@ end
|
|||||||
-- @param Core.Settings#Settings Settings (Optional) Settings for message display.
|
-- @param Core.Settings#Settings Settings (Optional) Settings for message display.
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
-- @usage
|
-- @usage
|
||||||
|
--
|
||||||
-- -- Send a message created to all players.
|
-- -- Send a message created to all players.
|
||||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
|
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
|
||||||
-- or
|
-- or
|
||||||
@@ -330,7 +336,8 @@ end
|
|||||||
-- or
|
-- or
|
||||||
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
|
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
|
||||||
-- MessageAll:ToAll()
|
-- MessageAll:ToAll()
|
||||||
function MESSAGE:ToAll(Settings)
|
--
|
||||||
|
function MESSAGE:ToAll( Settings )
|
||||||
self:F()
|
self:F()
|
||||||
|
|
||||||
if self.MessageType then
|
if self.MessageType then
|
||||||
@@ -340,14 +347,13 @@ function MESSAGE:ToAll(Settings)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.MessageDuration ~= 0 then
|
if self.MessageDuration ~= 0 then
|
||||||
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
|
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
|
||||||
trigger.action.outText( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
|
trigger.action.outText( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Sends a MESSAGE to all players if the given Condition is true.
|
--- Sends a MESSAGE to all players if the given Condition is true.
|
||||||
-- @param #MESSAGE self
|
-- @param #MESSAGE self
|
||||||
-- @return #MESSAGE
|
-- @return #MESSAGE
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,6 @@
|
|||||||
-- @module Core.Report
|
-- @module Core.Report
|
||||||
-- @image Core_Report.JPG
|
-- @image Core_Report.JPG
|
||||||
|
|
||||||
|
|
||||||
--- @type REPORT
|
--- @type REPORT
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
@@ -45,28 +44,26 @@ end
|
|||||||
--- Has the REPORT Text?
|
--- Has the REPORT Text?
|
||||||
-- @param #REPORT self
|
-- @param #REPORT self
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
function REPORT:HasText() --R2.1
|
function REPORT:HasText() -- R2.1
|
||||||
|
|
||||||
return #self.Report > 0
|
return #self.Report > 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set indent of a REPORT.
|
--- Set indent of a REPORT.
|
||||||
-- @param #REPORT self
|
-- @param #REPORT self
|
||||||
-- @param #number Indent
|
-- @param #number Indent
|
||||||
-- @return #REPORT
|
-- @return #REPORT
|
||||||
function REPORT:SetIndent( Indent ) --R2.1
|
function REPORT:SetIndent( Indent ) -- R2.1
|
||||||
self.Indent = Indent
|
self.Indent = Indent
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Add a new line to a REPORT.
|
--- Add a new line to a REPORT.
|
||||||
-- @param #REPORT self
|
-- @param #REPORT self
|
||||||
-- @param #string Text
|
-- @param #string Text
|
||||||
-- @return #REPORT
|
-- @return #REPORT
|
||||||
function REPORT:Add( Text )
|
function REPORT:Add( Text )
|
||||||
self.Report[#self.Report+1] = Text
|
self.Report[#self.Report + 1] = Text
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -76,17 +73,17 @@ end
|
|||||||
-- @param #string Separator (optional) The start of each report line can begin with an optional separator character. This can be a "-", or "#", or "*". You're free to choose what you find the best.
|
-- @param #string Separator (optional) The start of each report line can begin with an optional separator character. This can be a "-", or "#", or "*". You're free to choose what you find the best.
|
||||||
-- @return #REPORT
|
-- @return #REPORT
|
||||||
function REPORT:AddIndent( Text, Separator )
|
function REPORT:AddIndent( Text, Separator )
|
||||||
self.Report[#self.Report+1] = ( ( Separator and Separator .. string.rep( " ", self.Indent - 1 ) ) or string.rep(" ", self.Indent ) ) .. Text:gsub("\n","\n"..string.rep( " ", self.Indent ) )
|
self.Report[#self.Report + 1] = ((Separator and Separator .. string.rep( " ", self.Indent - 1 )) or string.rep( " ", self.Indent )) .. Text:gsub( "\n", "\n" .. string.rep( " ", self.Indent ) )
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Produces the text of the report, taking into account an optional delimeter, which is \n by default.
|
--- Produces the text of the report, taking into account an optional delimiter, which is \n by default.
|
||||||
-- @param #REPORT self
|
-- @param #REPORT self
|
||||||
-- @param #string Delimiter (optional) A delimiter text.
|
-- @param #string Delimiter (optional) A delimiter text.
|
||||||
-- @return #string The report text.
|
-- @return #string The report text.
|
||||||
function REPORT:Text( Delimiter )
|
function REPORT:Text( Delimiter )
|
||||||
Delimiter = Delimiter or "\n"
|
Delimiter = Delimiter or "\n"
|
||||||
local ReportText = ( self.Title ~= "" and self.Title .. Delimiter or self.Title ) .. table.concat( self.Report, Delimiter ) or ""
|
local ReportText = (self.Title ~= "" and self.Title .. Delimiter or self.Title) .. table.concat( self.Report, Delimiter ) or ""
|
||||||
return ReportText
|
return ReportText
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
-- - When a SCHEDULER object is not attached to another object (that is, it's first :Schedule() parameter is nil), then the SCHEDULER object is _persistent_ within memory.
|
-- - When a SCHEDULER object is not attached to another object (that is, it's first :Schedule() parameter is nil), then the SCHEDULER object is _persistent_ within memory.
|
||||||
-- - When a SCHEDULER object *is* attached to another object, then the SCHEDULER object is _not persistent_ within memory after a garbage collection!
|
-- - When a SCHEDULER object *is* attached to another object, then the SCHEDULER object is _not persistent_ within memory after a garbage collection!
|
||||||
--
|
--
|
||||||
-- The none persistency of SCHEDULERS attached to objects is required to allow SCHEDULER objects to be garbage collectged, when the parent object is also desroyed or nillified and garbage collected.
|
-- The non-persistency of SCHEDULERS attached to objects is required to allow SCHEDULER objects to be garbage collected when the parent object is destroyed, or set to nil and garbage collected.
|
||||||
-- Even when there are pending timer scheduled functions to be executed for the SCHEDULER object,
|
-- Even when there are pending timer scheduled functions to be executed for the SCHEDULER object,
|
||||||
-- these will not be executed anymore when the SCHEDULER object has been destroyed.
|
-- these will not be executed anymore when the SCHEDULER object has been destroyed.
|
||||||
--
|
--
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
-- @type SCHEDULEDISPATCHER
|
-- @type SCHEDULEDISPATCHER
|
||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
-- @field #number CallID Call ID counter.
|
-- @field #number CallID Call ID counter.
|
||||||
-- @field #table PersistentSchedulers Persistant schedulers.
|
-- @field #table PersistentSchedulers Persistent schedulers.
|
||||||
-- @field #table ObjectSchedulers Schedulers that only exist as long as the master object exists.
|
-- @field #table ObjectSchedulers Schedulers that only exist as long as the master object exists.
|
||||||
-- @field #table Schedule Meta table setmetatable( {}, { __mode = "k" } ).
|
-- @field #table Schedule Meta table setmetatable( {}, { __mode = "k" } ).
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
@@ -58,7 +58,7 @@ SCHEDULEDISPATCHER = {
|
|||||||
-- @field #function Function The schedule function to be called.
|
-- @field #function Function The schedule function to be called.
|
||||||
-- @field #table Arguments Schedule function arguments.
|
-- @field #table Arguments Schedule function arguments.
|
||||||
-- @field #number Start Start time in seconds.
|
-- @field #number Start Start time in seconds.
|
||||||
-- @field #number Repeat Repeat time intervall in seconds.
|
-- @field #number Repeat Repeat time interval in seconds.
|
||||||
-- @field #number Randomize Randomization factor [0,1].
|
-- @field #number Randomize Randomization factor [0,1].
|
||||||
-- @field #number Stop Stop time in seconds.
|
-- @field #number Stop Stop time in seconds.
|
||||||
-- @field #number StartTime Time in seconds when the scheduler is created.
|
-- @field #number StartTime Time in seconds when the scheduler is created.
|
||||||
@@ -77,7 +77,7 @@ end
|
|||||||
|
|
||||||
--- Add a Schedule to the ScheduleDispatcher.
|
--- Add a Schedule to the ScheduleDispatcher.
|
||||||
-- The development of this method was really tidy.
|
-- The development of this method was really tidy.
|
||||||
-- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is nillified.
|
-- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is set to nil.
|
||||||
-- Nothing of this code should be modified without testing it thoroughly.
|
-- Nothing of this code should be modified without testing it thoroughly.
|
||||||
-- @param #SCHEDULEDISPATCHER self
|
-- @param #SCHEDULEDISPATCHER self
|
||||||
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
|
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
|
||||||
@@ -85,7 +85,7 @@ end
|
|||||||
-- @param #table ScheduleArguments Table of arguments passed to the ScheduleFunction.
|
-- @param #table ScheduleArguments Table of arguments passed to the ScheduleFunction.
|
||||||
-- @param #number Start Start time in seconds.
|
-- @param #number Start Start time in seconds.
|
||||||
-- @param #number Repeat Repeat interval in seconds.
|
-- @param #number Repeat Repeat interval in seconds.
|
||||||
-- @param #number Randomize Radomization factor [0,1].
|
-- @param #number Randomize Randomization factor [0,1].
|
||||||
-- @param #number Stop Stop time in seconds.
|
-- @param #number Stop Stop time in seconds.
|
||||||
-- @param #number TraceLevel Trace level [0,3].
|
-- @param #number TraceLevel Trace level [0,3].
|
||||||
-- @param Core.Fsm#FSM Fsm Finite state model.
|
-- @param Core.Fsm#FSM Fsm Finite state model.
|
||||||
@@ -97,9 +97,9 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
self.CallID = self.CallID + 1
|
self.CallID = self.CallID + 1
|
||||||
|
|
||||||
-- Create ID.
|
-- Create ID.
|
||||||
local CallID = self.CallID .. "#" .. ( Scheduler.MasterObject and Scheduler.MasterObject.GetClassNameAndID and Scheduler.MasterObject:GetClassNameAndID() or "" ) or ""
|
local CallID = self.CallID .. "#" .. (Scheduler.MasterObject and Scheduler.MasterObject.GetClassNameAndID and Scheduler.MasterObject:GetClassNameAndID() or "") or ""
|
||||||
|
|
||||||
self:T2(string.format("Adding schedule #%d CallID=%s", self.CallID, CallID))
|
self:T2( string.format( "Adding schedule #%d CallID=%s", self.CallID, CallID ) )
|
||||||
|
|
||||||
-- Initialize PersistentSchedulers
|
-- Initialize PersistentSchedulers
|
||||||
self.PersistentSchedulers = self.PersistentSchedulers or {}
|
self.PersistentSchedulers = self.PersistentSchedulers or {}
|
||||||
@@ -110,7 +110,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
|
|
||||||
if Scheduler.MasterObject then
|
if Scheduler.MasterObject then
|
||||||
self.ObjectSchedulers[CallID] = Scheduler
|
self.ObjectSchedulers[CallID] = Scheduler
|
||||||
self:F3( { CallID = CallID, ObjectScheduler = tostring(self.ObjectSchedulers[CallID]), MasterObject = tostring(Scheduler.MasterObject) } )
|
self:F3( { CallID = CallID, ObjectScheduler = tostring( self.ObjectSchedulers[CallID] ), MasterObject = tostring( Scheduler.MasterObject ) } )
|
||||||
else
|
else
|
||||||
self.PersistentSchedulers[CallID] = Scheduler
|
self.PersistentSchedulers[CallID] = Scheduler
|
||||||
self:F3( { CallID = CallID, PersistentScheduler = self.PersistentSchedulers[CallID] } )
|
self:F3( { CallID = CallID, PersistentScheduler = self.PersistentSchedulers[CallID] } )
|
||||||
@@ -118,16 +118,15 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
|
|
||||||
self.Schedule = self.Schedule or setmetatable( {}, { __mode = "k" } )
|
self.Schedule = self.Schedule or setmetatable( {}, { __mode = "k" } )
|
||||||
self.Schedule[Scheduler] = self.Schedule[Scheduler] or {}
|
self.Schedule[Scheduler] = self.Schedule[Scheduler] or {}
|
||||||
self.Schedule[Scheduler][CallID] = {} --#SCHEDULEDISPATCHER.ScheduleData
|
self.Schedule[Scheduler][CallID] = {} -- #SCHEDULEDISPATCHER.ScheduleData
|
||||||
self.Schedule[Scheduler][CallID].Function = ScheduleFunction
|
self.Schedule[Scheduler][CallID].Function = ScheduleFunction
|
||||||
self.Schedule[Scheduler][CallID].Arguments = ScheduleArguments
|
self.Schedule[Scheduler][CallID].Arguments = ScheduleArguments
|
||||||
self.Schedule[Scheduler][CallID].StartTime = timer.getTime() + ( Start or 0 )
|
self.Schedule[Scheduler][CallID].StartTime = timer.getTime() + (Start or 0)
|
||||||
self.Schedule[Scheduler][CallID].Start = Start + 0.1
|
self.Schedule[Scheduler][CallID].Start = Start + 0.1
|
||||||
self.Schedule[Scheduler][CallID].Repeat = Repeat or 0
|
self.Schedule[Scheduler][CallID].Repeat = Repeat or 0
|
||||||
self.Schedule[Scheduler][CallID].Randomize = Randomize or 0
|
self.Schedule[Scheduler][CallID].Randomize = Randomize or 0
|
||||||
self.Schedule[Scheduler][CallID].Stop = Stop
|
self.Schedule[Scheduler][CallID].Stop = Stop
|
||||||
|
|
||||||
|
|
||||||
-- This section handles the tracing of the scheduled calls.
|
-- This section handles the tracing of the scheduled calls.
|
||||||
-- Because these calls will be executed with a delay, we inspect the place where these scheduled calls are initiated.
|
-- Because these calls will be executed with a delay, we inspect the place where these scheduled calls are initiated.
|
||||||
-- The Info structure contains the output of the debug.getinfo() calls, which inspects the call stack for the function name, line number and source name.
|
-- The Info structure contains the output of the debug.getinfo() calls, which inspects the call stack for the function name, line number and source name.
|
||||||
@@ -149,7 +148,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
-- Therefore, in the call stack, at the TraceLevel these functions are mentioned as "tail calls", and the Info.name field will be nil as a result.
|
-- Therefore, in the call stack, at the TraceLevel these functions are mentioned as "tail calls", and the Info.name field will be nil as a result.
|
||||||
-- To obtain the correct function name for FSM object calls, the function is mentioned in the call stack at a higher stack level.
|
-- To obtain the correct function name for FSM object calls, the function is mentioned in the call stack at a higher stack level.
|
||||||
-- So when function name stored in Info.name is nil, then I inspect the function name within the call stack one level higher.
|
-- So when function name stored in Info.name is nil, then I inspect the function name within the call stack one level higher.
|
||||||
-- So this little piece of code does its magic wonderfully, preformance overhead is neglectible, as scheduled calls don't happen that often.
|
-- So this little piece of code does its magic wonderfully, performance overhead is negligible, as scheduled calls don't happen that often.
|
||||||
|
|
||||||
local Info = {}
|
local Info = {}
|
||||||
|
|
||||||
@@ -181,24 +180,24 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
return errmsg
|
return errmsg
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get object or persistant scheduler object.
|
-- Get object or persistent scheduler object.
|
||||||
local Scheduler = self.ObjectSchedulers[CallID] --Core.Scheduler#SCHEDULER
|
local Scheduler = self.ObjectSchedulers[CallID] -- Core.Scheduler#SCHEDULER
|
||||||
if not Scheduler then
|
if not Scheduler then
|
||||||
Scheduler = self.PersistentSchedulers[CallID]
|
Scheduler = self.PersistentSchedulers[CallID]
|
||||||
end
|
end
|
||||||
|
|
||||||
--self:T3( { Scheduler = Scheduler } )
|
-- self:T3( { Scheduler = Scheduler } )
|
||||||
|
|
||||||
if Scheduler then
|
if Scheduler then
|
||||||
|
|
||||||
local MasterObject = tostring(Scheduler.MasterObject)
|
local MasterObject = tostring( Scheduler.MasterObject )
|
||||||
|
|
||||||
-- Schedule object.
|
-- Schedule object.
|
||||||
local Schedule = self.Schedule[Scheduler][CallID] --#SCHEDULEDISPATCHER.ScheduleData
|
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
|
||||||
|
|
||||||
--self:T3( { Schedule = Schedule } )
|
-- self:T3( { Schedule = Schedule } )
|
||||||
|
|
||||||
local SchedulerObject = Scheduler.MasterObject --Scheduler.SchedulerObject Now is this the Maste or Scheduler object?
|
local SchedulerObject = Scheduler.MasterObject -- Scheduler.SchedulerObject Now is this the Master or Scheduler object?
|
||||||
local ShowTrace = Scheduler.ShowTrace
|
local ShowTrace = Scheduler.ShowTrace
|
||||||
|
|
||||||
local ScheduleFunction = Schedule.Function
|
local ScheduleFunction = Schedule.Function
|
||||||
@@ -209,11 +208,10 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
local Stop = Schedule.Stop or 0
|
local Stop = Schedule.Stop or 0
|
||||||
local ScheduleID = Schedule.ScheduleID
|
local ScheduleID = Schedule.ScheduleID
|
||||||
|
|
||||||
|
local Prefix = (Repeat == 0) and "--->" or "+++>"
|
||||||
local Prefix = ( Repeat == 0 ) and "--->" or "+++>"
|
|
||||||
|
|
||||||
local Status, Result
|
local Status, Result
|
||||||
--self:E( { SchedulerObject = SchedulerObject } )
|
-- self:E( { SchedulerObject = SchedulerObject } )
|
||||||
if SchedulerObject then
|
if SchedulerObject then
|
||||||
local function Timer()
|
local function Timer()
|
||||||
if ShowTrace then
|
if ShowTrace then
|
||||||
@@ -236,14 +234,13 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
|||||||
local StartTime = Schedule.StartTime
|
local StartTime = Schedule.StartTime
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:F3( { CallID=CallID, ScheduleID=ScheduleID, Master = MasterObject, CurrentTime = CurrentTime, StartTime = StartTime, Start = Start, Repeat = Repeat, Randomize = Randomize, Stop = Stop } )
|
self:F3( { CallID = CallID, ScheduleID = ScheduleID, Master = MasterObject, CurrentTime = CurrentTime, StartTime = StartTime, Start = Start, Repeat = Repeat, Randomize = Randomize, Stop = Stop } )
|
||||||
|
|
||||||
|
if Status and ((Result == nil) or (Result and Result ~= false)) then
|
||||||
|
|
||||||
if Status and (( Result == nil ) or ( Result and Result ~= false ) ) then
|
if Repeat ~= 0 and ((Stop == 0) or (Stop ~= 0 and CurrentTime <= StartTime + Stop)) then
|
||||||
|
local ScheduleTime = CurrentTime + Repeat + math.random( -(Randomize * Repeat / 2), (Randomize * Repeat / 2) ) + 0.0001 -- Accuracy
|
||||||
if Repeat ~= 0 and ( ( Stop == 0 ) or ( Stop ~= 0 and CurrentTime <= StartTime + Stop ) ) then
|
-- self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
|
||||||
local ScheduleTime = CurrentTime + Repeat + math.random(- ( Randomize * Repeat / 2 ), ( Randomize * Repeat / 2 )) + 0.0001 -- Accuracy
|
|
||||||
--self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
|
|
||||||
return ScheduleTime -- returns the next time the function needs to be called.
|
return ScheduleTime -- returns the next time the function needs to be called.
|
||||||
else
|
else
|
||||||
self:Stop( Scheduler, CallID )
|
self:Stop( Scheduler, CallID )
|
||||||
@@ -287,21 +284,21 @@ function SCHEDULEDISPATCHER:Start( Scheduler, CallID, Info )
|
|||||||
|
|
||||||
if CallID then
|
if CallID then
|
||||||
|
|
||||||
local Schedule = self.Schedule[Scheduler][CallID] --#SCHEDULEDISPATCHER.ScheduleData
|
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
|
||||||
|
|
||||||
-- Only start when there is no ScheduleID defined!
|
-- Only start when there is no ScheduleID defined!
|
||||||
-- This prevents to "Start" the scheduler twice with the same CallID...
|
-- This prevents to "Start" the scheduler twice with the same CallID...
|
||||||
if not Schedule.ScheduleID then
|
if not Schedule.ScheduleID then
|
||||||
|
|
||||||
-- Current time in seconds.
|
-- Current time in seconds.
|
||||||
local Tnow=timer.getTime()
|
local Tnow = timer.getTime()
|
||||||
|
|
||||||
Schedule.StartTime = Tnow -- Set the StartTime field to indicate when the scheduler started.
|
Schedule.StartTime = Tnow -- Set the StartTime field to indicate when the scheduler started.
|
||||||
|
|
||||||
-- Start DCS schedule function https://wiki.hoggitworld.com/view/DCS_func_scheduleFunction
|
-- Start DCS schedule function https://wiki.hoggitworld.com/view/DCS_func_scheduleFunction
|
||||||
Schedule.ScheduleID = timer.scheduleFunction(Schedule.CallHandler, { CallID = CallID, Info = Info }, Tnow + Schedule.Start)
|
Schedule.ScheduleID = timer.scheduleFunction( Schedule.CallHandler, { CallID = CallID, Info = Info }, Tnow + Schedule.Start )
|
||||||
|
|
||||||
self:T(string.format("Starting scheduledispatcher Call ID=%s ==> Schedule ID=%s", tostring(CallID), tostring(Schedule.ScheduleID)))
|
self:T( string.format( "Starting SCHEDULEDISPATCHER Call ID=%s ==> Schedule ID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -323,20 +320,20 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
|
|||||||
|
|
||||||
if CallID then
|
if CallID then
|
||||||
|
|
||||||
local Schedule = self.Schedule[Scheduler][CallID] --#SCHEDULEDISPATCHER.ScheduleData
|
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
|
||||||
|
|
||||||
-- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing.
|
-- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing.
|
||||||
if Schedule.ScheduleID then
|
if Schedule.ScheduleID then
|
||||||
|
|
||||||
self:T(string.format("scheduledispatcher stopping scheduler CallID=%s, ScheduleID=%s", tostring(CallID), tostring(Schedule.ScheduleID)))
|
self:T( string.format( "SCHEDULEDISPATCHER stopping scheduler CallID=%s, ScheduleID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
|
||||||
|
|
||||||
-- Remove schedule function https://wiki.hoggitworld.com/view/DCS_func_removeFunction
|
-- Remove schedule function https://wiki.hoggitworld.com/view/DCS_func_removeFunction
|
||||||
timer.removeFunction(Schedule.ScheduleID)
|
timer.removeFunction( Schedule.ScheduleID )
|
||||||
|
|
||||||
Schedule.ScheduleID = nil
|
Schedule.ScheduleID = nil
|
||||||
|
|
||||||
else
|
else
|
||||||
self:T(string.format("Error no ScheduleID for CallID=%s", tostring(CallID)))
|
self:T( string.format( "Error no ScheduleID for CallID=%s", tostring( CallID ) ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -359,7 +356,7 @@ function SCHEDULEDISPATCHER:Clear( Scheduler )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Shopw tracing info.
|
--- Show tracing info.
|
||||||
-- @param #SCHEDULEDISPATCHER self
|
-- @param #SCHEDULEDISPATCHER self
|
||||||
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
|
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
|
||||||
function SCHEDULEDISPATCHER:ShowTrace( Scheduler )
|
function SCHEDULEDISPATCHER:ShowTrace( Scheduler )
|
||||||
|
|||||||
@@ -48,7 +48,6 @@
|
|||||||
-- @field #boolean ShowTrace Trace info if true.
|
-- @field #boolean ShowTrace Trace info if true.
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
--- Creates and handles schedules over time, which allow to execute code at specific time intervals with randomization.
|
--- Creates and handles schedules over time, which allow to execute code at specific time intervals with randomization.
|
||||||
--
|
--
|
||||||
-- A SCHEDULER can manage **multiple** (repeating) schedules. Each planned or executing schedule has a unique **ScheduleID**.
|
-- A SCHEDULER can manage **multiple** (repeating) schedules. Each planned or executing schedule has a unique **ScheduleID**.
|
||||||
@@ -79,7 +78,7 @@
|
|||||||
--
|
--
|
||||||
-- ### Construct a SCHEDULER object without a volatile schedule, but volatile to the Object existence...
|
-- ### Construct a SCHEDULER object without a volatile schedule, but volatile to the Object existence...
|
||||||
--
|
--
|
||||||
-- * @{#SCHEDULER.New}( Object ): Setup a new SCHEDULER object, which is linked to the Object. When the Object is nillified or destroyed, the SCHEDULER object will also be destroyed and stopped after garbage collection.
|
-- * @{#SCHEDULER.New}( Object ): Setup a new SCHEDULER object, which is linked to the Object. When the Object is set to nil or destroyed, the SCHEDULER object will also be destroyed and stopped after garbage collection.
|
||||||
--
|
--
|
||||||
-- ZoneObject = ZONE:New( "ZoneName" )
|
-- ZoneObject = ZONE:New( "ZoneName" )
|
||||||
-- MasterObject = SCHEDULER:New( ZoneObject )
|
-- MasterObject = SCHEDULER:New( ZoneObject )
|
||||||
@@ -149,13 +148,13 @@
|
|||||||
-- ZoneObject = ZONE:New( "ZoneName" )
|
-- ZoneObject = ZONE:New( "ZoneName" )
|
||||||
-- MasterObject = SCHEDULER:New( ZoneObject )
|
-- MasterObject = SCHEDULER:New( ZoneObject )
|
||||||
--
|
--
|
||||||
-- Several parameters can be specified that influence the behaviour of a Schedule.
|
-- Several parameters can be specified that influence the behavior of a Schedule.
|
||||||
--
|
--
|
||||||
-- ### A single schedule, immediately executed
|
-- ### A single schedule, immediately executed
|
||||||
--
|
--
|
||||||
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {} )
|
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {} )
|
||||||
--
|
--
|
||||||
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within milleseconds ...
|
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within milliseconds ...
|
||||||
--
|
--
|
||||||
-- ### A single schedule, planned over time
|
-- ### A single schedule, planned over time
|
||||||
--
|
--
|
||||||
@@ -235,7 +234,7 @@ end
|
|||||||
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
|
||||||
-- @param #number Repeat Specifies the time interval in seconds when the scheduler will call the event function.
|
-- @param #number Repeat Specifies the time interval in seconds when the scheduler will call the event function.
|
||||||
-- @param #number RandomizeFactor Specifies a randomization factor between 0 and 1 to randomize the Repeat.
|
-- @param #number RandomizeFactor Specifies a randomization factor between 0 and 1 to randomize the Repeat.
|
||||||
-- @param #number Stop Time interval in seconds after which the scheduler will be stoppe.
|
-- @param #number Stop Time interval in seconds after which the scheduler will be stopped.
|
||||||
-- @param #number TraceLevel Trace level [0,3]. Default 3.
|
-- @param #number TraceLevel Trace level [0,3]. Default 3.
|
||||||
-- @param Core.Fsm#FSM Fsm Finite state model.
|
-- @param Core.Fsm#FSM Fsm Finite state model.
|
||||||
-- @return #table The ScheduleID of the planned schedule.
|
-- @return #table The ScheduleID of the planned schedule.
|
||||||
@@ -254,8 +253,7 @@ function SCHEDULER:Schedule( MasterObject, SchedulerFunction, SchedulerArguments
|
|||||||
self.MasterObject = MasterObject
|
self.MasterObject = MasterObject
|
||||||
|
|
||||||
-- Add schedule.
|
-- Add schedule.
|
||||||
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
|
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule( self,
|
||||||
self,
|
|
||||||
SchedulerFunction,
|
SchedulerFunction,
|
||||||
SchedulerArguments,
|
SchedulerArguments,
|
||||||
Start,
|
Start,
|
||||||
@@ -266,7 +264,7 @@ function SCHEDULER:Schedule( MasterObject, SchedulerFunction, SchedulerArguments
|
|||||||
Fsm
|
Fsm
|
||||||
)
|
)
|
||||||
|
|
||||||
self.Schedules[#self.Schedules+1] = ScheduleID
|
self.Schedules[#self.Schedules + 1] = ScheduleID
|
||||||
|
|
||||||
return ScheduleID
|
return ScheduleID
|
||||||
end
|
end
|
||||||
@@ -276,7 +274,7 @@ end
|
|||||||
-- @param #string ScheduleID (Optional) The ScheduleID of the planned (repeating) schedule.
|
-- @param #string ScheduleID (Optional) The ScheduleID of the planned (repeating) schedule.
|
||||||
function SCHEDULER:Start( ScheduleID )
|
function SCHEDULER:Start( ScheduleID )
|
||||||
self:F3( { ScheduleID } )
|
self:F3( { ScheduleID } )
|
||||||
self:T(string.format("Starting scheduler ID=%s", tostring(ScheduleID)))
|
self:T( string.format( "Starting scheduler ID=%s", tostring( ScheduleID ) ) )
|
||||||
_SCHEDULEDISPATCHER:Start( self, ScheduleID )
|
_SCHEDULEDISPATCHER:Start( self, ScheduleID )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -285,7 +283,7 @@ end
|
|||||||
-- @param #string ScheduleID (Optional) The ScheduleID of the planned (repeating) schedule.
|
-- @param #string ScheduleID (Optional) The ScheduleID of the planned (repeating) schedule.
|
||||||
function SCHEDULER:Stop( ScheduleID )
|
function SCHEDULER:Stop( ScheduleID )
|
||||||
self:F3( { ScheduleID } )
|
self:F3( { ScheduleID } )
|
||||||
self:T(string.format("Stopping scheduler ID=%s", tostring(ScheduleID)))
|
self:T( string.format( "Stopping scheduler ID=%s", tostring( ScheduleID ) ) )
|
||||||
_SCHEDULEDISPATCHER:Stop( self, ScheduleID )
|
_SCHEDULEDISPATCHER:Stop( self, ScheduleID )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -294,15 +292,15 @@ end
|
|||||||
-- @param #string ScheduleID (optional) The ScheduleID of the planned (repeating) schedule.
|
-- @param #string ScheduleID (optional) The ScheduleID of the planned (repeating) schedule.
|
||||||
function SCHEDULER:Remove( ScheduleID )
|
function SCHEDULER:Remove( ScheduleID )
|
||||||
self:F3( { ScheduleID } )
|
self:F3( { ScheduleID } )
|
||||||
self:T(string.format("Removing scheduler ID=%s", tostring(ScheduleID)))
|
self:T( string.format( "Removing scheduler ID=%s", tostring( ScheduleID ) ) )
|
||||||
_SCHEDULEDISPATCHER:RemoveSchedule( self, ScheduleID )
|
_SCHEDULEDISPATCHER:RemoveSchedule( self, ScheduleID )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Clears all pending schedules.
|
--- Clears all pending schedules.
|
||||||
-- @param #SCHEDULER self
|
-- @param #SCHEDULER self
|
||||||
function SCHEDULER:Clear()
|
function SCHEDULER:Clear()
|
||||||
self:F3( )
|
self:F3()
|
||||||
self:T(string.format("Clearing scheduler"))
|
self:T( string.format( "Clearing scheduler" ) )
|
||||||
_SCHEDULEDISPATCHER:Clear( self )
|
_SCHEDULEDISPATCHER:Clear( self )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -29,15 +29,14 @@
|
|||||||
-- @module Core.Settings
|
-- @module Core.Settings
|
||||||
-- @image Core_Settings.JPG
|
-- @image Core_Settings.JPG
|
||||||
|
|
||||||
|
|
||||||
--- @type SETTINGS
|
--- @type SETTINGS
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- Takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework.
|
--- Takes care of various settings that influence the behavior of certain functionalities and classes within the MOOSE framework.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- The SETTINGS class takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework.
|
-- The SETTINGS class takes care of various settings that influence the behavior of certain functionalities and classes within the MOOSE framework.
|
||||||
-- SETTINGS can work on 2 levels:
|
-- SETTINGS can work on 2 levels:
|
||||||
--
|
--
|
||||||
-- - **Default settings**: A running mission has **Default settings**.
|
-- - **Default settings**: A running mission has **Default settings**.
|
||||||
@@ -59,7 +58,7 @@
|
|||||||
--
|
--
|
||||||
-- A menu is created automatically per Command Center that allows to modify the **Default** settings.
|
-- A menu is created automatically per Command Center that allows to modify the **Default** settings.
|
||||||
-- So, when joining a CC unit, a menu will be available that allows to change the settings parameters **FOR ALL THE PLAYERS**!
|
-- So, when joining a CC unit, a menu will be available that allows to change the settings parameters **FOR ALL THE PLAYERS**!
|
||||||
-- Note that the **Default settings** will only be used when a player has not choosen its own settings.
|
-- Note that the **Default settings** will only be used when a player has not chosen its own settings.
|
||||||
--
|
--
|
||||||
-- ## 2.2) Player settings menu
|
-- ## 2.2) Player settings menu
|
||||||
--
|
--
|
||||||
@@ -69,7 +68,7 @@
|
|||||||
--
|
--
|
||||||
-- ## 2.3) Show or Hide the Player Setting menus
|
-- ## 2.3) Show or Hide the Player Setting menus
|
||||||
--
|
--
|
||||||
-- Of course, it may be requried not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**.
|
-- Of course, it may be required not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**.
|
||||||
-- Use @{#SETTINGS.SetPlayerMenuOff}() to hide the player menus, and use @{#SETTINGS.SetPlayerMenuOn}() show the player menus.
|
-- Use @{#SETTINGS.SetPlayerMenuOff}() to hide the player menus, and use @{#SETTINGS.SetPlayerMenuOn}() show the player menus.
|
||||||
-- Note that when this method is used, any player already in a slot will not have its menus visibility changed.
|
-- Note that when this method is used, any player already in a slot will not have its menus visibility changed.
|
||||||
-- The option will only have effect when a player enters a new slot or changes a slot.
|
-- The option will only have effect when a player enters a new slot or changes a slot.
|
||||||
@@ -94,8 +93,8 @@
|
|||||||
--
|
--
|
||||||
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)).
|
||||||
-- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
-- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
|
||||||
-- - A2G LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
-- - A2G LL DMS: Latitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
|
||||||
-- - A2G LL DDM: Lattitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
-- - A2G LL DDM: Latitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
|
||||||
--
|
--
|
||||||
-- ### 3.1.2) A2G coordinates setting **menu**
|
-- ### 3.1.2) A2G coordinates setting **menu**
|
||||||
--
|
--
|
||||||
@@ -183,7 +182,7 @@
|
|||||||
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
|
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
|
||||||
--
|
--
|
||||||
-- Each Message Type has specific timings that will be applied when the message is displayed.
|
-- Each Message Type has specific timings that will be applied when the message is displayed.
|
||||||
-- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be choosen.
|
-- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be chosen.
|
||||||
-- So the player can choose its own amount of seconds how long a message should be displayed of a certain type.
|
-- So the player can choose its own amount of seconds how long a message should be displayed of a certain type.
|
||||||
-- Note that **Update** messages can be chosen not to be displayed at all!
|
-- Note that **Update** messages can be chosen not to be displayed at all!
|
||||||
--
|
--
|
||||||
@@ -196,7 +195,7 @@
|
|||||||
--
|
--
|
||||||
-- ## 3.5) **Era** of the battle
|
-- ## 3.5) **Era** of the battle
|
||||||
--
|
--
|
||||||
-- The threat level metric is scaled according the era of the battle. A target that is AAA, will pose a much greather threat in WWII than on modern warfare.
|
-- The threat level metric is scaled according the era of the battle. A target that is AAA, will pose a much greater threat in WWII than on modern warfare.
|
||||||
-- Therefore, there are 4 era that are defined within the settings:
|
-- Therefore, there are 4 era that are defined within the settings:
|
||||||
--
|
--
|
||||||
-- - **WWII** era: Use for warfare with equipment during the world war II time.
|
-- - **WWII** era: Use for warfare with equipment during the world war II time.
|
||||||
@@ -231,7 +230,6 @@ SETTINGS.__Enum.Era = {
|
|||||||
Modern = 4,
|
Modern = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
do -- SETTINGS
|
do -- SETTINGS
|
||||||
|
|
||||||
--- SETTINGS constructor.
|
--- SETTINGS constructor.
|
||||||
@@ -268,14 +266,14 @@ do -- SETTINGS
|
|||||||
-- Short text are better suited for, e.g., VR.
|
-- Short text are better suited for, e.g., VR.
|
||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @param #boolean onoff If *true* use short menu texts. If *false* long ones (default).
|
-- @param #boolean onoff If *true* use short menu texts. If *false* long ones (default).
|
||||||
function SETTINGS:SetMenutextShort(onoff)
|
function SETTINGS:SetMenutextShort( onoff )
|
||||||
_SETTINGS.MenuShort = onoff
|
_SETTINGS.MenuShort = onoff
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set menu to be static.
|
--- Set menu to be static.
|
||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @param #boolean onoff If *true* menu is static. If *false* menu will be updated after changes (default).
|
-- @param #boolean onoff If *true* menu is static. If *false* menu will be updated after changes (default).
|
||||||
function SETTINGS:SetMenuStatic(onoff)
|
function SETTINGS:SetMenuStatic( onoff )
|
||||||
_SETTINGS.MenuStatic = onoff
|
_SETTINGS.MenuStatic = onoff
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -289,7 +287,7 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if metric.
|
-- @return #boolean true if metric.
|
||||||
function SETTINGS:IsMetric()
|
function SETTINGS:IsMetric()
|
||||||
return ( self.Metric ~= nil and self.Metric == true ) or ( self.Metric == nil and _SETTINGS:IsMetric() )
|
return (self.Metric ~= nil and self.Metric == true) or (self.Metric == nil and _SETTINGS:IsMetric())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the SETTINGS imperial.
|
--- Sets the SETTINGS imperial.
|
||||||
@@ -302,7 +300,7 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if imperial.
|
-- @return #boolean true if imperial.
|
||||||
function SETTINGS:IsImperial()
|
function SETTINGS:IsImperial()
|
||||||
return ( self.Metric ~= nil and self.Metric == false ) or ( self.Metric == nil and _SETTINGS:IsMetric() )
|
return (self.Metric ~= nil and self.Metric == false) or (self.Metric == nil and _SETTINGS:IsMetric())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets the SETTINGS LL accuracy.
|
--- Sets the SETTINGS LL accuracy.
|
||||||
@@ -344,13 +342,12 @@ do -- SETTINGS
|
|||||||
self.MessageTypeTimings[MessageType] = MessageTime
|
self.MessageTypeTimings[MessageType] = MessageTime
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Gets the SETTINGS Message Display Timing of a MessageType
|
--- Gets the SETTINGS Message Display Timing of a MessageType
|
||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @param Core.Message#MESSAGE MessageType The type of the message.
|
-- @param Core.Message#MESSAGE MessageType The type of the message.
|
||||||
-- @return #number
|
-- @return #number
|
||||||
function SETTINGS:GetMessageTime( MessageType )
|
function SETTINGS:GetMessageTime( MessageType )
|
||||||
return ( self.MessageTypeTimings and self.MessageTypeTimings[MessageType] ) or _SETTINGS:GetMessageTime( MessageType )
|
return (self.MessageTypeTimings and self.MessageTypeTimings[MessageType]) or _SETTINGS:GetMessageTime( MessageType )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets A2G LL DMS
|
--- Sets A2G LL DMS
|
||||||
@@ -371,14 +368,14 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if LL DMS
|
-- @return #boolean true if LL DMS
|
||||||
function SETTINGS:IsA2G_LL_DMS()
|
function SETTINGS:IsA2G_LL_DMS()
|
||||||
return ( self.A2GSystem and self.A2GSystem == "LL DMS" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_LL_DMS() )
|
return (self.A2GSystem and self.A2GSystem == "LL DMS") or (not self.A2GSystem and _SETTINGS:IsA2G_LL_DMS())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Is LL DDM
|
--- Is LL DDM
|
||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if LL DDM
|
-- @return #boolean true if LL DDM
|
||||||
function SETTINGS:IsA2G_LL_DDM()
|
function SETTINGS:IsA2G_LL_DDM()
|
||||||
return ( self.A2GSystem and self.A2GSystem == "LL DDM" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_LL_DDM() )
|
return (self.A2GSystem and self.A2GSystem == "LL DDM") or (not self.A2GSystem and _SETTINGS:IsA2G_LL_DDM())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets A2G MGRS
|
--- Sets A2G MGRS
|
||||||
@@ -392,7 +389,7 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if MGRS
|
-- @return #boolean true if MGRS
|
||||||
function SETTINGS:IsA2G_MGRS()
|
function SETTINGS:IsA2G_MGRS()
|
||||||
return ( self.A2GSystem and self.A2GSystem == "MGRS" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_MGRS() )
|
return (self.A2GSystem and self.A2GSystem == "MGRS") or (not self.A2GSystem and _SETTINGS:IsA2G_MGRS())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets A2G BRA
|
--- Sets A2G BRA
|
||||||
@@ -406,7 +403,7 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if BRA
|
-- @return #boolean true if BRA
|
||||||
function SETTINGS:IsA2G_BR()
|
function SETTINGS:IsA2G_BR()
|
||||||
return ( self.A2GSystem and self.A2GSystem == "BR" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_BR() )
|
return (self.A2GSystem and self.A2GSystem == "BR") or (not self.A2GSystem and _SETTINGS:IsA2G_BR())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets A2A BRA
|
--- Sets A2A BRA
|
||||||
@@ -420,7 +417,7 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if BRA
|
-- @return #boolean true if BRA
|
||||||
function SETTINGS:IsA2A_BRAA()
|
function SETTINGS:IsA2A_BRAA()
|
||||||
return ( self.A2ASystem and self.A2ASystem == "BRAA" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BRAA() )
|
return (self.A2ASystem and self.A2ASystem == "BRAA") or (not self.A2ASystem and _SETTINGS:IsA2A_BRAA())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets A2A BULLS
|
--- Sets A2A BULLS
|
||||||
@@ -434,7 +431,7 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if BULLS
|
-- @return #boolean true if BULLS
|
||||||
function SETTINGS:IsA2A_BULLS()
|
function SETTINGS:IsA2A_BULLS()
|
||||||
return ( self.A2ASystem and self.A2ASystem == "BULLS" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BULLS() )
|
return (self.A2ASystem and self.A2ASystem == "BULLS") or (not self.A2ASystem and _SETTINGS:IsA2A_BULLS())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets A2A LL DMS
|
--- Sets A2A LL DMS
|
||||||
@@ -455,14 +452,14 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if LL DMS
|
-- @return #boolean true if LL DMS
|
||||||
function SETTINGS:IsA2A_LL_DMS()
|
function SETTINGS:IsA2A_LL_DMS()
|
||||||
return ( self.A2ASystem and self.A2ASystem == "LL DMS" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_LL_DMS() )
|
return (self.A2ASystem and self.A2ASystem == "LL DMS") or (not self.A2ASystem and _SETTINGS:IsA2A_LL_DMS())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Is LL DDM
|
--- Is LL DDM
|
||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if LL DDM
|
-- @return #boolean true if LL DDM
|
||||||
function SETTINGS:IsA2A_LL_DDM()
|
function SETTINGS:IsA2A_LL_DDM()
|
||||||
return ( self.A2ASystem and self.A2ASystem == "LL DDM" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_LL_DDM() )
|
return (self.A2ASystem and self.A2ASystem == "LL DDM") or (not self.A2ASystem and _SETTINGS:IsA2A_LL_DDM())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Sets A2A MGRS
|
--- Sets A2A MGRS
|
||||||
@@ -476,7 +473,7 @@ do -- SETTINGS
|
|||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #boolean true if MGRS
|
-- @return #boolean true if MGRS
|
||||||
function SETTINGS:IsA2A_MGRS()
|
function SETTINGS:IsA2A_MGRS()
|
||||||
return ( self.A2ASystem and self.A2ASystem == "MGRS" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_MGRS() )
|
return (self.A2ASystem and self.A2ASystem == "MGRS") or (not self.A2ASystem and _SETTINGS:IsA2A_MGRS())
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
@@ -495,37 +492,37 @@ do -- SETTINGS
|
|||||||
-- A2G Coordinate System
|
-- A2G Coordinate System
|
||||||
-------
|
-------
|
||||||
|
|
||||||
local text="A2G Coordinate System"
|
local text = "A2G Coordinate System"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2G Coordinates"
|
text = "A2G Coordinates"
|
||||||
end
|
end
|
||||||
local A2GCoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
local A2GCoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
||||||
|
|
||||||
-- Set LL DMS
|
-- Set LL DMS
|
||||||
if not self:IsA2G_LL_DMS() then
|
if not self:IsA2G_LL_DMS() then
|
||||||
local text="Lat/Lon Degree Min Sec (LL DMS)"
|
local text = "Lat/Lon Degree Min Sec (LL DMS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="LL DMS"
|
text = "LL DMS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set LL DDM
|
-- Set LL DDM
|
||||||
if not self:IsA2G_LL_DDM() then
|
if not self:IsA2G_LL_DDM() then
|
||||||
local text="Lat/Lon Degree Dec Min (LL DDM)"
|
local text = "Lat/Lon Degree Dec Min (LL DDM)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="LL DDM"
|
text = "LL DDM"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set LL DMS accuracy.
|
-- Set LL DMS accuracy.
|
||||||
if self:IsA2G_LL_DDM() then
|
if self:IsA2G_LL_DDM() then
|
||||||
local text1="LL DDM Accuracy 1"
|
local text1 = "LL DDM Accuracy 1"
|
||||||
local text2="LL DDM Accuracy 2"
|
local text2 = "LL DDM Accuracy 2"
|
||||||
local text3="LL DDM Accuracy 3"
|
local text3 = "LL DDM Accuracy 3"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text1="LL DDM"
|
text1 = "LL DDM"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime )
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime )
|
||||||
@@ -534,18 +531,18 @@ do -- SETTINGS
|
|||||||
|
|
||||||
-- Set BR.
|
-- Set BR.
|
||||||
if not self:IsA2G_BR() then
|
if not self:IsA2G_BR() then
|
||||||
local text="Bearing, Range (BR)"
|
local text = "Bearing, Range (BR)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="BR"
|
text = "BR"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text , A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Set MGRS.
|
-- Set MGRS.
|
||||||
if not self:IsA2G_MGRS() then
|
if not self:IsA2G_MGRS() then
|
||||||
local text="Military Grid (MGRS)"
|
local text = "Military Grid (MGRS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="MGRS"
|
text = "MGRS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
@@ -563,24 +560,24 @@ do -- SETTINGS
|
|||||||
-- A2A Coordinate System
|
-- A2A Coordinate System
|
||||||
-------
|
-------
|
||||||
|
|
||||||
local text="A2A Coordinate System"
|
local text = "A2A Coordinate System"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2A Coordinates"
|
text = "A2A Coordinates"
|
||||||
end
|
end
|
||||||
local A2ACoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
local A2ACoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
||||||
|
|
||||||
if not self:IsA2A_LL_DMS() then
|
if not self:IsA2A_LL_DMS() then
|
||||||
local text="Lat/Lon Degree Min Sec (LL DMS)"
|
local text = "Lat/Lon Degree Min Sec (LL DMS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="LL DMS"
|
text = "LL DMS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_LL_DDM() then
|
if not self:IsA2A_LL_DDM() then
|
||||||
local text="Lat/Lon Degree Dec Min (LL DDM)"
|
local text = "Lat/Lon Degree Dec Min (LL DDM)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="LL DDM"
|
text = "LL DDM"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
@@ -593,25 +590,25 @@ do -- SETTINGS
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_BULLS() then
|
if not self:IsA2A_BULLS() then
|
||||||
local text="Bullseye (BULLS)"
|
local text = "Bullseye (BULLS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Bulls"
|
text = "Bulls"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BULLS" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BULLS" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_BRAA() then
|
if not self:IsA2A_BRAA() then
|
||||||
local text="Bearing Range Altitude Aspect (BRAA)"
|
local text = "Bearing Range Altitude Aspect (BRAA)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="BRAA"
|
text = "BRAA"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BRAA" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BRAA" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_MGRS() then
|
if not self:IsA2A_MGRS() then
|
||||||
local text="Military Grid (MGRS)"
|
local text = "Military Grid (MGRS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="MGRS"
|
text = "MGRS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
@@ -624,31 +621,31 @@ do -- SETTINGS
|
|||||||
MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 5", A2ACoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 5 ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 5", A2ACoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 5 ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
local text="Measures and Weights System"
|
local text = "Measures and Weights System"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Unit System"
|
text = "Unit System"
|
||||||
end
|
end
|
||||||
local MetricsMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
local MetricsMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
||||||
|
|
||||||
if self:IsMetric() then
|
if self:IsMetric() then
|
||||||
local text="Imperial (Miles,Feet)"
|
local text = "Imperial (Miles,Feet)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Imperial"
|
text = "Imperial"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, false ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, false ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
if self:IsImperial() then
|
if self:IsImperial() then
|
||||||
local text="Metric (Kilometers,Meters)"
|
local text = "Metric (Kilometers,Meters)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Metric"
|
text = "Metric"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, true ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, true ):SetTime( MenuTime )
|
||||||
end
|
end
|
||||||
|
|
||||||
local text="Messages and Reports"
|
local text = "Messages and Reports"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Messages & Reports"
|
text = "Messages & Reports"
|
||||||
end
|
end
|
||||||
local MessagesMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
local MessagesMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
|
||||||
|
|
||||||
@@ -689,7 +686,6 @@ do -- SETTINGS
|
|||||||
MENU_GROUP_COMMAND:New( MenuGroup, "2 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 120 ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, "2 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 120 ):SetTime( MenuTime )
|
||||||
MENU_GROUP_COMMAND:New( MenuGroup, "3 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 180 ):SetTime( MenuTime )
|
MENU_GROUP_COMMAND:New( MenuGroup, "3 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 180 ):SetTime( MenuTime )
|
||||||
|
|
||||||
|
|
||||||
SettingsMenu:Remove( MenuTime )
|
SettingsMenu:Remove( MenuTime )
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@@ -733,7 +729,7 @@ do -- SETTINGS
|
|||||||
|
|
||||||
self.PlayerMenu = PlayerMenu
|
self.PlayerMenu = PlayerMenu
|
||||||
|
|
||||||
self:I(string.format("Setting menu for player %s", tostring(PlayerName)))
|
self:I( string.format( "Setting menu for player %s", tostring( PlayerName ) ) )
|
||||||
|
|
||||||
local submenu = MENU_GROUP:New( PlayerGroup, "LL Accuracy", PlayerMenu )
|
local submenu = MENU_GROUP:New( PlayerGroup, "LL Accuracy", PlayerMenu )
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 0 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 0 )
|
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 0 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 0 )
|
||||||
@@ -754,40 +750,40 @@ do -- SETTINGS
|
|||||||
-- A2G Coordinate System
|
-- A2G Coordinate System
|
||||||
------
|
------
|
||||||
|
|
||||||
local text="A2G Coordinate System"
|
local text = "A2G Coordinate System"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2G Coordinates"
|
text = "A2G Coordinates"
|
||||||
end
|
end
|
||||||
local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
||||||
|
|
||||||
if not self:IsA2G_LL_DMS() or _SETTINGS.MenuStatic then
|
if not self:IsA2G_LL_DMS() or _SETTINGS.MenuStatic then
|
||||||
local text="Lat/Lon Degree Min Sec (LL DMS)"
|
local text = "Lat/Lon Degree Min Sec (LL DMS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2G LL DMS"
|
text = "A2G LL DMS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2G_LL_DDM() or _SETTINGS.MenuStatic then
|
if not self:IsA2G_LL_DDM() or _SETTINGS.MenuStatic then
|
||||||
local text="Lat/Lon Degree Dec Min (LL DDM)"
|
local text = "Lat/Lon Degree Dec Min (LL DDM)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2G LL DDM"
|
text = "A2G LL DDM"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2G_BR() or _SETTINGS.MenuStatic then
|
if not self:IsA2G_BR() or _SETTINGS.MenuStatic then
|
||||||
local text="Bearing, Range (BR)"
|
local text = "Bearing, Range (BR)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2G BR"
|
text = "A2G BR"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2G_MGRS() or _SETTINGS.MenuStatic then
|
if not self:IsA2G_MGRS() or _SETTINGS.MenuStatic then
|
||||||
local text="Military Grid (MGRS)"
|
local text = "Military Grid (MGRS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2G MGRS"
|
text = "A2G MGRS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
||||||
end
|
end
|
||||||
@@ -796,49 +792,48 @@ do -- SETTINGS
|
|||||||
-- A2A Coordinates Menu
|
-- A2A Coordinates Menu
|
||||||
------
|
------
|
||||||
|
|
||||||
local text="A2A Coordinate System"
|
local text = "A2A Coordinate System"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2A Coordinates"
|
text = "A2A Coordinates"
|
||||||
end
|
end
|
||||||
local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
||||||
|
|
||||||
|
|
||||||
if not self:IsA2A_LL_DMS() or _SETTINGS.MenuStatic then
|
if not self:IsA2A_LL_DMS() or _SETTINGS.MenuStatic then
|
||||||
local text="Lat/Lon Degree Min Sec (LL DMS)"
|
local text = "Lat/Lon Degree Min Sec (LL DMS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2A LL DMS"
|
text = "A2A LL DMS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_LL_DDM() or _SETTINGS.MenuStatic then
|
if not self:IsA2A_LL_DDM() or _SETTINGS.MenuStatic then
|
||||||
local text="Lat/Lon Degree Dec Min (LL DDM)"
|
local text = "Lat/Lon Degree Dec Min (LL DDM)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2A LL DDM"
|
text = "A2A LL DDM"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_BULLS() or _SETTINGS.MenuStatic then
|
if not self:IsA2A_BULLS() or _SETTINGS.MenuStatic then
|
||||||
local text="Bullseye (BULLS)"
|
local text = "Bullseye (BULLS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2A BULLS"
|
text = "A2A BULLS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_BRAA() or _SETTINGS.MenuStatic then
|
if not self:IsA2A_BRAA() or _SETTINGS.MenuStatic then
|
||||||
local text="Bearing Range Altitude Aspect (BRAA)"
|
local text = "Bearing Range Altitude Aspect (BRAA)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2A BRAA"
|
text = "A2A BRAA"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self:IsA2A_MGRS() or _SETTINGS.MenuStatic then
|
if not self:IsA2A_MGRS() or _SETTINGS.MenuStatic then
|
||||||
local text="Military Grid (MGRS)"
|
local text = "Military Grid (MGRS)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="A2A MGRS"
|
text = "A2A MGRS"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
||||||
end
|
end
|
||||||
@@ -847,24 +842,24 @@ do -- SETTINGS
|
|||||||
-- Unit system
|
-- Unit system
|
||||||
---
|
---
|
||||||
|
|
||||||
local text="Measures and Weights System"
|
local text = "Measures and Weights System"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Unit System"
|
text = "Unit System"
|
||||||
end
|
end
|
||||||
local MetricsMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
local MetricsMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
||||||
|
|
||||||
if self:IsMetric() or _SETTINGS.MenuStatic then
|
if self:IsMetric() or _SETTINGS.MenuStatic then
|
||||||
local text="Imperial (Miles,Feet)"
|
local text = "Imperial (Miles,Feet)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Imperial"
|
text = "Imperial"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false )
|
||||||
end
|
end
|
||||||
|
|
||||||
if self:IsImperial() or _SETTINGS.MenuStatic then
|
if self:IsImperial() or _SETTINGS.MenuStatic then
|
||||||
local text="Metric (Kilometers,Meters)"
|
local text = "Metric (Kilometers,Meters)"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Metric"
|
text = "Metric"
|
||||||
end
|
end
|
||||||
MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true )
|
MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true )
|
||||||
end
|
end
|
||||||
@@ -873,9 +868,9 @@ do -- SETTINGS
|
|||||||
-- Messages and Reports
|
-- Messages and Reports
|
||||||
---
|
---
|
||||||
|
|
||||||
local text="Messages and Reports"
|
local text = "Messages and Reports"
|
||||||
if _SETTINGS.MenuShort then
|
if _SETTINGS.MenuShort then
|
||||||
text="Messages & Reports"
|
text = "Messages & Reports"
|
||||||
end
|
end
|
||||||
local MessagesMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
local MessagesMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
|
||||||
|
|
||||||
@@ -935,39 +930,38 @@ do -- SETTINGS
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
|
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
|
||||||
self.A2GSystem = A2GSystem
|
self.A2GSystem = A2GSystem
|
||||||
MESSAGE:New( string.format("Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem )
|
function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem )
|
||||||
self.A2ASystem = A2ASystem
|
self.A2ASystem = A2ASystem
|
||||||
MESSAGE:New( string.format("Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuLL_DDM_Accuracy( MenuGroup, RootMenu, LL_Accuracy )
|
function SETTINGS:MenuLL_DDM_Accuracy( MenuGroup, RootMenu, LL_Accuracy )
|
||||||
self.LL_Accuracy = LL_Accuracy
|
self.LL_Accuracy = LL_Accuracy
|
||||||
MESSAGE:New( string.format("Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy )
|
function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy )
|
||||||
self.MGRS_Accuracy = MGRS_Accuracy
|
self.MGRS_Accuracy = MGRS_Accuracy
|
||||||
MESSAGE:New( string.format("Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW )
|
function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW )
|
||||||
self.Metric = MW
|
self.Metric = MW
|
||||||
MESSAGE:New( string.format("Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll()
|
MESSAGE:New( string.format( "Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll()
|
||||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -980,12 +974,12 @@ do -- SETTINGS
|
|||||||
do
|
do
|
||||||
--- @param #SETTINGS self
|
--- @param #SETTINGS self
|
||||||
function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem )
|
function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem )
|
||||||
BASE:E( {self, PlayerUnit:GetName(), A2GSystem} )
|
BASE:E( { self, PlayerUnit:GetName(), A2GSystem } )
|
||||||
self.A2GSystem = A2GSystem
|
self.A2GSystem = A2GSystem
|
||||||
MESSAGE:New( string.format( "Settings: A2G format set to %s for player %s.", A2GSystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: A2G format set to %s for player %s.", A2GSystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
if _SETTINGS.MenuStatic==false then
|
if _SETTINGS.MenuStatic == false then
|
||||||
self:RemovePlayerMenu(PlayerUnit)
|
self:RemovePlayerMenu( PlayerUnit )
|
||||||
self:SetPlayerMenu(PlayerUnit)
|
self:SetPlayerMenu( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -993,9 +987,9 @@ do -- SETTINGS
|
|||||||
function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem )
|
function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem )
|
||||||
self.A2ASystem = A2ASystem
|
self.A2ASystem = A2ASystem
|
||||||
MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
if _SETTINGS.MenuStatic==false then
|
if _SETTINGS.MenuStatic == false then
|
||||||
self:RemovePlayerMenu(PlayerUnit)
|
self:RemovePlayerMenu( PlayerUnit )
|
||||||
self:SetPlayerMenu(PlayerUnit)
|
self:SetPlayerMenu( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1003,9 +997,9 @@ do -- SETTINGS
|
|||||||
function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy )
|
function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy )
|
||||||
self.LL_Accuracy = LL_Accuracy
|
self.LL_Accuracy = LL_Accuracy
|
||||||
MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
if _SETTINGS.MenuStatic==false then
|
if _SETTINGS.MenuStatic == false then
|
||||||
self:RemovePlayerMenu(PlayerUnit)
|
self:RemovePlayerMenu( PlayerUnit )
|
||||||
self:SetPlayerMenu(PlayerUnit)
|
self:SetPlayerMenu( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1013,9 +1007,9 @@ do -- SETTINGS
|
|||||||
function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy )
|
function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy )
|
||||||
self.MGRS_Accuracy = MGRS_Accuracy
|
self.MGRS_Accuracy = MGRS_Accuracy
|
||||||
MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
if _SETTINGS.MenuStatic==false then
|
if _SETTINGS.MenuStatic == false then
|
||||||
self:RemovePlayerMenu(PlayerUnit)
|
self:RemovePlayerMenu( PlayerUnit )
|
||||||
self:SetPlayerMenu(PlayerUnit)
|
self:SetPlayerMenu( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1023,9 +1017,9 @@ do -- SETTINGS
|
|||||||
function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW )
|
function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW )
|
||||||
self.Metric = MW
|
self.Metric = MW
|
||||||
MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup )
|
MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||||
if _SETTINGS.MenuStatic==false then
|
if _SETTINGS.MenuStatic == false then
|
||||||
self:RemovePlayerMenu(PlayerUnit)
|
self:RemovePlayerMenu( PlayerUnit )
|
||||||
self:SetPlayerMenu(PlayerUnit)
|
self:SetPlayerMenu( PlayerUnit )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1055,7 +1049,6 @@ do -- SETTINGS
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Configures the era of the mission to be Cold war.
|
--- Configures the era of the mission to be Cold war.
|
||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #SETTINGS self
|
-- @return #SETTINGS self
|
||||||
@@ -1065,7 +1058,6 @@ do -- SETTINGS
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Configures the era of the mission to be Modern war.
|
--- Configures the era of the mission to be Modern war.
|
||||||
-- @param #SETTINGS self
|
-- @param #SETTINGS self
|
||||||
-- @return #SETTINGS self
|
-- @return #SETTINGS self
|
||||||
@@ -1075,7 +1067,4 @@ do -- SETTINGS
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -422,7 +422,11 @@ function SPAWNSTATIC:_SpawnStatic(Template, CountryID)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.InitCargo~=nil then
|
if self.InitCargo~=nil then
|
||||||
Template.isCargo=self.InitCargo
|
Template.canCargo=self.InitCargo
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.InitCargoMass~=nil then
|
||||||
|
Template.mass=self.InitCargoMass
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.InitLinkUnit then
|
if self.InitLinkUnit then
|
||||||
|
|||||||
@@ -183,12 +183,12 @@ function ZONE_BASE:IsCoordinateInZone( Coordinate )
|
|||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns if a PointVec2 is within the zone.
|
--- Returns if a PointVec2 is within the zone. (Name is misleading, actually takes a #COORDINATE)
|
||||||
-- @param #ZONE_BASE self
|
-- @param #ZONE_BASE self
|
||||||
-- @param Core.Point#POINT_VEC2 PointVec2 The PointVec2 to test.
|
-- @param Core.Point#COORDINATE PointVec2 The coordinate to test.
|
||||||
-- @return #boolean true if the PointVec2 is within the zone.
|
-- @return #boolean true if the PointVec2 is within the zone.
|
||||||
function ZONE_BASE:IsPointVec2InZone( PointVec2 )
|
function ZONE_BASE:IsPointVec2InZone( Coordinate )
|
||||||
local InZone = self:IsVec2InZone( PointVec2:GetVec2() )
|
local InZone = self:IsVec2InZone( Coordinate:GetVec2() )
|
||||||
return InZone
|
return InZone
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
-- @module Functional.FOX
|
-- @module Functional.FOX
|
||||||
-- @image Functional_FOX.png
|
-- @image Functional_FOX.png
|
||||||
|
|
||||||
|
|
||||||
--- FOX class.
|
--- FOX class.
|
||||||
-- @type FOX
|
-- @type FOX
|
||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
@@ -48,7 +47,6 @@
|
|||||||
-- @field #number dt05 Time step [sec] for missile position updates if distance to target > 5 km and < 10 km. Default 0.5 sec.
|
-- @field #number dt05 Time step [sec] for missile position updates if distance to target > 5 km and < 10 km. Default 0.5 sec.
|
||||||
-- @field #number dt01 Time step [sec] for missile position updates if distance to target > 1 km and < 5 km. Default 0.1 sec.
|
-- @field #number dt01 Time step [sec] for missile position updates if distance to target > 1 km and < 5 km. Default 0.1 sec.
|
||||||
-- @field #number dt00 Time step [sec] for missile position updates if distance to target < 1 km. Default 0.01 sec.
|
-- @field #number dt00 Time step [sec] for missile position updates if distance to target < 1 km. Default 0.01 sec.
|
||||||
-- @field #boolean
|
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- Fox 3!
|
--- Fox 3!
|
||||||
@@ -1707,8 +1705,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
|
||||||
|
|||||||
@@ -19,13 +19,13 @@
|
|||||||
--
|
--
|
||||||
-- @module Functional.Mantis
|
-- @module Functional.Mantis
|
||||||
-- @image Functional.Mantis.jpg
|
-- @image Functional.Mantis.jpg
|
||||||
|
--
|
||||||
-- Date: July 2021
|
-- Date: Nov 2021
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
-------------------------------------------------------------------------
|
||||||
--- **MANTIS** class, extends #Core.Base#BASE
|
--- **MANTIS** class, extends Core.Base#BASE
|
||||||
-- @type MANTIS
|
-- @type MANTIS
|
||||||
-- @field #string Classname
|
-- @field #string ClassName
|
||||||
-- @field #string name Name of this Mantis
|
-- @field #string name Name of this Mantis
|
||||||
-- @field #string SAM_Templates_Prefix Prefix to build the #SET_GROUP for SAM sites
|
-- @field #string SAM_Templates_Prefix Prefix to build the #SET_GROUP for SAM sites
|
||||||
-- @field Core.Set#SET_GROUP SAM_Group The SAM #SET_GROUP
|
-- @field Core.Set#SET_GROUP SAM_Group The SAM #SET_GROUP
|
||||||
@@ -101,23 +101,23 @@
|
|||||||
--
|
--
|
||||||
-- # 2. Start up your MANTIS with a basic setting
|
-- # 2. Start up your MANTIS with a basic setting
|
||||||
--
|
--
|
||||||
-- `myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)`
|
-- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)
|
||||||
-- `myredmantis:Start()`
|
-- myredmantis:Start()
|
||||||
--
|
--
|
||||||
-- [optional] Use
|
-- [optional] Use
|
||||||
--
|
--
|
||||||
-- * `MANTIS:SetEWRGrouping(radius)`
|
-- * MANTIS:SetEWRGrouping(radius)
|
||||||
-- * `MANTIS:SetEWRRange(radius)`
|
-- * MANTIS:SetEWRRange(radius)
|
||||||
-- * `MANTIS:SetSAMRadius(radius)`
|
-- * MANTIS:SetSAMRadius(radius)
|
||||||
-- * `MANTIS:SetDetectInterval(interval)`
|
-- * MANTIS:SetDetectInterval(interval)
|
||||||
-- * `MANTIS:SetAutoRelocate(hq, ewr)`
|
-- * MANTIS:SetAutoRelocate(hq, ewr)
|
||||||
--
|
--
|
||||||
-- before starting #MANTIS to fine-tune your setup.
|
-- before starting #MANTIS to fine-tune your setup.
|
||||||
--
|
--
|
||||||
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
|
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
|
||||||
--
|
--
|
||||||
-- `mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")`
|
-- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
||||||
-- `mybluemantis:Start()`
|
-- mybluemantis:Start()
|
||||||
--
|
--
|
||||||
-- # 3. Default settings
|
-- # 3. Default settings
|
||||||
--
|
--
|
||||||
@@ -138,7 +138,7 @@
|
|||||||
--
|
--
|
||||||
-- Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Awacs is counted as one EWR unit. It will set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option.
|
-- Advanced mode will *decrease* reactivity of MANTIS, if HQ and/or EWR network dies. Awacs is counted as one EWR unit. It will set SAMs to RED state if both are dead. Requires usage of an **HQ** object and the **dynamic** option.
|
||||||
--
|
--
|
||||||
-- E.g. `mymantis:SetAdvancedMode( true, 90 )`
|
-- E.g. mymantis:SetAdvancedMode( true, 90 )
|
||||||
--
|
--
|
||||||
-- Use this option if you want to make use of or allow advanced SEAD tactics.
|
-- Use this option if you want to make use of or allow advanced SEAD tactics.
|
||||||
--
|
--
|
||||||
@@ -147,16 +147,39 @@
|
|||||||
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in
|
-- You can also choose to integrate Mantis with @{Functional.Shorad#SHORAD} for protection against HARMs and AGMs. When SHORAD detects a missile fired at one of MANTIS' SAM sites, it will activate SHORAD systems in
|
||||||
-- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so:
|
-- the given defense checkradius around that SAM site. Create a SHORAD object first, then integrate with MANTIS like so:
|
||||||
--
|
--
|
||||||
-- `local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()`
|
-- local SamSet = SET_GROUP:New():FilterPrefixes("Blue SAM"):FilterCoalitions("blue"):FilterStart()
|
||||||
-- `myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")`
|
-- myshorad = SHORAD:New("BlueShorad", "Blue SHORAD", SamSet, 22000, 600, "blue")
|
||||||
-- `-- now set up MANTIS`
|
-- -- now set up MANTIS
|
||||||
-- `mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")`
|
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
||||||
-- `mymantis:AddShorad(myshorad,720)`
|
-- mymantis:AddShorad(myshorad,720)
|
||||||
-- `mymantis:Start()`
|
-- mymantis:Start()
|
||||||
--
|
--
|
||||||
-- and (optionally) remove the link later on with
|
-- and (optionally) remove the link later on with
|
||||||
--
|
--
|
||||||
-- `mymantis:RemoveShorad()`
|
-- mymantis:RemoveShorad()
|
||||||
|
--
|
||||||
|
-- # 6. Integrated SEAD
|
||||||
|
--
|
||||||
|
-- MANTIS is using @{Functional.Sead#SEAD} internally to both detect and evade HARM attacks. No extra efforts needed to set this up!
|
||||||
|
-- Once a HARM attack is detected, MANTIS (via SEAD) will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
|
||||||
|
-- vehicles around (*if they are __drivable__*, that is). There's a component of randomness in detection and evasion, which is based on the
|
||||||
|
-- skill set of the SAM set (the higher the skill, the more likely). When a missile is fired from far away, the SAM will stay active for a
|
||||||
|
-- period of time to stay defensive, before it takes evasive actions.
|
||||||
|
--
|
||||||
|
-- You can link into the SEAD driven events of MANTIS like so:
|
||||||
|
--
|
||||||
|
-- function mymantis:OnAfterSeadSuppressionPlanned(From, Event, To, Group, Name, SuppressionStartTime, SuppressionEndTime)
|
||||||
|
-- -- your code here - SAM site shutdown and evasion planned, but not yet executed
|
||||||
|
-- -- Time entries relate to timer.getTime() - see https://wiki.hoggitworld.com/view/DCS_func_getTime
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- function mymantis:OnAfterSeadSuppressionStart(From, Event, To, Group, Name)
|
||||||
|
-- -- your code here - SAM site is emissions off and possibly moving
|
||||||
|
-- end
|
||||||
|
--
|
||||||
|
-- function mymantis:OnAfterSeadSuppressionEnd(From, Event, To, Group, Name)
|
||||||
|
-- -- your code here - SAM site is back online
|
||||||
|
-- end
|
||||||
--
|
--
|
||||||
-- @field #MANTIS
|
-- @field #MANTIS
|
||||||
MANTIS = {
|
MANTIS = {
|
||||||
@@ -195,6 +218,10 @@ MANTIS = {
|
|||||||
TimeStamp = 0,
|
TimeStamp = 0,
|
||||||
state2flag = false,
|
state2flag = false,
|
||||||
SamStateTracker = {},
|
SamStateTracker = {},
|
||||||
|
DLink = false,
|
||||||
|
DLTimeStamp = 0,
|
||||||
|
Padding = 10,
|
||||||
|
SuppressedGroups = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Advanced state enumerator
|
--- Advanced state enumerator
|
||||||
@@ -219,29 +246,30 @@ do
|
|||||||
--@param #string coaltion Coalition side of your setup, e.g. "blue", "red" or "neutral"
|
--@param #string coaltion Coalition side of your setup, e.g. "blue", "red" or "neutral"
|
||||||
--@param #boolean dynamic Use constant (true) filtering or just filter once (false, default) (optional)
|
--@param #boolean dynamic Use constant (true) filtering or just filter once (false, default) (optional)
|
||||||
--@param #string awacs Group name of your Awacs (optional)
|
--@param #string awacs Group name of your Awacs (optional)
|
||||||
--@param #boolean EmOnOff Make MANTIS switch Emissions on and off instead of changing the alarm state between RED and GREEN
|
--@param #boolean EmOnOff Make MANTIS switch Emissions on and off instead of changing the alarm state between RED and GREEN (optional)
|
||||||
|
--@param #number Padding For #SEAD - Extra number of seconds to add to radar switch-back-on time (optional)
|
||||||
--@return #MANTIS self
|
--@return #MANTIS self
|
||||||
--@usage Start up your MANTIS with a basic setting
|
--@usage Start up your MANTIS with a basic setting
|
||||||
--
|
--
|
||||||
-- `myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)`
|
-- myredmantis = MANTIS:New("myredmantis","Red SAM","Red EWR",nil,"red",false)
|
||||||
-- `myredmantis:Start()`
|
-- myredmantis:Start()
|
||||||
--
|
--
|
||||||
-- [optional] Use
|
-- [optional] Use
|
||||||
--
|
--
|
||||||
-- * `MANTIS:SetEWRGrouping(radius)`
|
-- * MANTIS:SetEWRGrouping(radius)
|
||||||
-- * `MANTIS:SetEWRRange(radius)`
|
-- * MANTIS:SetEWRRange(radius)
|
||||||
-- * `MANTIS:SetSAMRadius(radius)`
|
-- * MANTIS:SetSAMRadius(radius)
|
||||||
-- * `MANTIS:SetDetectInterval(interval)`
|
-- * MANTIS:SetDetectInterval(interval)
|
||||||
-- * `MANTIS:SetAutoRelocate(hq, ewr)`
|
-- * MANTIS:SetAutoRelocate(hq, ewr)
|
||||||
--
|
--
|
||||||
-- before starting #MANTIS to fine-tune your setup.
|
-- before starting #MANTIS to fine-tune your setup.
|
||||||
--
|
--
|
||||||
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
|
-- If you want to use a separate AWACS unit (default detection range: 250km) to support your EWR system, use e.g. the following setup:
|
||||||
--
|
--
|
||||||
-- `mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")`
|
-- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
||||||
-- `mybluemantis:Start()`
|
-- mybluemantis:Start()
|
||||||
--
|
--
|
||||||
function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs, EmOnOff)
|
function MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic,awacs, EmOnOff, Padding)
|
||||||
|
|
||||||
-- DONE: Create some user functions for these
|
-- DONE: Create some user functions for these
|
||||||
-- DONE: Make HQ useful
|
-- DONE: Make HQ useful
|
||||||
@@ -278,6 +306,9 @@ do
|
|||||||
self.relointerval = math.random(1800,3600) -- random between 30 and 60 mins
|
self.relointerval = math.random(1800,3600) -- random between 30 and 60 mins
|
||||||
self.state2flag = false
|
self.state2flag = false
|
||||||
self.SamStateTracker = {} -- table to hold alert states, so we don't trigger state changes twice in adv mode
|
self.SamStateTracker = {} -- table to hold alert states, so we don't trigger state changes twice in adv mode
|
||||||
|
self.DLink = false
|
||||||
|
self.Padding = Padding or 10
|
||||||
|
self.SuppressedGroups = {}
|
||||||
|
|
||||||
if EmOnOff then
|
if EmOnOff then
|
||||||
if EmOnOff == false then
|
if EmOnOff == false then
|
||||||
@@ -325,7 +356,7 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
self.version="0.5.2"
|
self.version="0.7.1"
|
||||||
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
self:I(string.format("***** Starting MANTIS Version %s *****", self.version))
|
||||||
|
|
||||||
--- FSM Functions ---
|
--- FSM Functions ---
|
||||||
@@ -342,6 +373,9 @@ do
|
|||||||
self:AddTransition("*", "RedState", "*") -- MANTIS A SAM switching to RED state.
|
self:AddTransition("*", "RedState", "*") -- MANTIS A SAM switching to RED state.
|
||||||
self:AddTransition("*", "AdvStateChange", "*") -- MANTIS advanced mode state change.
|
self:AddTransition("*", "AdvStateChange", "*") -- MANTIS advanced mode state change.
|
||||||
self:AddTransition("*", "ShoradActivated", "*") -- MANTIS woke up a connected SHORAD.
|
self:AddTransition("*", "ShoradActivated", "*") -- MANTIS woke up a connected SHORAD.
|
||||||
|
self:AddTransition("*", "SeadSuppressionStart", "*") -- SEAD has switched off one group.
|
||||||
|
self:AddTransition("*", "SeadSuppressionEnd", "*") -- SEAD has switched on one group.
|
||||||
|
self:AddTransition("*", "SeadSuppressionPlanned", "*") -- SEAD has planned a suppression.
|
||||||
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
|
||||||
|
|
||||||
------------------------
|
------------------------
|
||||||
@@ -421,6 +455,35 @@ do
|
|||||||
-- @param #number Radius Radius around the named group to find SHORAD groups
|
-- @param #number Radius Radius around the named group to find SHORAD groups
|
||||||
-- @param #number Ontime Seconds the SHORAD will stay active
|
-- @param #number Ontime Seconds the SHORAD will stay active
|
||||||
|
|
||||||
|
--- On After "SeadSuppressionPlanned" event. Mantis has planned to switch off a site to defend SEAD attack.
|
||||||
|
-- @function [parent=#MANTIS] OnAfterSeadSuppressionPlanned
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #string From The From State
|
||||||
|
-- @param #string Event The Event
|
||||||
|
-- @param #string To The To State
|
||||||
|
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
|
||||||
|
-- @param #string Name Name of the suppressed group
|
||||||
|
-- @param #number SuppressionStartTime Model start time of the suppression from `timer.getTime()`
|
||||||
|
-- @param #number SuppressionEndTime Model end time of the suppression from `timer.getTime()`
|
||||||
|
|
||||||
|
--- On After "SeadSuppressionStart" event. Mantis has switched off a site to defend a SEAD attack.
|
||||||
|
-- @function [parent=#MANTIS] OnAfterSeadSuppressionStart
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #string From The From State
|
||||||
|
-- @param #string Event The Event
|
||||||
|
-- @param #string To The To State
|
||||||
|
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
|
||||||
|
-- @param #string Name Name of the suppressed groupe
|
||||||
|
|
||||||
|
--- On After "SeadSuppressionEnd" event. Mantis has switched on a site after a SEAD attack.
|
||||||
|
-- @function [parent=#MANTIS] OnAfterSeadSuppressionEnd
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #string From The From State
|
||||||
|
-- @param #string Event The Event
|
||||||
|
-- @param #string To The To State
|
||||||
|
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
|
||||||
|
-- @param #string Name Name of the suppressed group
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -593,7 +656,7 @@ do
|
|||||||
-- E.g. `mymantis:SetAdvancedMode(true, 90)`
|
-- E.g. `mymantis:SetAdvancedMode(true, 90)`
|
||||||
function MANTIS:SetAdvancedMode(onoff, ratio)
|
function MANTIS:SetAdvancedMode(onoff, ratio)
|
||||||
self:T(self.lid .. "SetAdvancedMode")
|
self:T(self.lid .. "SetAdvancedMode")
|
||||||
self:T({onoff, ratio})
|
--self:T({onoff, ratio})
|
||||||
local onoff = onoff or false
|
local onoff = onoff or false
|
||||||
local ratio = ratio or 100
|
local ratio = ratio or 100
|
||||||
if (type(self.HQ_Template_CC) == "string") and onoff and self.dynamic then
|
if (type(self.HQ_Template_CC) == "string") and onoff and self.dynamic then
|
||||||
@@ -619,6 +682,17 @@ do
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set using an #INTEL_DLINK object instead of #DETECTION
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param Ops.Intelligence#INTEL_DLINK DLink The data link object to be used.
|
||||||
|
function MANTIS:SetUsingDLink(DLink)
|
||||||
|
self:T(self.lid .. "SetUsingDLink")
|
||||||
|
self.DLink = true
|
||||||
|
self.Detection = DLink
|
||||||
|
self.DLTimeStamp = timer.getAbsTime()
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- [Internal] Function to check if HQ is alive
|
--- [Internal] Function to check if HQ is alive
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
-- @return #boolean True if HQ is alive, else false
|
-- @return #boolean True if HQ is alive, else false
|
||||||
@@ -633,10 +707,10 @@ do
|
|||||||
local hqgrp = GROUP:FindByName(hq)
|
local hqgrp = GROUP:FindByName(hq)
|
||||||
if hqgrp then
|
if hqgrp then
|
||||||
if hqgrp:IsAlive() then -- ok we're on, hq exists and as alive
|
if hqgrp:IsAlive() then -- ok we're on, hq exists and as alive
|
||||||
self:T(self.lid.." HQ is alive!")
|
--self:T(self.lid.." HQ is alive!")
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
self:T(self.lid.." HQ is dead!")
|
--self:T(self.lid.." HQ is dead!")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -650,7 +724,7 @@ do
|
|||||||
function MANTIS:_CheckEWRState()
|
function MANTIS:_CheckEWRState()
|
||||||
self:T(self.lid .. "CheckEWRState")
|
self:T(self.lid .. "CheckEWRState")
|
||||||
local text = self.lid.." Checking EWR State"
|
local text = self.lid.." Checking EWR State"
|
||||||
self:T(text)
|
--self:T(text)
|
||||||
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(text) end
|
if self.verbose then self:I(text) end
|
||||||
-- start check
|
-- start check
|
||||||
@@ -666,7 +740,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:T(self.lid..string.format(" No of EWR alive is %d", nalive))
|
--self:T(self.lid..string.format(" No of EWR alive is %d", nalive))
|
||||||
if nalive > 0 then
|
if nalive > 0 then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
@@ -682,10 +756,8 @@ do
|
|||||||
-- @return #number Previous state for tracking 0, 1, or 2
|
-- @return #number Previous state for tracking 0, 1, or 2
|
||||||
function MANTIS:_CalcAdvState()
|
function MANTIS:_CalcAdvState()
|
||||||
self:T(self.lid .. "CalcAdvState")
|
self:T(self.lid .. "CalcAdvState")
|
||||||
local text = self.lid.." Calculating Advanced State"
|
local m=MESSAGE:New(self.lid.." Calculating Advanced State",10,"MANTIS"):ToAllIf(self.debug)
|
||||||
self:T(text)
|
if self.verbose then self:I(self.lid.." Calculating Advanced State") end
|
||||||
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
|
||||||
if self.verbose then self:I(text) end
|
|
||||||
-- start check
|
-- start check
|
||||||
local currstate = self.adv_state -- save curr state for comparison later
|
local currstate = self.adv_state -- save curr state for comparison later
|
||||||
local EWR_State = self:_CheckEWRState()
|
local EWR_State = self:_CheckEWRState()
|
||||||
@@ -703,10 +775,12 @@ do
|
|||||||
local ratio = self.adv_ratio / 100 -- e.g. 80/100 = 0.8
|
local ratio = self.adv_ratio / 100 -- e.g. 80/100 = 0.8
|
||||||
ratio = ratio * self.adv_state -- e.g 0.8*2 = 1.6
|
ratio = ratio * self.adv_state -- e.g 0.8*2 = 1.6
|
||||||
local newinterval = interval + (interval * ratio) -- e.g. 30+(30*1.6) = 78
|
local newinterval = interval + (interval * ratio) -- e.g. 30+(30*1.6) = 78
|
||||||
|
if self.debug or self.verbose then
|
||||||
local text = self.lid..string.format(" Calculated OldState/NewState/Interval: %d / %d / %d", currstate, self.adv_state, newinterval)
|
local text = self.lid..string.format(" Calculated OldState/NewState/Interval: %d / %d / %d", currstate, self.adv_state, newinterval)
|
||||||
self:T(text)
|
--self:T(text)
|
||||||
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(text) end
|
if self.verbose then self:I(text) end
|
||||||
|
end
|
||||||
return newinterval, currstate
|
return newinterval, currstate
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -716,13 +790,13 @@ do
|
|||||||
-- @param #boolean ewr If true, will relocate EWR objects
|
-- @param #boolean ewr If true, will relocate EWR objects
|
||||||
function MANTIS:SetAutoRelocate(hq, ewr)
|
function MANTIS:SetAutoRelocate(hq, ewr)
|
||||||
self:T(self.lid .. "SetAutoRelocate")
|
self:T(self.lid .. "SetAutoRelocate")
|
||||||
self:T({hq, ewr})
|
--self:T({hq, ewr})
|
||||||
local hqrel = hq or false
|
local hqrel = hq or false
|
||||||
local ewrel = ewr or false
|
local ewrel = ewr or false
|
||||||
if hqrel or ewrel then
|
if hqrel or ewrel then
|
||||||
self.autorelocate = true
|
self.autorelocate = true
|
||||||
self.autorelocateunits = { HQ = hqrel, EWR = ewrel }
|
self.autorelocateunits = { HQ = hqrel, EWR = ewrel }
|
||||||
self:T({self.autorelocate, self.autorelocateunits})
|
--self:T({self.autorelocate, self.autorelocateunits})
|
||||||
end
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -739,7 +813,7 @@ do
|
|||||||
local HQGroup = self.HQ_CC
|
local HQGroup = self.HQ_CC
|
||||||
if self.autorelocateunits.HQ and self.HQ_CC and HQGroup:IsAlive() then --only relocate if HQ exists
|
if self.autorelocateunits.HQ and self.HQ_CC and HQGroup:IsAlive() then --only relocate if HQ exists
|
||||||
local _hqgrp = self.HQ_CC
|
local _hqgrp = self.HQ_CC
|
||||||
self:T(self.lid.." Relocating HQ")
|
--self:T(self.lid.." Relocating HQ")
|
||||||
local text = self.lid.." Relocating HQ"
|
local text = self.lid.." Relocating HQ"
|
||||||
--local m= MESSAGE:New(text,10,"MANTIS"):ToAll()
|
--local m= MESSAGE:New(text,10,"MANTIS"):ToAll()
|
||||||
_hqgrp:RelocateGroundRandomInRadius(20,500,true,true)
|
_hqgrp:RelocateGroundRandomInRadius(20,500,true,true)
|
||||||
@@ -752,7 +826,7 @@ do
|
|||||||
local EWR_Grps = EWR_GRP.Set --table of objects in SET_GROUP
|
local EWR_Grps = EWR_GRP.Set --table of objects in SET_GROUP
|
||||||
for _,_grp in pairs (EWR_Grps) do
|
for _,_grp in pairs (EWR_Grps) do
|
||||||
if _grp:IsAlive() and _grp:IsGround() then
|
if _grp:IsAlive() and _grp:IsGround() then
|
||||||
self:T(self.lid.." Relocating EWR ".._grp:GetName())
|
--self:T(self.lid.." Relocating EWR ".._grp:GetName())
|
||||||
local text = self.lid.." Relocating EWR ".._grp:GetName()
|
local text = self.lid.." Relocating EWR ".._grp:GetName()
|
||||||
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
local m= MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(text) end
|
if self.verbose then self:I(text) end
|
||||||
@@ -778,12 +852,14 @@ do
|
|||||||
for _,_coord in pairs (set) do
|
for _,_coord in pairs (set) do
|
||||||
local coord = _coord -- get current coord to check
|
local coord = _coord -- get current coord to check
|
||||||
-- output for cross-check
|
-- output for cross-check
|
||||||
|
local targetdistance = samcoordinate:DistanceFromPointVec2(coord)
|
||||||
|
if self.verbose or self.debug then
|
||||||
local dectstring = coord:ToStringLLDMS()
|
local dectstring = coord:ToStringLLDMS()
|
||||||
local samstring = samcoordinate:ToStringLLDMS()
|
local samstring = samcoordinate:ToStringLLDMS()
|
||||||
local targetdistance = samcoordinate:DistanceFromPointVec2(coord)
|
|
||||||
local text = string.format("Checking SAM at % s - Distance %d m - Target %s", samstring, targetdistance, dectstring)
|
local text = string.format("Checking SAM at % s - Distance %d m - Target %s", samstring, targetdistance, dectstring)
|
||||||
local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug)
|
local m = MESSAGE:New(text,10,"Check"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(self.lid..text) end
|
self:I(self.lid..text)
|
||||||
|
end
|
||||||
-- end output to cross-check
|
-- end output to cross-check
|
||||||
if targetdistance <= radius then
|
if targetdistance <= radius then
|
||||||
return true, targetdistance
|
return true, targetdistance
|
||||||
@@ -872,6 +948,7 @@ do
|
|||||||
local group = _group -- Wrapper.Group#GROUP
|
local group = _group -- Wrapper.Group#GROUP
|
||||||
-- TODO: add emissions on/off
|
-- TODO: add emissions on/off
|
||||||
if self.UseEmOnOff then
|
if self.UseEmOnOff then
|
||||||
|
group:OptionAlarmStateRed()
|
||||||
group:EnableEmission(false)
|
group:EnableEmission(false)
|
||||||
--group:SetAIOff()
|
--group:SetAIOff()
|
||||||
else
|
else
|
||||||
@@ -888,8 +965,12 @@ do
|
|||||||
end
|
end
|
||||||
self.SAM_Table = SAM_Tbl
|
self.SAM_Table = SAM_Tbl
|
||||||
-- make SAMs evasive
|
-- make SAMs evasive
|
||||||
local mysead = SEAD:New( SEAD_Grps )
|
local mysead = SEAD:New( SEAD_Grps, self.Padding ) -- Functional.Sead#SEAD
|
||||||
mysead:SetEngagementRange(engagerange)
|
mysead:SetEngagementRange(engagerange)
|
||||||
|
mysead:AddCallBack(self)
|
||||||
|
if self.UseEmOnOff then
|
||||||
|
mysead:SwitchEmissions(true)
|
||||||
|
end
|
||||||
self.mysead = mysead
|
self.mysead = mysead
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -976,22 +1057,24 @@ do
|
|||||||
local name = _data[1]
|
local name = _data[1]
|
||||||
local samgroup = GROUP:FindByName(name)
|
local samgroup = GROUP:FindByName(name)
|
||||||
local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate)
|
local IsInZone, Distance = self:CheckObjectInZone(detset, samcoordinate)
|
||||||
if IsInZone then --check any target in zone
|
local suppressed = self.SuppressedGroups[name] or false
|
||||||
|
if IsInZone then --check any target in zone and not curr managed by SEAD
|
||||||
if samgroup:IsAlive() then
|
if samgroup:IsAlive() then
|
||||||
-- switch on SAM
|
-- switch on SAM
|
||||||
if self.UseEmOnOff then
|
if self.UseEmOnOff and not suppressed then
|
||||||
-- TODO: add emissions on/off
|
-- DONE: add emissions on/off
|
||||||
--samgroup:SetAIOn()
|
--samgroup:SetAIOn()
|
||||||
samgroup:EnableEmission(true)
|
samgroup:EnableEmission(true)
|
||||||
end
|
elseif not self.UseEmOnOff and not suppressed then
|
||||||
samgroup:OptionAlarmStateRed()
|
samgroup:OptionAlarmStateRed()
|
||||||
if self.SamStateTracker[name] ~= "RED" then
|
end
|
||||||
|
if self.SamStateTracker[name] ~= "RED" and not suppressed then
|
||||||
self:__RedState(1,samgroup)
|
self:__RedState(1,samgroup)
|
||||||
self.SamStateTracker[name] = "RED"
|
self.SamStateTracker[name] = "RED"
|
||||||
end
|
end
|
||||||
-- link in to SHORAD if available
|
-- link in to SHORAD if available
|
||||||
-- DONE: Test integration fully
|
-- DONE: Test integration fully
|
||||||
if self.ShoradLink and Distance < self.ShoradActDistance then -- don't give SHORAD position away too early
|
if self.ShoradLink and (Distance < self.ShoradActDistance or suppressed) then -- don't give SHORAD position away too early
|
||||||
local Shorad = self.Shorad
|
local Shorad = self.Shorad
|
||||||
local radius = self.checkradius
|
local radius = self.checkradius
|
||||||
local ontime = self.ShoradTime
|
local ontime = self.ShoradTime
|
||||||
@@ -999,24 +1082,29 @@ do
|
|||||||
self:__ShoradActivated(1,name, radius, ontime)
|
self:__ShoradActivated(1,name, radius, ontime)
|
||||||
end
|
end
|
||||||
-- debug output
|
-- debug output
|
||||||
|
if self.debug or self.verbose and not suppressed then
|
||||||
local text = string.format("SAM %s switched to alarm state RED!", name)
|
local text = string.format("SAM %s switched to alarm state RED!", name)
|
||||||
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(self.lid..text) end
|
if self.verbose then self:I(self.lid..text) end
|
||||||
|
end
|
||||||
end --end alive
|
end --end alive
|
||||||
else
|
else
|
||||||
if samgroup:IsAlive() then
|
if samgroup:IsAlive() then
|
||||||
-- switch off SAM
|
-- switch off SAM
|
||||||
if self.UseEmOnOff then
|
if self.UseEmOnOff and not suppressed then
|
||||||
samgroup:EnableEmission(false)
|
samgroup:EnableEmission(false)
|
||||||
end
|
elseif not self.UseEmOnOff and not suppressed then
|
||||||
samgroup:OptionAlarmStateGreen()
|
samgroup:OptionAlarmStateGreen()
|
||||||
if self.SamStateTracker[name] ~= "GREEN" then
|
end
|
||||||
|
if self.SamStateTracker[name] ~= "GREEN" and not suppressed then
|
||||||
self:__GreenState(1,samgroup)
|
self:__GreenState(1,samgroup)
|
||||||
self.SamStateTracker[name] = "GREEN"
|
self.SamStateTracker[name] = "GREEN"
|
||||||
end
|
end
|
||||||
|
if self.debug or self.verbose and not suppressed then
|
||||||
local text = string.format("SAM %s switched to alarm state GREEN!", name)
|
local text = string.format("SAM %s switched to alarm state GREEN!", name)
|
||||||
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
local m=MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.debug)
|
||||||
if self.verbose then self:I(self.lid..text) end
|
if self.verbose then self:I(self.lid..text) end
|
||||||
|
end
|
||||||
end --end alive
|
end --end alive
|
||||||
end --end check
|
end --end check
|
||||||
end --for for loop
|
end --for for loop
|
||||||
@@ -1067,6 +1155,20 @@ do
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [Internal] Check DLink state
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @return #MANTIS self
|
||||||
|
function MANTIS:_CheckDLinkState()
|
||||||
|
self:T(self.lid .. "_CheckDLinkState")
|
||||||
|
local dlink = self.Detection -- Ops.Intelligence#INTEL_DLINK
|
||||||
|
local TS = timer.getAbsTime()
|
||||||
|
if not dlink:Is("Running") and (TS - self.DLTimeStamp > 29) then
|
||||||
|
self.DLink = false
|
||||||
|
self.Detection = self:StartDetection() -- fall back
|
||||||
|
self:I(self.lid .. "Intel DLink not running - switching back to single detection!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- [Internal] Function to set start state
|
--- [Internal] Function to set start state
|
||||||
-- @param #MANTIS self
|
-- @param #MANTIS self
|
||||||
-- @param #string From The From State
|
-- @param #string From The From State
|
||||||
@@ -1077,11 +1179,13 @@ do
|
|||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
self:T(self.lid.."Starting MANTIS")
|
self:T(self.lid.."Starting MANTIS")
|
||||||
self:SetSAMStartState()
|
self:SetSAMStartState()
|
||||||
|
if not self.DLink then
|
||||||
self.Detection = self:StartDetection()
|
self.Detection = self:StartDetection()
|
||||||
|
end
|
||||||
if self.advAwacs then
|
if self.advAwacs then
|
||||||
self.AWACS_Detection = self:StartAwacsDetection()
|
self.AWACS_Detection = self:StartAwacsDetection()
|
||||||
end
|
end
|
||||||
self:__Status(self.detectinterval)
|
self:__Status(-math.random(1,10))
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1120,11 +1224,16 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- timer for advanced state check
|
-- advanced state check
|
||||||
if self.advanced then
|
if self.advanced then
|
||||||
self:_CheckAdvState()
|
self:_CheckAdvState()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- check DLink state
|
||||||
|
if self.DLink then
|
||||||
|
self:_CheckDLinkState()
|
||||||
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -1136,6 +1245,13 @@ do
|
|||||||
-- @return #MANTIS self
|
-- @return #MANTIS self
|
||||||
function MANTIS:onafterStatus(From,Event,To)
|
function MANTIS:onafterStatus(From,Event,To)
|
||||||
self:T({From, Event, To})
|
self:T({From, Event, To})
|
||||||
|
-- Display some states
|
||||||
|
if self.debug then
|
||||||
|
self:I(self.lid .. "Status Report")
|
||||||
|
for _name,_state in pairs(self.SamStateTracker) do
|
||||||
|
self:I(string.format("Site %s\tStatus %s",_name,_state))
|
||||||
|
end
|
||||||
|
end
|
||||||
local interval = self.detectinterval * -1
|
local interval = self.detectinterval * -1
|
||||||
self:__Status(interval)
|
self:__Status(interval)
|
||||||
return self
|
return self
|
||||||
@@ -1213,6 +1329,47 @@ do
|
|||||||
self:T({From, Event, To, Name, Radius, Ontime})
|
self:T({From, Event, To, Name, Radius, Ontime})
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- [Internal] Function triggered by Event SeadSuppressionStart
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #string From The From State
|
||||||
|
-- @param #string Event The Event
|
||||||
|
-- @param #string To The To State
|
||||||
|
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
|
||||||
|
-- @param #string Name Name of the suppressed group
|
||||||
|
function MANTIS:onafterSeadSuppressionStart(From, Event, To, Group, Name)
|
||||||
|
self:T({From, Event, To, Name})
|
||||||
|
self.SuppressedGroups[Name] = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [Internal] Function triggered by Event SeadSuppressionEnd
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #string From The From State
|
||||||
|
-- @param #string Event The Event
|
||||||
|
-- @param #string To The To State
|
||||||
|
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
|
||||||
|
-- @param #string Name Name of the suppressed group
|
||||||
|
function MANTIS:onafterSeadSuppressionEnd(From, Event, To, Group, Name)
|
||||||
|
self:T({From, Event, To, Name})
|
||||||
|
self.SuppressedGroups[Name] = false
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- [Internal] Function triggered by Event SeadSuppressionPlanned
|
||||||
|
-- @param #MANTIS self
|
||||||
|
-- @param #string From The From State
|
||||||
|
-- @param #string Event The Event
|
||||||
|
-- @param #string To The To State
|
||||||
|
-- @param Wrapper.Group#GROUP Group The suppressed GROUP object
|
||||||
|
-- @param #string Name Name of the suppressed group
|
||||||
|
-- @param #number SuppressionStartTime Model start time of the suppression from `timer.getTime()`
|
||||||
|
-- @param #number SuppressionEndTime Model end time of the suppression from `timer.getTime()`
|
||||||
|
function MANTIS:onafterSeadSuppressionPlanned(From, Event, To, Group, Name, SuppressionStartTime, SuppressionEndTime)
|
||||||
|
self:T({From, Event, To, Name})
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
-- MANTIS end
|
-- MANTIS end
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -742,7 +742,7 @@ function PSEUDOATC:ReportWeather(GID, UID, position, location)
|
|||||||
local T=position:GetTemperature()
|
local T=position:GetTemperature()
|
||||||
|
|
||||||
-- Correct unit system.
|
-- Correct unit system.
|
||||||
local _T=string.format('%d°F', UTILS.CelciusToFarenheit(T))
|
local _T=string.format('%d°F', UTILS.CelsiusToFahrenheit(T))
|
||||||
if settings:IsMetric() then
|
if settings:IsMetric() then
|
||||||
_T=string.format('%d°C', T)
|
_T=string.format('%d°C', T)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -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()))
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -6,6 +6,8 @@
|
|||||||
--
|
--
|
||||||
-- * When SAM sites are being fired upon, the SAMs will take evasive action will reposition themselves when possible.
|
-- * When SAM sites are being fired upon, the SAMs will take evasive action will reposition themselves when possible.
|
||||||
-- * When SAM sites are being fired upon, the SAMs will take defensive action by shutting down their radars.
|
-- * When SAM sites are being fired upon, the SAMs will take defensive action by shutting down their radars.
|
||||||
|
-- * SEAD calculates the time it takes for a HARM to reach the target - and will attempt to minimize the shut-down time.
|
||||||
|
-- * Detection and evasion of shots has a random component based on the skill level of the SAM groups.
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -17,19 +19,24 @@
|
|||||||
--
|
--
|
||||||
-- ### Authors: **FlightControl**, **applevangelist**
|
-- ### Authors: **FlightControl**, **applevangelist**
|
||||||
--
|
--
|
||||||
-- Last Update: July 2021
|
-- Last Update: Nov 2021
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- @module Functional.Sead
|
-- @module Functional.Sead
|
||||||
-- @image SEAD.JPG
|
-- @image SEAD.JPG
|
||||||
|
|
||||||
--- @type SEAD
|
---
|
||||||
|
-- @type SEAD
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- Make SAM sites execute evasive and defensive behaviour when being fired upon.
|
--- Make SAM sites execute evasive and defensive behaviour when being fired upon.
|
||||||
--
|
--
|
||||||
-- This class is very easy to use. Just setup a SEAD object by using @{#SEAD.New}() and SAMs will evade and take defensive action when being fired upon.
|
-- This class is very easy to use. Just setup a SEAD object by using @{#SEAD.New}() and SAMs will evade and take defensive action when being fired upon.
|
||||||
|
-- Once a HARM attack is detected, SEAD will shut down the radars of the attacked SAM site and take evasive action by moving the SAM
|
||||||
|
-- vehicles around (*if* they are drivable, that is). There's a component of randomness in detection and evasion, which is based on the
|
||||||
|
-- skill set of the SAM set (the higher the skill, the more likely). When a missile is fired from far away, the SAM will stay active for a
|
||||||
|
-- period of time to stay defensive, before it takes evasive actions.
|
||||||
--
|
--
|
||||||
-- # Constructor:
|
-- # Constructor:
|
||||||
--
|
--
|
||||||
@@ -48,7 +55,10 @@ SEAD = {
|
|||||||
},
|
},
|
||||||
SEADGroupPrefixes = {},
|
SEADGroupPrefixes = {},
|
||||||
SuppressedGroups = {},
|
SuppressedGroups = {},
|
||||||
EngagementRange = 75 -- default 75% engagement range Feature Request #1355
|
EngagementRange = 75, -- default 75% engagement range Feature Request #1355
|
||||||
|
Padding = 10,
|
||||||
|
CallBack = nil,
|
||||||
|
UseCallBack = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Missile enumerators
|
--- Missile enumerators
|
||||||
@@ -59,7 +69,7 @@ SEAD = {
|
|||||||
["AGM_122"] = "AGM_122",
|
["AGM_122"] = "AGM_122",
|
||||||
["AGM_84"] = "AGM_84",
|
["AGM_84"] = "AGM_84",
|
||||||
["AGM_45"] = "AGM_45",
|
["AGM_45"] = "AGM_45",
|
||||||
["ALARN"] = "ALARM",
|
["ALARM"] = "ALARM",
|
||||||
["LD-10"] = "LD-10",
|
["LD-10"] = "LD-10",
|
||||||
["X_58"] = "X_58",
|
["X_58"] = "X_58",
|
||||||
["X_28"] = "X_28",
|
["X_28"] = "X_28",
|
||||||
@@ -68,17 +78,35 @@ SEAD = {
|
|||||||
["Kh25"] = "Kh25",
|
["Kh25"] = "Kh25",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Missile enumerators - from DCS ME and Wikipedia
|
||||||
|
-- @field HarmData
|
||||||
|
SEAD.HarmData = {
|
||||||
|
-- km and mach
|
||||||
|
["AGM_88"] = { 150, 3},
|
||||||
|
["AGM_45"] = { 12, 2},
|
||||||
|
["AGM_122"] = { 16.5, 2.3},
|
||||||
|
["AGM_84"] = { 280, 0.85},
|
||||||
|
["ALARM"] = { 45, 2},
|
||||||
|
["LD-10"] = { 60, 4},
|
||||||
|
["X_58"] = { 70, 4},
|
||||||
|
["X_28"] = { 80, 2.5},
|
||||||
|
["X_25"] = { 25, 0.76},
|
||||||
|
["X_31"] = {150, 3},
|
||||||
|
["Kh25"] = {25, 0.8},
|
||||||
|
}
|
||||||
|
|
||||||
--- Creates the main object which is handling defensive actions for SA sites or moving SA vehicles.
|
--- Creates the main object which is handling defensive actions for SA sites or moving SA vehicles.
|
||||||
-- When an anti radiation missile is fired (KH-58, KH-31P, KH-31A, KH-25MPU, HARM missiles), the SA will shut down their radars and will take evasive actions...
|
-- When an anti radiation missile is fired (KH-58, KH-31P, KH-31A, KH-25MPU, HARM missiles), the SA will shut down their radars and will take evasive actions...
|
||||||
-- Chances are big that the missile will miss.
|
-- Chances are big that the missile will miss.
|
||||||
-- @param #SEAD self
|
-- @param #SEAD self
|
||||||
-- @param table{string,...}|string SEADGroupPrefixes which is a table of Prefixes of the SA Groups in the DCS mission editor on which evasive actions need to be taken.
|
-- @param #table SEADGroupPrefixes Table of #string entries or single #string, which is a table of Prefixes of the SA Groups in the DCS mission editor on which evasive actions need to be taken.
|
||||||
-- @return SEAD
|
-- @param #number Padding (Optional) Extra number of seconds to add to radar switch-back-on time
|
||||||
|
-- @return #SEAD self
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- CCCP SEAD Defenses
|
-- -- CCCP SEAD Defenses
|
||||||
-- -- Defends the Russian SA installations from SEAD attacks.
|
-- -- Defends the Russian SA installations from SEAD attacks.
|
||||||
-- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } )
|
-- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } )
|
||||||
function SEAD:New( SEADGroupPrefixes )
|
function SEAD:New( SEADGroupPrefixes, Padding )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:F( SEADGroupPrefixes )
|
self:F( SEADGroupPrefixes )
|
||||||
@@ -91,18 +119,27 @@ function SEAD:New( SEADGroupPrefixes )
|
|||||||
self.SEADGroupPrefixes[SEADGroupPrefixes] = SEADGroupPrefixes
|
self.SEADGroupPrefixes[SEADGroupPrefixes] = SEADGroupPrefixes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local padding = Padding or 10
|
||||||
|
if padding < 10 then padding = 10 end
|
||||||
|
self.Padding = padding
|
||||||
|
self.UseEmissionsOnOff = false
|
||||||
|
|
||||||
|
self.CallBack = nil
|
||||||
|
self.UseCallBack = false
|
||||||
|
|
||||||
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.3.3")
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Update the active SEAD Set
|
--- Update the active SEAD Set (while running)
|
||||||
-- @param #SEAD self
|
-- @param #SEAD self
|
||||||
-- @param #table SEADGroupPrefixes The prefixes to add, note: can also be a single #string
|
-- @param #table SEADGroupPrefixes The prefixes to add, note: can also be a single #string
|
||||||
-- @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
|
||||||
@@ -117,10 +154,10 @@ end
|
|||||||
|
|
||||||
--- Sets the engagement range of the SAMs. Defaults to 75% to make it more deadly. Feature Request #1355
|
--- Sets the engagement range of the SAMs. Defaults to 75% to make it more deadly. Feature Request #1355
|
||||||
-- @param #SEAD self
|
-- @param #SEAD self
|
||||||
-- @param #number range Set the engagement range in percent, e.g. 50
|
-- @param #number range Set the engagement range in percent, e.g. 55 (default 75)
|
||||||
-- @return self
|
-- @return #SEAD 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
|
||||||
@@ -130,53 +167,125 @@ function SEAD:SetEngagementRange(range)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check if a known HARM was fired
|
--- Set the padding in seconds, which extends the radar off time calculated by SEAD
|
||||||
-- @param #SEAD self
|
-- @param #SEAD self
|
||||||
-- @param #string WeaponName
|
-- @param #number Padding Extra number of seconds to add for the switch-on (default 10 seconds)
|
||||||
-- @return #boolean Returns true for a match
|
-- @return #SEAD self
|
||||||
function SEAD:_CheckHarms(WeaponName)
|
function SEAD:SetPadding(Padding)
|
||||||
self:F( { WeaponName } )
|
self:T( { Padding } )
|
||||||
|
local padding = Padding or 10
|
||||||
|
if padding < 10 then padding = 10 end
|
||||||
|
self.Padding = padding
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set SEAD to use emissions on/off in addition to alarm state.
|
||||||
|
-- @param #SEAD self
|
||||||
|
-- @param #boolean Switch True for on, false for off.
|
||||||
|
-- @return #SEAD self
|
||||||
|
function SEAD:SwitchEmissions(Switch)
|
||||||
|
self:T({Switch})
|
||||||
|
self.UseEmissionsOnOff = Switch
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add an object to call back when going evasive.
|
||||||
|
-- @param #SEAD self
|
||||||
|
-- @param #table Object The object to call. Needs to have object functions as follows:
|
||||||
|
-- `:SeadSuppressionPlanned(Group, Name, SuppressionStartTime, SuppressionEndTime)`
|
||||||
|
-- `:SeadSuppressionStart(Group, Name)`,
|
||||||
|
-- `:SeadSuppressionEnd(Group, Name)`,
|
||||||
|
-- @return #SEAD self
|
||||||
|
function SEAD:AddCallBack(Object)
|
||||||
|
self:T({Class=Object.ClassName})
|
||||||
|
self.CallBack = Object
|
||||||
|
self.UseCallBack = true
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Check if a known HARM was fired
|
||||||
|
-- @param #SEAD self
|
||||||
|
-- @param #string WeaponName
|
||||||
|
-- @return #boolean Returns true for a match
|
||||||
|
-- @return #string name Name of hit in table
|
||||||
|
function SEAD:_CheckHarms(WeaponName)
|
||||||
|
self:T( { WeaponName } )
|
||||||
local hit = false
|
local hit = false
|
||||||
|
local name = ""
|
||||||
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
|
||||||
|
name = _name
|
||||||
|
break
|
||||||
end
|
end
|
||||||
return hit
|
|
||||||
end
|
end
|
||||||
|
return hit, name
|
||||||
|
end
|
||||||
|
|
||||||
--- Detects if an SAM site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME.
|
--- (Internal) Return distance in meters between two coordinates or -1 on error.
|
||||||
-- @see SEAD
|
-- @param #SEAD self
|
||||||
-- @param #SEAD
|
-- @param Core.Point#COORDINATE _point1 Coordinate one
|
||||||
|
-- @param Core.Point#COORDINATE _point2 Coordinate two
|
||||||
|
-- @return #number Distance in meters
|
||||||
|
function SEAD:_GetDistance(_point1, _point2)
|
||||||
|
self:T("_GetDistance")
|
||||||
|
if _point1 and _point2 then
|
||||||
|
local distance1 = _point1:Get2DDistance(_point2)
|
||||||
|
local distance2 = _point1:DistanceFromPointVec2(_point2)
|
||||||
|
--self:T({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
|
||||||
|
self:E("******Cannot calculate distance!")
|
||||||
|
self:E({_point1,_point2})
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- (Internal) Detects if an SAM site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME.
|
||||||
|
-- @param #SEAD self
|
||||||
-- @param Core.Event#EVENTDATA EventData
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
-- @return #SEAD self
|
||||||
function SEAD:HandleEventShot( EventData )
|
function SEAD:HandleEventShot( EventData )
|
||||||
self:T( { EventData } )
|
self:T( { EventData.id } )
|
||||||
|
local SEADPlane = EventData.IniUnit -- Wrapper.Unit#UNIT
|
||||||
|
local SEADPlanePos = SEADPlane:GetCoordinate() -- Core.Point#COORDINATE
|
||||||
local SEADUnit = EventData.IniDCSUnit
|
local SEADUnit = EventData.IniDCSUnit
|
||||||
local SEADUnitName = EventData.IniDCSUnitName
|
local SEADUnitName = EventData.IniDCSUnitName
|
||||||
local SEADWeapon = EventData.Weapon -- Identify the weapon fired
|
local SEADWeapon = EventData.Weapon -- Identify the weapon fired
|
||||||
local SEADWeaponName = EventData.WeaponName -- return weapon type
|
local SEADWeaponName = EventData.WeaponName -- return weapon type
|
||||||
|
|
||||||
self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
|
self:T( "*** SEAD - Missile Launched = " .. SEADWeaponName)
|
||||||
self:T({ SEADWeapon })
|
--self:T({ SEADWeapon })
|
||||||
|
|
||||||
if self:_CheckHarms(SEADWeaponName) then
|
if self:_CheckHarms(SEADWeaponName) then
|
||||||
|
self:T( '*** SEAD - Weapon Match' )
|
||||||
local _targetskill = "Random"
|
local _targetskill = "Random"
|
||||||
local _targetMimgroupName = "none"
|
local _targetgroupname = "none"
|
||||||
local _evade = math.random (1,100) -- random number for chance of evading action
|
local _target = EventData.Weapon:getTarget() -- Identify target
|
||||||
local _targetMim = EventData.Weapon:getTarget() -- Identify target
|
local _targetUnit = UNIT:Find(_target) -- Wrapper.Unit#UNIT
|
||||||
local _targetUnit = UNIT:Find(_targetMim) -- Unit name by DCS Object
|
local _targetgroup = nil -- Wrapper.Group#GROUP
|
||||||
if _targetUnit and _targetUnit:IsAlive() then
|
if _targetUnit and _targetUnit:IsAlive() then
|
||||||
local _targetMimgroup = _targetUnit:GetGroup()
|
_targetgroup = _targetUnit:GetGroup()
|
||||||
local _targetMimgroupName = _targetMimgroup:GetName() -- group name
|
_targetgroupname = _targetgroup:GetName() -- group name
|
||||||
--local _targetskill = _DATABASE.Templates.Units[_targetUnit].Template.skill
|
local _targetUnitName = _targetUnit:GetName()
|
||||||
self:T( self.SEADGroupPrefixes )
|
_targetUnit:GetSkill()
|
||||||
self:T( _targetMimgroupName )
|
_targetskill = _targetUnit:GetSkill()
|
||||||
end
|
end
|
||||||
-- 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
|
||||||
if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then
|
self:T( _targetgroupname, SEADGroupPrefix )
|
||||||
|
if string.find( _targetgroupname, SEADGroupPrefix, 1, true ) then
|
||||||
SEADGroupFound = true
|
SEADGroupFound = true
|
||||||
self:T( '*** SEAD - Group Found' )
|
self:T( '*** SEAD - Group Match Found' )
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -185,45 +294,91 @@ function SEAD:HandleEventShot( EventData )
|
|||||||
local Skills = { "Average", "Good", "High", "Excellent" }
|
local Skills = { "Average", "Good", "High", "Excellent" }
|
||||||
_targetskill = Skills[ math.random(1,4) ]
|
_targetskill = Skills[ math.random(1,4) ]
|
||||||
end
|
end
|
||||||
self:T( _targetskill )
|
--self:T( _targetskill )
|
||||||
if self.TargetSkill[_targetskill] then
|
if self.TargetSkill[_targetskill] then
|
||||||
|
local _evade = math.random (1,100) -- random number for chance of evading action
|
||||||
if (_evade > self.TargetSkill[_targetskill].Evade) then
|
if (_evade > self.TargetSkill[_targetskill].Evade) then
|
||||||
|
self:T("*** SEAD - Evading")
|
||||||
self:T( string.format("*** SEAD - Evading, target skill " ..string.format(_targetskill)) )
|
-- calculate distance of attacker
|
||||||
|
local _targetpos = _targetgroup:GetCoordinate()
|
||||||
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
|
local _distance = self:_GetDistance(SEADPlanePos, _targetpos)
|
||||||
local _targetMimcont= _targetMimgroup:getController()
|
-- weapon speed
|
||||||
|
local hit, data = self:_CheckHarms(SEADWeaponName)
|
||||||
routines.groupRandomDistSelf(_targetMimgroup,300,'Diamond',250,20) -- move randomly
|
local wpnspeed = 666 -- ;)
|
||||||
|
local reach = 10
|
||||||
--tracker ID table to switch groups off and on again
|
if hit then
|
||||||
local id = {
|
local wpndata = SEAD.HarmData[data]
|
||||||
groupName = _targetMimgroup,
|
reach = wpndata[1] * 1,1
|
||||||
ctrl = _targetMimcont
|
local mach = wpndata[2]
|
||||||
}
|
wpnspeed = math.floor(mach * 340.29)
|
||||||
|
|
||||||
local function SuppressionEnd(id) --switch group back on
|
|
||||||
local range = self.EngagementRange -- Feature Request #1355
|
|
||||||
self:T(string.format("*** SEAD - Engagement Range is %d", range))
|
|
||||||
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.RED)
|
|
||||||
--id.groupName:enableEmission(true)
|
|
||||||
id.ctrl:setOption(AI.Option.Ground.id.AC_ENGAGEMENT_RANGE_RESTRICTION,range) --Feature Request #1355
|
|
||||||
self.SuppressedGroups[id.groupName] = nil --delete group id from table when done
|
|
||||||
end
|
end
|
||||||
|
-- time to impact
|
||||||
|
local _tti = math.floor(_distance / wpnspeed) -- estimated impact time
|
||||||
|
if _distance > 0 then
|
||||||
|
_distance = math.floor(_distance / 1000) -- km
|
||||||
|
else
|
||||||
|
_distance = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
self:T( string.format("*** SEAD - target skill %s, distance %dkm, reach %dkm, tti %dsec", _targetskill, _distance,reach,_tti ))
|
||||||
|
|
||||||
|
if reach >= _distance then
|
||||||
|
self:T("*** SEAD - Shot in Reach")
|
||||||
|
|
||||||
|
local function SuppressionStart(args)
|
||||||
|
self:T(string.format("*** SEAD - %s Radar Off & Relocating",args[2]))
|
||||||
|
local grp = args[1] -- Wrapper.Group#GROUP
|
||||||
|
local name = args[2] -- #string Group Name
|
||||||
|
if self.UseEmissionsOnOff then
|
||||||
|
grp:EnableEmission(false)
|
||||||
|
end
|
||||||
|
grp:OptionAlarmStateGreen() -- needed else we cannot move around
|
||||||
|
grp:RelocateGroundRandomInRadius(20,300,false,false,"Diamond")
|
||||||
|
if self.UseCallBack then
|
||||||
|
local object = self.CallBack
|
||||||
|
object:SeadSuppressionStart(grp,name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function SuppressionStop(args)
|
||||||
|
self:T(string.format("*** SEAD - %s Radar On",args[2]))
|
||||||
|
local grp = args[1] -- Wrapper.Group#GROUP
|
||||||
|
local name = args[2] -- #string Group Nam
|
||||||
|
if self.UseEmissionsOnOff then
|
||||||
|
grp:EnableEmission(true)
|
||||||
|
end
|
||||||
|
grp:OptionAlarmStateAuto()
|
||||||
|
grp:OptionEngageRange(self.EngagementRange)
|
||||||
|
self.SuppressedGroups[name] = false
|
||||||
|
if self.UseCallBack then
|
||||||
|
local object = self.CallBack
|
||||||
|
object:SeadSuppressionEnd(grp,name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- randomize switch-on time
|
-- randomize switch-on time
|
||||||
local delay = math.random(self.TargetSkill[_targetskill].DelayOn[1], self.TargetSkill[_targetskill].DelayOn[2])
|
local delay = math.random(self.TargetSkill[_targetskill].DelayOn[1], self.TargetSkill[_targetskill].DelayOn[2])
|
||||||
local SuppressionEndTime = timer.getTime() + delay
|
if delay > _tti then delay = delay / 2 end -- speed up
|
||||||
--create entry
|
if _tti > (3*delay) then delay = (_tti / 2) * 0.9 end -- shot from afar
|
||||||
if self.SuppressedGroups[id.groupName] == nil then --no timer entry for this group yet
|
|
||||||
self.SuppressedGroups[id.groupName] = {
|
local SuppressionStartTime = timer.getTime() + delay
|
||||||
SuppressionEndTime = delay
|
local SuppressionEndTime = timer.getTime() + _tti + self.Padding
|
||||||
}
|
|
||||||
Controller.setOption(_targetMimcont, AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
|
if not self.SuppressedGroups[_targetgroupname] then
|
||||||
--_targetMimgroup:enableEmission(false)
|
self:T(string.format("*** SEAD - %s | Parameters TTI %ds | Switch-Off in %ds",_targetgroupname,_tti,delay))
|
||||||
timer.scheduleFunction(SuppressionEnd, id, SuppressionEndTime) --Schedule the SuppressionEnd() function
|
timer.scheduleFunction(SuppressionStart,{_targetgroup,_targetgroupname},SuppressionStartTime)
|
||||||
|
timer.scheduleFunction(SuppressionStop,{_targetgroup,_targetgroupname},SuppressionEndTime)
|
||||||
|
self.SuppressedGroups[_targetgroupname] = true
|
||||||
|
if self.UseCallBack then
|
||||||
|
local object = self.CallBack
|
||||||
|
object:SeadSuppressionPlanned(_targetgroup,_targetgroupname,SuppressionStartTime,SuppressionEndTime)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ do
|
|||||||
["AGM_122"] = "AGM_122",
|
["AGM_122"] = "AGM_122",
|
||||||
["AGM_84"] = "AGM_84",
|
["AGM_84"] = "AGM_84",
|
||||||
["AGM_45"] = "AGM_45",
|
["AGM_45"] = "AGM_45",
|
||||||
["ALARN"] = "ALARM",
|
["ALARM"] = "ALARM",
|
||||||
["LD-10"] = "LD-10",
|
["LD-10"] = "LD-10",
|
||||||
["X_58"] = "X_58",
|
["X_58"] = "X_58",
|
||||||
["X_28"] = "X_28",
|
["X_28"] = "X_28",
|
||||||
|
|||||||
@@ -1601,7 +1601,7 @@ WAREHOUSE = {
|
|||||||
-- @field #number range Range of the unit in meters.
|
-- @field #number range Range of the unit in meters.
|
||||||
-- @field #number speedmax Maximum speed in km/h the group can do.
|
-- @field #number speedmax Maximum speed in km/h the group can do.
|
||||||
-- @field #number size Maximum size in length and with of the asset in meters.
|
-- @field #number size Maximum size in length and with of the asset in meters.
|
||||||
-- @field #number weight The weight of the whole asset group in kilo gramms.
|
-- @field #number weight The weight of the whole asset group in kilograms.
|
||||||
-- @field DCS#Object.Desc DCSdesc All DCS descriptors.
|
-- @field DCS#Object.Desc DCSdesc All DCS descriptors.
|
||||||
-- @field #WAREHOUSE.Attribute attribute Generalized attribute of the group.
|
-- @field #WAREHOUSE.Attribute attribute Generalized attribute of the group.
|
||||||
-- @field #table cargobay Array of cargo bays of all units in an asset group.
|
-- @field #table cargobay Array of cargo bays of all units in an asset group.
|
||||||
|
|||||||
@@ -715,6 +715,7 @@ do -- ZONE_CAPTURE_COALITION
|
|||||||
|
|
||||||
local UnitHit = EventData.TgtUnit
|
local UnitHit = EventData.TgtUnit
|
||||||
|
|
||||||
|
if UnitHit.ClassName ~= "SCENERY" then
|
||||||
-- Check if unit is inside the capture zone and that it is of the defending coalition.
|
-- Check if unit is inside the capture zone and that it is of the defending coalition.
|
||||||
if UnitHit and UnitHit:IsInZone(self) and UnitHit:GetCoalition()==self.Coalition then
|
if UnitHit and UnitHit:IsInZone(self) and UnitHit:GetCoalition()==self.Coalition then
|
||||||
|
|
||||||
@@ -728,7 +729,7 @@ do -- ZONE_CAPTURE_COALITION
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -890,12 +891,14 @@ do -- ZONE_CAPTURE_COALITION
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Status text.
|
-- Status text.
|
||||||
|
if false then
|
||||||
local text=string.format("CAPTURE ZONE %s: Owner=%s (Previous=%s): #blue=%d, #red=%d, Status %s", self:GetZoneName(), self:GetCoalitionName(), UTILS.GetCoalitionName(self:GetPreviousCoalition()), nBlue, nRed, State)
|
local text=string.format("CAPTURE ZONE %s: Owner=%s (Previous=%s): #blue=%d, #red=%d, Status %s", self:GetZoneName(), self:GetCoalitionName(), UTILS.GetCoalitionName(self:GetPreviousCoalition()), nBlue, nRed, State)
|
||||||
local NewState = self:GetState()
|
local NewState = self:GetState()
|
||||||
if NewState~=State then
|
if NewState~=State then
|
||||||
text=text..string.format(" --> %s", NewState)
|
text=text..string.format(" --> %s", NewState)
|
||||||
end
|
end
|
||||||
self:I(text)
|
self:I(text)
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ _DATABASE:_RegisterCargos()
|
|||||||
|
|
||||||
--- Register zones.
|
--- Register zones.
|
||||||
_DATABASE:_RegisterZones()
|
_DATABASE:_RegisterZones()
|
||||||
|
_DATABASE:_RegisterAirbases()
|
||||||
|
|
||||||
--- Check if os etc is available.
|
--- Check if os etc is available.
|
||||||
BASE:I("Checking de-sanitization of os, io and lfs:")
|
BASE:I("Checking de-sanitization of os, io and lfs:")
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -802,7 +802,7 @@ function RESCUEHELO:_OnEventCrashOrEject(EventData)
|
|||||||
-- Debug.
|
-- Debug.
|
||||||
local text=string.format("Unit %s crashed or ejected.", unitname)
|
local text=string.format("Unit %s crashed or ejected.", unitname)
|
||||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||||
self:I(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
-- Get coordinate of unit.
|
-- Get coordinate of unit.
|
||||||
local coord=unit:GetCoordinate()
|
local coord=unit:GetCoordinate()
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ end
|
|||||||
--- Set the frequency for the radio transmission.
|
--- Set the frequency for the radio transmission.
|
||||||
-- If the transmitting positionable is a unit or group, this also set the command "SetFrequency" with the defined frequency and modulation.
|
-- If the transmitting positionable is a unit or group, this also set the command "SetFrequency" with the defined frequency and modulation.
|
||||||
-- @param #RADIO self
|
-- @param #RADIO self
|
||||||
-- @param #number Frequency Frequency in MHz. Ranges allowed for radio transmissions in DCS : 30-87.995 / 108-173.995 / 225-399.975MHz.
|
-- @param #number Frequency Frequency in MHz.
|
||||||
-- @return #RADIO self
|
-- @return #RADIO self
|
||||||
function RADIO:SetFrequency(Frequency)
|
function RADIO:SetFrequency(Frequency)
|
||||||
self:F2(Frequency)
|
self:F2(Frequency)
|
||||||
@@ -165,7 +165,7 @@ function RADIO:SetFrequency(Frequency)
|
|||||||
if type(Frequency) == "number" then
|
if type(Frequency) == "number" then
|
||||||
|
|
||||||
-- If frequency is in range
|
-- If frequency is in range
|
||||||
if (Frequency >= 30 and Frequency <= 87.995) or (Frequency >= 108 and Frequency <= 173.995) or (Frequency >= 225 and Frequency <= 399.975) then
|
-- if (Frequency >= 30 and Frequency <= 87.995) or (Frequency >= 108 and Frequency <= 173.995) or (Frequency >= 225 and Frequency <= 399.975) then
|
||||||
|
|
||||||
-- Convert frequency from MHz to Hz
|
-- Convert frequency from MHz to Hz
|
||||||
self.Frequency = Frequency * 1000000
|
self.Frequency = Frequency * 1000000
|
||||||
@@ -186,10 +186,10 @@ function RADIO:SetFrequency(Frequency)
|
|||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
-- end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:E({"Frequency is outside of DCS Frequency ranges (30-80, 108-152, 225-400). Frequency unchanged.", Frequency})
|
self:E({"Frequency is not a number. Frequency unchanged.", Frequency})
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -88,10 +88,19 @@
|
|||||||
--
|
--
|
||||||
-- Use a specific "culture" with the @{#MSRS.SetCulture} function, e.g. `:SetCulture("en-US")` or `:SetCulture("de-DE")`.
|
-- Use a specific "culture" with the @{#MSRS.SetCulture} function, e.g. `:SetCulture("en-US")` or `:SetCulture("de-DE")`.
|
||||||
--
|
--
|
||||||
|
-- ## Set Google
|
||||||
|
--
|
||||||
|
-- Use Google's text-to-speech engine with the @{#MSRS.SetGoogle} function, e.g. ':SetGoogle()'.
|
||||||
|
-- By enabling this it also allows you to utilize SSML in your text for added flexibilty.
|
||||||
|
-- For more information on setting up a cloud account, visit: https://cloud.google.com/text-to-speech
|
||||||
|
-- Google's supported SSML reference: https://cloud.google.com/text-to-speech/docs/ssml
|
||||||
|
--
|
||||||
-- ## Set Voice
|
-- ## Set Voice
|
||||||
--
|
--
|
||||||
-- Use a specifc voice with the @{#MSRS.SetVoice} function, e.g, `:SetVoice("Microsoft Hedda Desktop")`.
|
-- Use a specifc voice with the @{#MSRS.SetVoice} function, e.g, `:SetVoice("Microsoft Hedda Desktop")`.
|
||||||
-- Note that this must be installed on your windows system.
|
-- Note that this must be installed on your windows system.
|
||||||
|
-- If enabling SetGoogle(), you can use voices provided by Google
|
||||||
|
-- Google's supported voices: https://cloud.google.com/text-to-speech/docs/voices
|
||||||
--
|
--
|
||||||
-- ## Set Coordinate
|
-- ## Set Coordinate
|
||||||
--
|
--
|
||||||
@@ -678,7 +687,7 @@ function MSRS:_GetCommand(freqs, modus, coal, gender, voice, culture, volume, sp
|
|||||||
|
|
||||||
-- Set google.
|
-- Set google.
|
||||||
if self.google then
|
if self.google then
|
||||||
command=command..string.format(' -G "%s"', self.google)
|
command=command..string.format(' --ssml -G "%s"', self.google)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ do -- TASK_A2A
|
|||||||
--
|
--
|
||||||
-- @field #TASK_A2A
|
-- @field #TASK_A2A
|
||||||
TASK_A2A = {
|
TASK_A2A = {
|
||||||
ClassName = "TASK_A2A",
|
ClassName = "TASK_A2A"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2A.
|
--- Instantiates a new TASK_A2A.
|
||||||
@@ -60,29 +60,27 @@ do -- TASK_A2A
|
|||||||
|
|
||||||
local Fsm = self:GetUnitProcess()
|
local Fsm = self:GetUnitProcess()
|
||||||
|
|
||||||
|
|
||||||
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
||||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||||
|
|
||||||
Fsm:AddTransition( { "Arrived", "RoutingToRendezVous" }, "ArriveAtRendezVous", "ArrivedAtRendezVous" )
|
Fsm:AddTransition( { "Arrived", "RoutingToRendezVous" }, "ArriveAtRendezVous", "ArrivedAtRendezVous" )
|
||||||
|
|
||||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "Engage", "Engaging" )
|
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "Engage", "Engaging" )
|
||||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "HoldAtRendezVous", "HoldingAtRendezVous" )
|
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "HoldAtRendezVous", "HoldingAtRendezVous" )
|
||||||
|
|
||||||
Fsm:AddProcess ( "Engaging", "Account", ACT_ACCOUNT_DEADS:New(), {} )
|
Fsm:AddProcess( "Engaging", "Account", ACT_ACCOUNT_DEADS:New(), {} )
|
||||||
Fsm:AddTransition( "Engaging", "RouteToTarget", "Engaging" )
|
Fsm:AddTransition( "Engaging", "RouteToTarget", "Engaging" )
|
||||||
Fsm:AddProcess( "Engaging", "RouteToTargetZone", ACT_ROUTE_ZONE:New(), {} )
|
Fsm:AddProcess( "Engaging", "RouteToTargetZone", ACT_ROUTE_ZONE:New(), {} )
|
||||||
Fsm:AddProcess( "Engaging", "RouteToTargetPoint", ACT_ROUTE_POINT:New(), {} )
|
Fsm:AddProcess( "Engaging", "RouteToTargetPoint", ACT_ROUTE_POINT:New(), {} )
|
||||||
Fsm:AddTransition( "Engaging", "RouteToTargets", "Engaging" )
|
Fsm:AddTransition( "Engaging", "RouteToTargets", "Engaging" )
|
||||||
|
|
||||||
-- Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
-- Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
||||||
-- Fsm:AddTransition( "Accounted", "Success", "Success" )
|
-- Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||||
|
|
||||||
|
-- @param #FSM_PROCESS self
|
||||||
---- @param #FSM_PROCESS self
|
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
-- @param #TASK_CARGO Task
|
-- @param #TASK_CARGO Task
|
||||||
function Fsm:OnLeaveAssigned( TaskUnit, Task )
|
function Fsm:OnLeaveAssigned( TaskUnit, Task )
|
||||||
@@ -128,7 +126,7 @@ do -- TASK_A2A
|
|||||||
function Fsm:onafterEngage( TaskUnit, Task )
|
function Fsm:onafterEngage( TaskUnit, Task )
|
||||||
self:F( { self } )
|
self:F( { self } )
|
||||||
self:__Account( 0.1 )
|
self:__Account( 0.1 )
|
||||||
self:__RouteToTarget(0.1 )
|
self:__RouteToTarget( 0.1 )
|
||||||
self:__RouteToTargets( -10 )
|
self:__RouteToTargets( -10 )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -177,8 +175,6 @@ do -- TASK_A2A
|
|||||||
self.TargetSetUnit = TargetSetUnit
|
self.TargetSetUnit = TargetSetUnit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2A self
|
--- @param #TASK_A2A self
|
||||||
function TASK_A2A:GetPlannedMenuText()
|
function TASK_A2A:GetPlannedMenuText()
|
||||||
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
||||||
@@ -209,8 +205,6 @@ do -- TASK_A2A
|
|||||||
return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange()
|
return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2A self
|
--- @param #TASK_A2A self
|
||||||
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
|
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
@@ -244,7 +238,6 @@ do -- TASK_A2A
|
|||||||
ActRouteTarget:SetCoordinate( TargetCoordinate )
|
ActRouteTarget:SetCoordinate( TargetCoordinate )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2A self
|
--- @param #TASK_A2A self
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
-- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map.
|
-- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map.
|
||||||
@@ -256,7 +249,6 @@ do -- TASK_A2A
|
|||||||
return ActRouteTarget:GetCoordinate()
|
return ActRouteTarget:GetCoordinate()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2A self
|
--- @param #TASK_A2A self
|
||||||
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
|
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
@@ -268,7 +260,6 @@ do -- TASK_A2A
|
|||||||
ActRouteTarget:SetZone( TargetZone, Altitude, Heading )
|
ActRouteTarget:SetZone( TargetZone, Altitude, Heading )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2A self
|
--- @param #TASK_A2A self
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
|
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
|
||||||
@@ -301,7 +292,6 @@ do -- TASK_A2A
|
|||||||
return Distance
|
return Distance
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- This method checks every 10 seconds if the goal has been reached of the task.
|
--- This method checks every 10 seconds if the goal has been reached of the task.
|
||||||
-- @param #TASK_A2A self
|
-- @param #TASK_A2A self
|
||||||
function TASK_A2A:onafterGoal( TaskUnit, From, Event, To )
|
function TASK_A2A:onafterGoal( TaskUnit, From, Event, To )
|
||||||
@@ -314,7 +304,6 @@ do -- TASK_A2A
|
|||||||
self:__Goal( -10 )
|
self:__Goal( -10 )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2A self
|
--- @param #TASK_A2A self
|
||||||
function TASK_A2A:UpdateTaskInfo( DetectedItem )
|
function TASK_A2A:UpdateTaskInfo( DetectedItem )
|
||||||
|
|
||||||
@@ -375,7 +364,6 @@ do -- TASK_A2A
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- TASK_A2A_INTERCEPT
|
do -- TASK_A2A_INTERCEPT
|
||||||
|
|
||||||
--- The TASK_A2A_INTERCEPT class
|
--- The TASK_A2A_INTERCEPT class
|
||||||
@@ -384,7 +372,7 @@ do -- TASK_A2A_INTERCEPT
|
|||||||
-- @extends Tasking.Task#TASK
|
-- @extends Tasking.Task#TASK
|
||||||
|
|
||||||
--- Defines an intercept task for a human player to be executed.
|
--- Defines an intercept task for a human player to be executed.
|
||||||
-- When enemy planes need to be intercepted by human players, use this task type to urgen the players to get out there!
|
-- When enemy planes need to be intercepted by human players, use this task type to urge the players to get out there!
|
||||||
--
|
--
|
||||||
-- The TASK_A2A_INTERCEPT is used by the @{Tasking.Task_A2A_Dispatcher#TASK_A2A_DISPATCHER} to automatically create intercept tasks
|
-- The TASK_A2A_INTERCEPT is used by the @{Tasking.Task_A2A_Dispatcher#TASK_A2A_DISPATCHER} to automatically create intercept tasks
|
||||||
-- based on detected airborne enemy targets intruding friendly airspace.
|
-- based on detected airborne enemy targets intruding friendly airspace.
|
||||||
@@ -394,11 +382,9 @@ do -- TASK_A2A_INTERCEPT
|
|||||||
--
|
--
|
||||||
-- @field #TASK_A2A_INTERCEPT
|
-- @field #TASK_A2A_INTERCEPT
|
||||||
TASK_A2A_INTERCEPT = {
|
TASK_A2A_INTERCEPT = {
|
||||||
ClassName = "TASK_A2A_INTERCEPT",
|
ClassName = "TASK_A2A_INTERCEPT"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2A_INTERCEPT.
|
--- Instantiates a new TASK_A2A_INTERCEPT.
|
||||||
-- @param #TASK_A2A_INTERCEPT self
|
-- @param #TASK_A2A_INTERCEPT self
|
||||||
-- @param Tasking.Mission#MISSION Mission
|
-- @param Tasking.Mission#MISSION Mission
|
||||||
@@ -413,15 +399,12 @@ do -- TASK_A2A_INTERCEPT
|
|||||||
|
|
||||||
Mission:AddTask( self )
|
Mission:AddTask( self )
|
||||||
|
|
||||||
self:SetBriefing(
|
self:SetBriefing( TaskBriefing or "Intercept incoming intruders.\n" )
|
||||||
TaskBriefing or
|
|
||||||
"Intercept incoming intruders.\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a score when a target in scope of the A2A attack, has been destroyed .
|
--- Set a score when a target in scope of the A2A attack, has been destroyed.
|
||||||
-- @param #TASK_A2A_INTERCEPT self
|
-- @param #TASK_A2A_INTERCEPT self
|
||||||
-- @param #string PlayerName The name of the player.
|
-- @param #string PlayerName The name of the player.
|
||||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||||
@@ -469,10 +452,8 @@ do -- TASK_A2A_INTERCEPT
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- TASK_A2A_SWEEP
|
do -- TASK_A2A_SWEEP
|
||||||
|
|
||||||
--- The TASK_A2A_SWEEP class
|
--- The TASK_A2A_SWEEP class
|
||||||
@@ -493,11 +474,9 @@ do -- TASK_A2A_SWEEP
|
|||||||
--
|
--
|
||||||
-- @field #TASK_A2A_SWEEP
|
-- @field #TASK_A2A_SWEEP
|
||||||
TASK_A2A_SWEEP = {
|
TASK_A2A_SWEEP = {
|
||||||
ClassName = "TASK_A2A_SWEEP",
|
ClassName = "TASK_A2A_SWEEP"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2A_SWEEP.
|
--- Instantiates a new TASK_A2A_SWEEP.
|
||||||
-- @param #TASK_A2A_SWEEP self
|
-- @param #TASK_A2A_SWEEP self
|
||||||
-- @param Tasking.Mission#MISSION Mission
|
-- @param Tasking.Mission#MISSION Mission
|
||||||
@@ -512,10 +491,7 @@ do -- TASK_A2A_SWEEP
|
|||||||
|
|
||||||
Mission:AddTask( self )
|
Mission:AddTask( self )
|
||||||
|
|
||||||
self:SetBriefing(
|
self:SetBriefing( TaskBriefing or "Perform a fighter sweep. Incoming intruders were detected and could be hiding at the location.\n" )
|
||||||
TaskBriefing or
|
|
||||||
"Perform a fighter sweep. Incoming intruders were detected and could be hiding at the location.\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -531,7 +507,7 @@ do -- TASK_A2A_SWEEP
|
|||||||
self:__Goal( -10 )
|
self:__Goal( -10 )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Set a score when a target in scope of the A2A attack, has been destroyed .
|
--- Set a score when a target in scope of the A2A attack, has been destroyed.
|
||||||
-- @param #TASK_A2A_SWEEP self
|
-- @param #TASK_A2A_SWEEP self
|
||||||
-- @param #string PlayerName The name of the player.
|
-- @param #string PlayerName The name of the player.
|
||||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||||
@@ -581,7 +557,6 @@ do -- TASK_A2A_SWEEP
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- TASK_A2A_ENGAGE
|
do -- TASK_A2A_ENGAGE
|
||||||
|
|
||||||
--- The TASK_A2A_ENGAGE class
|
--- The TASK_A2A_ENGAGE class
|
||||||
@@ -600,11 +575,9 @@ do -- TASK_A2A_ENGAGE
|
|||||||
--
|
--
|
||||||
-- @field #TASK_A2A_ENGAGE
|
-- @field #TASK_A2A_ENGAGE
|
||||||
TASK_A2A_ENGAGE = {
|
TASK_A2A_ENGAGE = {
|
||||||
ClassName = "TASK_A2A_ENGAGE",
|
ClassName = "TASK_A2A_ENGAGE"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2A_ENGAGE.
|
--- Instantiates a new TASK_A2A_ENGAGE.
|
||||||
-- @param #TASK_A2A_ENGAGE self
|
-- @param #TASK_A2A_ENGAGE self
|
||||||
-- @param Tasking.Mission#MISSION Mission
|
-- @param Tasking.Mission#MISSION Mission
|
||||||
@@ -619,10 +592,7 @@ do -- TASK_A2A_ENGAGE
|
|||||||
|
|
||||||
Mission:AddTask( self )
|
Mission:AddTask( self )
|
||||||
|
|
||||||
self:SetBriefing(
|
self:SetBriefing( TaskBriefing or "Bogeys are nearby! Players close by are ordered to ENGAGE the intruders!\n" )
|
||||||
TaskBriefing or
|
|
||||||
"Bogeys are nearby! Players close by are ordered to ENGAGE the intruders!\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
-- The above example creates a SET_GROUP instance, and stores this in the variable (object) **EWRSet**.
|
-- The above example creates a SET_GROUP instance, and stores this in the variable (object) **EWRSet**.
|
||||||
-- **EWRSet** is then being configured to filter all active groups with a group name starting with **EWR** to be included in the Set.
|
-- **EWRSet** is then being configured to filter all active groups with a group name starting with **EWR** to be included in the Set.
|
||||||
-- **EWRSet** is then being ordered to start the dynamic filtering. Note that any destroy or new spawn of a group with the above names will be removed or added to the Set.
|
-- **EWRSet** is then being ordered to start the dynamic filtering. Note that any destroy or new spawn of a group with the above names will be removed or added to the Set.
|
||||||
-- Then a new **EWRDetection** object is created from the class DETECTION_AREAS. A grouping radius of 6000 is choosen, which is 6km.
|
-- Then a new **EWRDetection** object is created from the class DETECTION_AREAS. A grouping radius of 6000 is chosen, which is 6 km.
|
||||||
-- The **EWRDetection** object is then passed to the @{#TASK_A2A_DISPATCHER.New}() method to indicate the EWR network configuration and setup the A2A tasking and detection mechanism.
|
-- The **EWRDetection** object is then passed to the @{#TASK_A2A_DISPATCHER.New}() method to indicate the EWR network configuration and setup the A2A tasking and detection mechanism.
|
||||||
--
|
--
|
||||||
-- ### 2. Define the detected **target grouping radius**:
|
-- ### 2. Define the detected **target grouping radius**:
|
||||||
@@ -185,7 +185,6 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
SweepZones = {},
|
SweepZones = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--- TASK_A2A_DISPATCHER constructor.
|
--- TASK_A2A_DISPATCHER constructor.
|
||||||
-- @param #TASK_A2A_DISPATCHER self
|
-- @param #TASK_A2A_DISPATCHER self
|
||||||
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
|
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
|
||||||
@@ -208,7 +207,6 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
|
|
||||||
self:AddTransition( "Started", "Assign", "Started" )
|
self:AddTransition( "Started", "Assign", "Started" )
|
||||||
|
|
||||||
|
|
||||||
--- OnAfter Transition Handler for Event Assign.
|
--- OnAfter Transition Handler for Event Assign.
|
||||||
-- @function [parent=#TASK_A2A_DISPATCHER] OnAfterAssign
|
-- @function [parent=#TASK_A2A_DISPATCHER] OnAfterAssign
|
||||||
-- @param #TASK_A2A_DISPATCHER self
|
-- @param #TASK_A2A_DISPATCHER self
|
||||||
@@ -224,7 +222,6 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Define the radius to when an ENGAGE task will be generated for any nearby by airborne friendlies, which are executing cap or returning from an intercept mission.
|
--- Define the radius to when an ENGAGE task will be generated for any nearby by airborne friendlies, which are executing cap or returning from an intercept mission.
|
||||||
-- So, if there is a target area detected and reported,
|
-- So, if there is a target area detected and reported,
|
||||||
-- then any friendlies that are airborne near this target area,
|
-- then any friendlies that are airborne near this target area,
|
||||||
@@ -286,7 +283,6 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Creates an SWEEP task when there are targets for it.
|
--- Creates an SWEEP task when there are targets for it.
|
||||||
-- @param #TASK_A2A_DISPATCHER self
|
-- @param #TASK_A2A_DISPATCHER self
|
||||||
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
||||||
@@ -296,8 +292,7 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
self:F( { DetectedItem.ItemID } )
|
self:F( { DetectedItem.ItemID } )
|
||||||
|
|
||||||
local DetectedSet = DetectedItem.Set
|
local DetectedSet = DetectedItem.Set
|
||||||
local DetectedZone = DetectedItem.Zone
|
local DetectedZone = DetectedItem.Zone -- TODO: This seems unused, remove?
|
||||||
|
|
||||||
|
|
||||||
if DetectedItem.IsDetected == false then
|
if DetectedItem.IsDetected == false then
|
||||||
|
|
||||||
@@ -312,7 +307,6 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Creates an ENGAGE task when there are human friendlies airborne near the targets.
|
--- Creates an ENGAGE task when there are human friendlies airborne near the targets.
|
||||||
-- @param #TASK_A2A_DISPATCHER self
|
-- @param #TASK_A2A_DISPATCHER self
|
||||||
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
||||||
@@ -322,11 +316,10 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
self:F( { DetectedItem.ItemID } )
|
self:F( { DetectedItem.ItemID } )
|
||||||
|
|
||||||
local DetectedSet = DetectedItem.Set
|
local DetectedSet = DetectedItem.Set
|
||||||
local DetectedZone = DetectedItem.Zone
|
local DetectedZone = DetectedItem.Zone -- TODO: This seems unused, remove?
|
||||||
|
|
||||||
local PlayersCount, PlayersReport = self:GetPlayerFriendliesNearBy( DetectedItem )
|
local PlayersCount, PlayersReport = self:GetPlayerFriendliesNearBy( DetectedItem )
|
||||||
|
|
||||||
|
|
||||||
-- Only allow ENGAGE when there are Players near the zone, and when the Area has detected items since the last run in a 60 seconds time zone.
|
-- Only allow ENGAGE when there are Players near the zone, and when the Area has detected items since the last run in a 60 seconds time zone.
|
||||||
if PlayersCount > 0 and DetectedItem.IsDetected == true then
|
if PlayersCount > 0 and DetectedItem.IsDetected == true then
|
||||||
|
|
||||||
@@ -341,9 +334,6 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Evaluates the removal of the Task from the Mission.
|
--- Evaluates the removal of the Task from the Mission.
|
||||||
-- Can only occur when the DetectedItem is Changed AND the state of the Task is "Planned".
|
-- Can only occur when the DetectedItem is Changed AND the state of the Task is "Planned".
|
||||||
-- @param #TASK_A2A_DISPATCHER self
|
-- @param #TASK_A2A_DISPATCHER self
|
||||||
@@ -388,8 +378,8 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
end
|
end
|
||||||
|
|
||||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||||
--DetectedSet:Flush( self )
|
-- DetectedSet:Flush( self )
|
||||||
--self:F( { DetectedSetCount = DetectedSet:Count() } )
|
-- self:F( { DetectedSetCount = DetectedSet:Count() } )
|
||||||
if DetectedSet:Count() == 0 then
|
if DetectedSet:Count() == 0 then
|
||||||
Remove = true
|
Remove = true
|
||||||
end
|
end
|
||||||
@@ -423,7 +413,7 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
local FriendlyUnitThreatLevel = FriendlyUnit:GetThreatLevel()
|
local FriendlyUnitThreatLevel = FriendlyUnit:GetThreatLevel()
|
||||||
FriendliesCount = FriendliesCount + 1
|
FriendliesCount = FriendliesCount + 1
|
||||||
local FriendlyType = FriendlyUnit:GetTypeName()
|
local FriendlyType = FriendlyUnit:GetTypeName()
|
||||||
FriendlyTypes[FriendlyType] = FriendlyTypes[FriendlyType] and ( FriendlyTypes[FriendlyType] + 1 ) or 1
|
FriendlyTypes[FriendlyType] = FriendlyTypes[FriendlyType] and (FriendlyTypes[FriendlyType] + 1) or 1
|
||||||
if DetectedTreatLevel < FriendlyUnitThreatLevel + 2 then
|
if DetectedTreatLevel < FriendlyUnitThreatLevel + 2 then
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -431,19 +421,18 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--self:F( { FriendliesCount = FriendliesCount } )
|
-- self:F( { FriendliesCount = FriendliesCount } )
|
||||||
|
|
||||||
local FriendlyTypesReport = REPORT:New()
|
local FriendlyTypesReport = REPORT:New()
|
||||||
|
|
||||||
if FriendliesCount > 0 then
|
if FriendliesCount > 0 then
|
||||||
for FriendlyType, FriendlyTypeCount in pairs( FriendlyTypes ) do
|
for FriendlyType, FriendlyTypeCount in pairs( FriendlyTypes ) do
|
||||||
FriendlyTypesReport:Add( string.format("%d of %s", FriendlyTypeCount, FriendlyType ) )
|
FriendlyTypesReport:Add( string.format( "%d of %s", FriendlyTypeCount, FriendlyType ) )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
FriendlyTypesReport:Add( "-" )
|
FriendlyTypesReport:Add( "-" )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return FriendliesCount, FriendlyTypesReport
|
return FriendliesCount, FriendlyTypesReport
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -464,7 +453,7 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
for PlayerUnitName, PlayerUnitData in pairs( PlayersNearBy ) do
|
for PlayerUnitName, PlayerUnitData in pairs( PlayersNearBy ) do
|
||||||
local PlayerUnit = PlayerUnitData -- Wrapper.Unit#UNIT
|
local PlayerUnit = PlayerUnitData -- Wrapper.Unit#UNIT
|
||||||
local PlayerName = PlayerUnit:GetPlayerName()
|
local PlayerName = PlayerUnit:GetPlayerName()
|
||||||
--self:F( { PlayerName = PlayerName, PlayerUnit = PlayerUnit } )
|
-- self:F( { PlayerName = PlayerName, PlayerUnit = PlayerUnit } )
|
||||||
if PlayerUnit:IsAirPlane() and PlayerName ~= nil then
|
if PlayerUnit:IsAirPlane() and PlayerName ~= nil then
|
||||||
local FriendlyUnitThreatLevel = PlayerUnit:GetThreatLevel()
|
local FriendlyUnitThreatLevel = PlayerUnit:GetThreatLevel()
|
||||||
PlayersCount = PlayersCount + 1
|
PlayersCount = PlayersCount + 1
|
||||||
@@ -481,13 +470,12 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
|
|
||||||
if PlayersCount > 0 then
|
if PlayersCount > 0 then
|
||||||
for PlayerName, PlayerType in pairs( PlayerTypes ) do
|
for PlayerName, PlayerType in pairs( PlayerTypes ) do
|
||||||
PlayerTypesReport:Add( string.format('"%s" in %s', PlayerName, PlayerType ) )
|
PlayerTypesReport:Add( string.format( '"%s" in %s', PlayerName, PlayerType ) )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
PlayerTypesReport:Add( "-" )
|
PlayerTypesReport:Add( "-" )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
return PlayersCount, PlayerTypesReport
|
return PlayersCount, PlayerTypesReport
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -496,7 +484,6 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
self.Tasks[TaskIndex] = nil
|
self.Tasks[TaskIndex] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}.
|
--- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}.
|
||||||
-- @param #TASK_A2A_DISPATCHER self
|
-- @param #TASK_A2A_DISPATCHER self
|
||||||
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object.
|
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object.
|
||||||
@@ -536,8 +523,8 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||||
local DetectedCount = DetectedSet:Count()
|
local DetectedCount = DetectedSet:Count()
|
||||||
local DetectedZone = DetectedItem.Zone
|
local DetectedZone = DetectedItem.Zone
|
||||||
--self:F( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
|
-- self:F( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
|
||||||
--DetectedSet:Flush( self )
|
-- DetectedSet:Flush( self )
|
||||||
|
|
||||||
local DetectedID = DetectedItem.ID
|
local DetectedID = DetectedItem.ID
|
||||||
local TaskIndex = DetectedItem.Index
|
local TaskIndex = DetectedItem.Index
|
||||||
@@ -593,7 +580,7 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
|
|
||||||
TaskReport:Add( Task:GetName() )
|
TaskReport:Add( Task:GetName() )
|
||||||
else
|
else
|
||||||
self:F("This should not happen")
|
self:F( "This should not happen" )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -612,10 +599,10 @@ do -- TASK_A2A_DISPATCHER
|
|||||||
-- TODO set menus using the HQ coordinator
|
-- TODO set menus using the HQ coordinator
|
||||||
Mission:GetCommandCenter():SetMenu()
|
Mission:GetCommandCenter():SetMenu()
|
||||||
|
|
||||||
local TaskText = TaskReport:Text(", ")
|
local TaskText = TaskReport:Text( ", " )
|
||||||
|
|
||||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||||
if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" and (self.FlashNewTask) then
|
if (not Mission:IsGroupAssigned( TaskGroup )) and TaskText ~= "" and (self.FlashNewTask) then
|
||||||
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup )
|
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ do -- TASK_A2G
|
|||||||
--
|
--
|
||||||
-- @field #TASK_A2G
|
-- @field #TASK_A2G
|
||||||
TASK_A2G = {
|
TASK_A2G = {
|
||||||
ClassName = "TASK_A2G",
|
ClassName = "TASK_A2G"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2G.
|
--- Instantiates a new TASK_A2G.
|
||||||
@@ -61,27 +61,25 @@ do -- TASK_A2G
|
|||||||
local Fsm = self:GetUnitProcess()
|
local Fsm = self:GetUnitProcess()
|
||||||
|
|
||||||
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
||||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
Fsm:AddProcess( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||||
|
|
||||||
Fsm:AddTransition( { "Arrived", "RoutingToRendezVous" }, "ArriveAtRendezVous", "ArrivedAtRendezVous" )
|
Fsm:AddTransition( { "Arrived", "RoutingToRendezVous" }, "ArriveAtRendezVous", "ArrivedAtRendezVous" )
|
||||||
|
|
||||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "Engage", "Engaging" )
|
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "Engage", "Engaging" )
|
||||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "HoldAtRendezVous", "HoldingAtRendezVous" )
|
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "HoldAtRendezVous", "HoldingAtRendezVous" )
|
||||||
|
|
||||||
Fsm:AddProcess ( "Engaging", "Account", ACT_ACCOUNT_DEADS:New(), {} )
|
Fsm:AddProcess( "Engaging", "Account", ACT_ACCOUNT_DEADS:New(), {} )
|
||||||
Fsm:AddTransition( "Engaging", "RouteToTarget", "Engaging" )
|
Fsm:AddTransition( "Engaging", "RouteToTarget", "Engaging" )
|
||||||
Fsm:AddProcess( "Engaging", "RouteToTargetZone", ACT_ROUTE_ZONE:New(), {} )
|
Fsm:AddProcess( "Engaging", "RouteToTargetZone", ACT_ROUTE_ZONE:New(), {} )
|
||||||
Fsm:AddProcess( "Engaging", "RouteToTargetPoint", ACT_ROUTE_POINT:New(), {} )
|
Fsm:AddProcess( "Engaging", "RouteToTargetPoint", ACT_ROUTE_POINT:New(), {} )
|
||||||
Fsm:AddTransition( "Engaging", "RouteToTargets", "Engaging" )
|
Fsm:AddTransition( "Engaging", "RouteToTargets", "Engaging" )
|
||||||
|
|
||||||
--Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
-- Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
||||||
--Fsm:AddTransition( "Accounted", "Success", "Success" )
|
-- Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Test
|
--- Test
|
||||||
-- @param #FSM_PROCESS self
|
-- @param #FSM_PROCESS self
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
@@ -130,7 +128,7 @@ do -- TASK_A2G
|
|||||||
function Fsm:onafterEngage( TaskUnit, Task )
|
function Fsm:onafterEngage( TaskUnit, Task )
|
||||||
self:F( { self } )
|
self:F( { self } )
|
||||||
self:__Account( 0.1 )
|
self:__Account( 0.1 )
|
||||||
self:__RouteToTarget(0.1 )
|
self:__RouteToTarget( 0.1 )
|
||||||
self:__RouteToTargets( -10 )
|
self:__RouteToTargets( -10 )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -179,8 +177,6 @@ do -- TASK_A2G
|
|||||||
self.TargetSetUnit = TargetSetUnit
|
self.TargetSetUnit = TargetSetUnit
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2G self
|
--- @param #TASK_A2G self
|
||||||
function TASK_A2G:GetPlannedMenuText()
|
function TASK_A2G:GetPlannedMenuText()
|
||||||
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
||||||
@@ -211,8 +207,6 @@ do -- TASK_A2G
|
|||||||
return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange()
|
return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2G self
|
--- @param #TASK_A2G self
|
||||||
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
|
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
@@ -246,7 +240,6 @@ do -- TASK_A2G
|
|||||||
ActRouteTarget:SetCoordinate( TargetCoordinate )
|
ActRouteTarget:SetCoordinate( TargetCoordinate )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2G self
|
--- @param #TASK_A2G self
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
-- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map.
|
-- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map.
|
||||||
@@ -258,7 +251,6 @@ do -- TASK_A2G
|
|||||||
return ActRouteTarget:GetCoordinate()
|
return ActRouteTarget:GetCoordinate()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2G self
|
--- @param #TASK_A2G self
|
||||||
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
|
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
@@ -270,7 +262,6 @@ do -- TASK_A2G
|
|||||||
ActRouteTarget:SetZone( TargetZone )
|
ActRouteTarget:SetZone( TargetZone )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- @param #TASK_A2G self
|
--- @param #TASK_A2G self
|
||||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||||
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
|
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
|
||||||
@@ -303,7 +294,6 @@ do -- TASK_A2G
|
|||||||
return Distance
|
return Distance
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- This method checks every 10 seconds if the goal has been reached of the task.
|
--- This method checks every 10 seconds if the goal has been reached of the task.
|
||||||
-- @param #TASK_A2G self
|
-- @param #TASK_A2G self
|
||||||
function TASK_A2G:onafterGoal( TaskUnit, From, Event, To )
|
function TASK_A2G:onafterGoal( TaskUnit, From, Event, To )
|
||||||
@@ -370,7 +360,7 @@ do -- TASK_A2G
|
|||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Distance then
|
||||||
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
|
local Coordinate = self.TaskInfo:GetData( "Coordinate" )
|
||||||
local Distance = Coordinate:Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
local Distance = Coordinate:Get2DDistance( CommandCenter:GetPositionable():GetCoordinate() )
|
||||||
self:F({Distance=Distance})
|
self:F( { Distance = Distance } )
|
||||||
return math.floor( Distance )
|
return math.floor( Distance )
|
||||||
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
elseif AutoAssignMethod == COMMANDCENTER.AutoAssignMethods.Priority then
|
||||||
return 1
|
return 1
|
||||||
@@ -381,7 +371,6 @@ do -- TASK_A2G
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
do -- TASK_A2G_SEAD
|
do -- TASK_A2G_SEAD
|
||||||
|
|
||||||
--- The TASK_A2G_SEAD class
|
--- The TASK_A2G_SEAD class
|
||||||
@@ -397,7 +386,7 @@ do -- TASK_A2G_SEAD
|
|||||||
--
|
--
|
||||||
-- @field #TASK_A2G_SEAD
|
-- @field #TASK_A2G_SEAD
|
||||||
TASK_A2G_SEAD = {
|
TASK_A2G_SEAD = {
|
||||||
ClassName = "TASK_A2G_SEAD",
|
ClassName = "TASK_A2G_SEAD"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2G_SEAD.
|
--- Instantiates a new TASK_A2G_SEAD.
|
||||||
@@ -408,16 +397,13 @@ do -- TASK_A2G_SEAD
|
|||||||
-- @param Core.Set#SET_UNIT TargetSetUnit
|
-- @param Core.Set#SET_UNIT TargetSetUnit
|
||||||
-- @param #string TaskBriefing The briefing of the task.
|
-- @param #string TaskBriefing The briefing of the task.
|
||||||
-- @return #TASK_A2G_SEAD self
|
-- @return #TASK_A2G_SEAD self
|
||||||
function TASK_A2G_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing)
|
function TASK_A2G_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||||
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD", TaskBriefing ) ) -- #TASK_A2G_SEAD
|
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD", TaskBriefing ) ) -- #TASK_A2G_SEAD
|
||||||
self:F()
|
self:F()
|
||||||
|
|
||||||
Mission:AddTask( self )
|
Mission:AddTask( self )
|
||||||
|
|
||||||
self:SetBriefing(
|
self:SetBriefing( TaskBriefing or "Execute a Suppression of Enemy Air Defenses." )
|
||||||
TaskBriefing or
|
|
||||||
"Execute a Suppression of Enemy Air Defenses."
|
|
||||||
)
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -470,7 +456,6 @@ do -- TASK_A2G_SEAD
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do -- TASK_A2G_BAI
|
do -- TASK_A2G_BAI
|
||||||
@@ -488,9 +473,7 @@ do -- TASK_A2G_BAI
|
|||||||
-- based on detected enemy ground targets.
|
-- based on detected enemy ground targets.
|
||||||
--
|
--
|
||||||
-- @field #TASK_A2G_BAI
|
-- @field #TASK_A2G_BAI
|
||||||
TASK_A2G_BAI = {
|
TASK_A2G_BAI = { ClassName = "TASK_A2G_BAI" }
|
||||||
ClassName = "TASK_A2G_BAI",
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2G_BAI.
|
--- Instantiates a new TASK_A2G_BAI.
|
||||||
-- @param #TASK_A2G_BAI self
|
-- @param #TASK_A2G_BAI self
|
||||||
@@ -506,10 +489,7 @@ do -- TASK_A2G_BAI
|
|||||||
|
|
||||||
Mission:AddTask( self )
|
Mission:AddTask( self )
|
||||||
|
|
||||||
self:SetBriefing(
|
self:SetBriefing( TaskBriefing or "Execute a Battlefield Air Interdiction of a group of enemy targets." )
|
||||||
TaskBriefing or
|
|
||||||
"Execute a Battlefield Air Interdiction of a group of enemy targets."
|
|
||||||
)
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -564,9 +544,6 @@ do -- TASK_A2G_BAI
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
do -- TASK_A2G_CAS
|
do -- TASK_A2G_CAS
|
||||||
|
|
||||||
--- The TASK_A2G_CAS class
|
--- The TASK_A2G_CAS class
|
||||||
@@ -581,9 +558,7 @@ do -- TASK_A2G_CAS
|
|||||||
-- based on detected enemy ground targets.
|
-- based on detected enemy ground targets.
|
||||||
--
|
--
|
||||||
-- @field #TASK_A2G_CAS
|
-- @field #TASK_A2G_CAS
|
||||||
TASK_A2G_CAS = {
|
TASK_A2G_CAS = { ClassName = "TASK_A2G_CAS" }
|
||||||
ClassName = "TASK_A2G_CAS",
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Instantiates a new TASK_A2G_CAS.
|
--- Instantiates a new TASK_A2G_CAS.
|
||||||
-- @param #TASK_A2G_CAS self
|
-- @param #TASK_A2G_CAS self
|
||||||
@@ -599,17 +574,11 @@ do -- TASK_A2G_CAS
|
|||||||
|
|
||||||
Mission:AddTask( self )
|
Mission:AddTask( self )
|
||||||
|
|
||||||
self:SetBriefing(
|
self:SetBriefing( TaskBriefing or ( "Execute a Close Air Support for a group of enemy targets. " .. "Beware of friendlies at the vicinity! " ) )
|
||||||
TaskBriefing or
|
|
||||||
"Execute a Close Air Support for a group of enemy targets. " ..
|
|
||||||
"Beware of friendlies at the vicinity! "
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Set a score when a target in scope of the A2G attack, has been destroyed .
|
--- Set a score when a target in scope of the A2G attack, has been destroyed .
|
||||||
-- @param #TASK_A2G_CAS self
|
-- @param #TASK_A2G_CAS self
|
||||||
-- @param #string PlayerName The name of the player.
|
-- @param #string PlayerName The name of the player.
|
||||||
@@ -658,5 +627,4 @@ do -- TASK_A2G_CAS
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,11 +6,12 @@
|
|||||||
-- * Dynamically change the tasks as the tactical situation evolves during the mission.
|
-- * Dynamically change the tasks as the tactical situation evolves during the mission.
|
||||||
-- * Dynamically assign (CAS) Close Air Support tasks for human players.
|
-- * Dynamically assign (CAS) Close Air Support tasks for human players.
|
||||||
-- * Dynamically assign (BAI) Battlefield Air Interdiction tasks for human players.
|
-- * Dynamically assign (BAI) Battlefield Air Interdiction tasks for human players.
|
||||||
-- * Dynamically assign (SEAD) Supression of Enemy Air Defense tasks for human players to eliminate G2A missile threats.
|
-- * Dynamically assign (SEAD) Suppression of Enemy Air Defense tasks for human players to eliminate G2A missile threats.
|
||||||
-- * Define and use an EWR (Early Warning Radar) network.
|
-- * Define and use an EWR (Early Warning Radar) network.
|
||||||
-- * Define different ranges to engage upon intruders.
|
-- * Define different ranges to engage upon intruders.
|
||||||
-- * Keep task achievements.
|
-- * Keep task achievements.
|
||||||
-- * Score task achievements.--
|
-- * Score task achievements.
|
||||||
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **FlightControl**
|
-- ### Author: **FlightControl**
|
||||||
@@ -122,7 +123,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
-- F1. Command Center [Lima]
|
-- F1. Command Center [Lima]
|
||||||
-- F1. Mission "Overlord (High)"
|
-- F1. Mission "Overlord (High)"
|
||||||
--
|
--
|
||||||
-- Command Center [Gori] is controlling Mission "Alpha", "Beta", "Gamma". Alpha is the Primary mission, Beta the Secondary and there is a Tacical mission Gamma.
|
-- Command Center [Gori] is controlling Mission "Alpha", "Beta", "Gamma". Alpha is the Primary mission, Beta the Secondary and there is a Tactical mission Gamma.
|
||||||
-- Command Center [Lima] is controlling Missions "Overlord", which needs to be executed with High priority.
|
-- Command Center [Lima] is controlling Missions "Overlord", which needs to be executed with High priority.
|
||||||
--
|
--
|
||||||
-- ## 1.1. Mission Menu (Under the Command Center Menu)
|
-- ## 1.1. Mission Menu (Under the Command Center Menu)
|
||||||
@@ -196,7 +197,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
--
|
--
|
||||||
-- The Mission Reports Menu is a sub menu, that provides options to retrieve further information on the current Mission:
|
-- The Mission Reports Menu is a sub menu, that provides options to retrieve further information on the current Mission:
|
||||||
--
|
--
|
||||||
-- - **Report Mission Progress**: Shows the progress of the current Mission. Each Task has a %-tage of completion.
|
-- - **Report Mission Progress**: Shows the progress of the current Mission. Each Task has a % of completion.
|
||||||
-- - **Report Players per Task**: Show which players are engaged on which Task within the Mission.
|
-- - **Report Players per Task**: Show which players are engaged on which Task within the Mission.
|
||||||
--
|
--
|
||||||
-- For CC |Gori|, Mission "Alpha", the Mission Reports menu structure could look like this:
|
-- For CC |Gori|, Mission "Alpha", the Mission Reports menu structure could look like this:
|
||||||
@@ -264,7 +265,6 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
--
|
--
|
||||||
-- **The F5. Assigned Task __TaskName__ allows the player to control the current Assigned Task and take further actions.**
|
-- **The F5. Assigned Task __TaskName__ allows the player to control the current Assigned Task and take further actions.**
|
||||||
--
|
--
|
||||||
--
|
|
||||||
-- ## 1.3. Join Planned Task Menu
|
-- ## 1.3. Join Planned Task Menu
|
||||||
--
|
--
|
||||||
-- The Join Planned Task Menu contains the different Planned A2G Tasks **in a structured Menu Hierarchy**.
|
-- The Join Planned Task Menu contains the different Planned A2G Tasks **in a structured Menu Hierarchy**.
|
||||||
@@ -388,7 +388,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
-- - A @{Mission} object. Each task belongs to a Mission.
|
-- - A @{Mission} object. Each task belongs to a Mission.
|
||||||
-- - A @{Detection} object. There are several detection grouping methods to choose from.
|
-- - A @{Detection} object. There are several detection grouping methods to choose from.
|
||||||
-- - A @{Task_A2G_Dispatcher} object. The master A2G task dispatcher.
|
-- - A @{Task_A2G_Dispatcher} object. The master A2G task dispatcher.
|
||||||
-- - A @{Set} of @{Wrapper.Group} objects that will detect the emeny, the RecceSet. This is attached to the @{Detection} object.
|
-- - A @{Set} of @{Wrapper.Group} objects that will detect the enemy, the RecceSet. This is attached to the @{Detection} object.
|
||||||
-- - A @{Set} ob @{Wrapper.Group} objects that will attack the enemy, the AttackSet. This is attached to the @{Task_A2G_Dispatcher} object.
|
-- - A @{Set} ob @{Wrapper.Group} objects that will attack the enemy, the AttackSet. This is attached to the @{Task_A2G_Dispatcher} object.
|
||||||
--
|
--
|
||||||
-- Below an example mission declaration that is defines a Task A2G Dispatcher object.
|
-- Below an example mission declaration that is defines a Task A2G Dispatcher object.
|
||||||
@@ -425,7 +425,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
--
|
--
|
||||||
-- -- Now we have everything to setup the main A2G TaskDispatcher.
|
-- -- Now we have everything to setup the main A2G TaskDispatcher.
|
||||||
-- TaskDispatcher = TASK_A2G_DISPATCHER
|
-- TaskDispatcher = TASK_A2G_DISPATCHER
|
||||||
-- :New( Mission, AttackSet, DetectionAreas ) -- We assign the TaskDispatcher under Mission. The AttackSet will engage the enemy and will recieve the dispatched Tasks. The DetectionAreas will report any detected enemies to the TaskDispatcher.
|
-- :New( Mission, AttackSet, DetectionAreas ) -- We assign the TaskDispatcher under Mission. The AttackSet will engage the enemy and will receive the dispatched Tasks. The DetectionAreas will report any detected enemies to the TaskDispatcher.
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
@@ -434,10 +434,9 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
ClassName = "TASK_A2G_DISPATCHER",
|
ClassName = "TASK_A2G_DISPATCHER",
|
||||||
Mission = nil,
|
Mission = nil,
|
||||||
Detection = nil,
|
Detection = nil,
|
||||||
Tasks = {},
|
Tasks = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
--- TASK_A2G_DISPATCHER constructor.
|
--- TASK_A2G_DISPATCHER constructor.
|
||||||
-- @param #TASK_A2G_DISPATCHER self
|
-- @param #TASK_A2G_DISPATCHER self
|
||||||
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
|
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
|
||||||
@@ -451,7 +450,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
|
|
||||||
self.Detection = Detection
|
self.Detection = Detection
|
||||||
self.Mission = Mission
|
self.Mission = Mission
|
||||||
self.FlashNewTask = true --set to false to suppress flash messages
|
self.FlashNewTask = true -- set to false to suppress flash messages
|
||||||
|
|
||||||
self.Detection:FilterCategories( { Unit.Category.GROUND_UNIT } )
|
self.Detection:FilterCategories( { Unit.Category.GROUND_UNIT } )
|
||||||
|
|
||||||
@@ -518,7 +517,6 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
local DetectedSet = DetectedItem.Set
|
local DetectedSet = DetectedItem.Set
|
||||||
local DetectedZone = DetectedItem.Zone
|
local DetectedZone = DetectedItem.Zone
|
||||||
|
|
||||||
|
|
||||||
-- Determine if the set has ground units.
|
-- Determine if the set has ground units.
|
||||||
-- There should be ground unit friendlies nearby. Airborne units are valid friendlies types.
|
-- There should be ground unit friendlies nearby. Airborne units are valid friendlies types.
|
||||||
-- And there shouldn't be any radar.
|
-- And there shouldn't be any radar.
|
||||||
@@ -550,7 +548,6 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
local DetectedSet = DetectedItem.Set
|
local DetectedSet = DetectedItem.Set
|
||||||
local DetectedZone = DetectedItem.Zone
|
local DetectedZone = DetectedItem.Zone
|
||||||
|
|
||||||
|
|
||||||
-- Determine if the set has ground units.
|
-- Determine if the set has ground units.
|
||||||
-- There shouldn't be any ground unit friendlies nearby.
|
-- There shouldn't be any ground unit friendlies nearby.
|
||||||
-- And there shouldn't be any radar.
|
-- And there shouldn't be any radar.
|
||||||
@@ -571,7 +568,6 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function TASK_A2G_DISPATCHER:RemoveTask( TaskIndex )
|
function TASK_A2G_DISPATCHER:RemoveTask( TaskIndex )
|
||||||
self.Mission:RemoveTask( self.Tasks[TaskIndex] )
|
self.Mission:RemoveTask( self.Tasks[TaskIndex] )
|
||||||
self.Tasks[TaskIndex] = nil
|
self.Tasks[TaskIndex] = nil
|
||||||
@@ -588,8 +584,8 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
function TASK_A2G_DISPATCHER:EvaluateRemoveTask( Mission, Task, TaskIndex, DetectedItemChanged )
|
function TASK_A2G_DISPATCHER:EvaluateRemoveTask( Mission, Task, TaskIndex, DetectedItemChanged )
|
||||||
|
|
||||||
if Task then
|
if Task then
|
||||||
if ( Task:IsStatePlanned() and DetectedItemChanged == true ) or Task:IsStateCancelled() then
|
if (Task:IsStatePlanned() and DetectedItemChanged == true) or Task:IsStateCancelled() then
|
||||||
--self:F( "Removing Tasking: " .. Task:GetTaskName() )
|
-- self:F( "Removing Tasking: " .. Task:GetTaskName() )
|
||||||
self:RemoveTask( TaskIndex )
|
self:RemoveTask( TaskIndex )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -597,7 +593,6 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
return Task
|
return Task
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}.
|
--- Assigns tasks in relation to the detected items to the @{Core.Set#SET_GROUP}.
|
||||||
-- @param #TASK_A2G_DISPATCHER self
|
-- @param #TASK_A2G_DISPATCHER self
|
||||||
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object.
|
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Functional.Detection#DETECTION_BASE} derived object.
|
||||||
@@ -638,8 +633,8 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||||
local DetectedZone = DetectedItem.Zone
|
local DetectedZone = DetectedItem.Zone
|
||||||
--self:F( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
|
-- self:F( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
|
||||||
--DetectedSet:Flush( self )
|
-- DetectedSet:Flush( self )
|
||||||
|
|
||||||
local DetectedItemID = DetectedItem.ID
|
local DetectedItemID = DetectedItem.ID
|
||||||
local TaskIndex = DetectedItem.Index
|
local TaskIndex = DetectedItem.Index
|
||||||
@@ -694,8 +689,8 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
|
|
||||||
-- Now we send to each group the changes, if any.
|
-- Now we send to each group the changes, if any.
|
||||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||||
local TargetsText = TargetsReport:Text(", ")
|
local TargetsText = TargetsReport:Text( ", " )
|
||||||
if ( Mission:IsGroupAssigned(TaskGroup) ) and TargetsText ~= "" and self.FlashNewTask then
|
if (Mission:IsGroupAssigned( TaskGroup )) and TargetsText ~= "" and self.FlashNewTask then
|
||||||
Mission:GetCommandCenter():MessageToGroup( string.format( "Task %s has change of targets:\n %s", Task:GetName(), TargetsText ), TaskGroup )
|
Mission:GetCommandCenter():MessageToGroup( string.format( "Task %s has change of targets:\n %s", Task:GetName(), TargetsText ), TaskGroup )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -753,7 +748,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
|
local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
|
||||||
if TargetSetUnit then
|
if TargetSetUnit then
|
||||||
Task = TASK_A2G_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", DetectedItemID ), TargetSetUnit )
|
Task = TASK_A2G_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", DetectedItemID ), TargetSetUnit )
|
||||||
DetectedItem.DesignateMenuName = string.format( "SEAD.%03d", DetectedItemID ) --inject a name for DESIGNATE, if using same DETECTION object
|
DetectedItem.DesignateMenuName = string.format( "SEAD.%03d", DetectedItemID ) -- inject a name for DESIGNATE, if using same DETECTION object
|
||||||
Task:SetDetection( Detection, DetectedItem )
|
Task:SetDetection( Detection, DetectedItem )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -762,7 +757,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be CASed...
|
local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be CASed...
|
||||||
if TargetSetUnit then
|
if TargetSetUnit then
|
||||||
Task = TASK_A2G_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", DetectedItemID ), TargetSetUnit )
|
Task = TASK_A2G_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", DetectedItemID ), TargetSetUnit )
|
||||||
DetectedItem.DesignateMenuName = string.format( "CAS.%03d", DetectedItemID ) --inject a name for DESIGNATE, if using same DETECTION object
|
DetectedItem.DesignateMenuName = string.format( "CAS.%03d", DetectedItemID ) -- inject a name for DESIGNATE, if using same DETECTION object
|
||||||
Task:SetDetection( Detection, DetectedItem )
|
Task:SetDetection( Detection, DetectedItem )
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -771,7 +766,7 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
local TargetSetUnit = self:EvaluateBAI( DetectedItem, self.Mission:GetCommandCenter():GetPositionable():GetCoalition() ) -- Returns a SetUnit if there are targets to be BAIed...
|
local TargetSetUnit = self:EvaluateBAI( DetectedItem, self.Mission:GetCommandCenter():GetPositionable():GetCoalition() ) -- Returns a SetUnit if there are targets to be BAIed...
|
||||||
if TargetSetUnit then
|
if TargetSetUnit then
|
||||||
Task = TASK_A2G_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", DetectedItemID ), TargetSetUnit )
|
Task = TASK_A2G_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", DetectedItemID ), TargetSetUnit )
|
||||||
DetectedItem.DesignateMenuName = string.format( "BAI.%03d", DetectedItemID ) --inject a name for DESIGNATE, if using same DETECTION object
|
DetectedItem.DesignateMenuName = string.format( "BAI.%03d", DetectedItemID ) -- inject a name for DESIGNATE, if using same DETECTION object
|
||||||
Task:SetDetection( Detection, DetectedItem )
|
Task:SetDetection( Detection, DetectedItem )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -800,14 +795,12 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
self:Aborted( Task )
|
self:Aborted( Task )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
TaskReport:Add( Task:GetName() )
|
TaskReport:Add( Task:GetName() )
|
||||||
else
|
else
|
||||||
self:F("This should not happen")
|
self:F( "This should not happen" )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- OK, so the tasking has been done, now delete the changes reported for the area.
|
-- OK, so the tasking has been done, now delete the changes reported for the area.
|
||||||
Detection:AcceptChanges( DetectedItem )
|
Detection:AcceptChanges( DetectedItem )
|
||||||
end
|
end
|
||||||
@@ -815,9 +808,9 @@ do -- TASK_A2G_DISPATCHER
|
|||||||
-- TODO set menus using the HQ coordinator
|
-- TODO set menus using the HQ coordinator
|
||||||
Mission:GetCommandCenter():SetMenu()
|
Mission:GetCommandCenter():SetMenu()
|
||||||
|
|
||||||
local TaskText = TaskReport:Text(", ")
|
local TaskText = TaskReport:Text( ", " )
|
||||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||||
if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" and self.FlashNewTask then
|
if (not Mission:IsGroupAssigned( TaskGroup )) and TaskText ~= "" and self.FlashNewTask then
|
||||||
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup )
|
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetShortText(), TaskText ), TaskGroup )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
--
|
--
|
||||||
-- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit.
|
-- DCS itself provides a lot of enumerators for various things. See [Enumerators](https://wiki.hoggitworld.com/view/Category:Enumerators) on Hoggit.
|
||||||
--
|
--
|
||||||
-- Other Moose classe also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
|
-- Other Moose classes also have enumerators. For example, the AIRBASE class has enumerators for airbase names.
|
||||||
--
|
--
|
||||||
-- @module ENUMS
|
-- @module ENUMS
|
||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
@@ -30,16 +30,16 @@ ENUMS = {}
|
|||||||
-- @type ENUMS.ROE
|
-- @type ENUMS.ROE
|
||||||
-- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target.
|
-- @field #number WeaponFree AI will engage any enemy group it detects. Target prioritization is based based on the threat of the target.
|
||||||
-- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking.
|
-- @field #number OpenFireWeaponFree AI will engage any enemy group it detects, but will prioritize targets specified in the groups tasking.
|
||||||
-- @field #number OpenFire AI will engage only targets specified in its taskings.
|
-- @field #number OpenFire AI will engage only targets specified in its tasking.
|
||||||
-- @field #number ReturnFire AI will only engage threats that shoot first.
|
-- @field #number ReturnFire AI will only engage threats that shoot first.
|
||||||
-- @field #number WeaponHold AI will hold fire under all circumstances.
|
-- @field #number WeaponHold AI will hold fire under all circumstances.
|
||||||
ENUMS.ROE = {
|
ENUMS.ROE = {
|
||||||
WeaponFree=0,
|
WeaponFree = 0,
|
||||||
OpenFireWeaponFree=1,
|
OpenFireWeaponFree = 1,
|
||||||
OpenFire=2,
|
OpenFire = 2,
|
||||||
ReturnFire=3,
|
ReturnFire = 3,
|
||||||
WeaponHold=4,
|
WeaponHold = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Reaction On Threat.
|
--- Reaction On Threat.
|
||||||
-- @type ENUMS.ROT
|
-- @type ENUMS.ROT
|
||||||
@@ -49,11 +49,11 @@ ENUMS.ROE = {
|
|||||||
-- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats.
|
-- @field #number BypassAndEscape AI will attempt to avoid enemy threat zones all together. This includes attempting to fly above or around threats.
|
||||||
-- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base.
|
-- @field #number AllowAbortMission If a threat is deemed severe enough the AI will abort its mission and return to base.
|
||||||
ENUMS.ROT = {
|
ENUMS.ROT = {
|
||||||
NoReaction=0,
|
NoReaction = 0,
|
||||||
PassiveDefense=1,
|
PassiveDefense = 1,
|
||||||
EvadeFire=2,
|
EvadeFire = 2,
|
||||||
BypassAndEscape=3,
|
BypassAndEscape = 3,
|
||||||
AllowAbortMission=4,
|
AllowAbortMission = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Alarm state.
|
--- Alarm state.
|
||||||
@@ -62,12 +62,12 @@ ENUMS.ROT = {
|
|||||||
-- @field #number Green Group is not combat ready. Sensors are stowed if possible.
|
-- @field #number Green Group is not combat ready. Sensors are stowed if possible.
|
||||||
-- @field #number Red Group is combat ready and actively searching for targets. Some groups like infantry will not move in this state.
|
-- @field #number Red Group is combat ready and actively searching for targets. Some groups like infantry will not move in this state.
|
||||||
ENUMS.AlarmState = {
|
ENUMS.AlarmState = {
|
||||||
Auto=0,
|
Auto = 0,
|
||||||
Green=1,
|
Green = 1,
|
||||||
Red=2,
|
Red = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerotor on hoggit wiki.
|
--- Weapon types. See the [Weapon Flag](https://wiki.hoggitworld.com/view/DCS_enum_weapon_flag) enumerator on Hoggit wiki.
|
||||||
-- @type ENUMS.WeaponFlag
|
-- @type ENUMS.WeaponFlag
|
||||||
ENUMS.WeaponFlag={
|
ENUMS.WeaponFlag={
|
||||||
-- Bombs
|
-- Bombs
|
||||||
@@ -111,7 +111,7 @@ ENUMS.WeaponFlag={
|
|||||||
--
|
--
|
||||||
-- Bombs
|
-- Bombs
|
||||||
GuidedBomb = 14, -- (LGB + TvGB + SNSGB)
|
GuidedBomb = 14, -- (LGB + TvGB + SNSGB)
|
||||||
AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispencer + CandleBomb + ParachuteBomb)
|
AnyUnguidedBomb = 2147485680, -- (HeBomb + Penetrator + NapalmBomb + FAEBomb + ClusterBomb + Dispenser + CandleBomb + ParachuteBomb)
|
||||||
AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb)
|
AnyBomb = 2147485694, -- (GuidedBomb + AnyUnguidedBomb)
|
||||||
--- Rockets
|
--- Rockets
|
||||||
AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket
|
AnyRocket = 30720, -- LightRocket + MarkerRocket + CandleRocket + HeavyRocket
|
||||||
@@ -173,7 +173,7 @@ ENUMS.MissionTask={
|
|||||||
TRANSPORT="Transport",
|
TRANSPORT="Transport",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki.
|
--- Formations (new). See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
|
||||||
-- @type ENUMS.Formation
|
-- @type ENUMS.Formation
|
||||||
ENUMS.Formation={}
|
ENUMS.Formation={}
|
||||||
ENUMS.Formation.FixedWing={}
|
ENUMS.Formation.FixedWing={}
|
||||||
@@ -216,23 +216,23 @@ ENUMS.Formation.FixedWing.FighterVic.Close = 917505
|
|||||||
ENUMS.Formation.FixedWing.FighterVic.Open = 917506
|
ENUMS.Formation.FixedWing.FighterVic.Open = 917506
|
||||||
ENUMS.Formation.RotaryWing={}
|
ENUMS.Formation.RotaryWing={}
|
||||||
ENUMS.Formation.RotaryWing.Column={}
|
ENUMS.Formation.RotaryWing.Column={}
|
||||||
ENUMS.Formation.RotaryWing.Column.D70=720896
|
ENUMS.Formation.RotaryWing.Column.D70 = 720896
|
||||||
ENUMS.Formation.RotaryWing.Wedge={}
|
ENUMS.Formation.RotaryWing.Wedge={}
|
||||||
ENUMS.Formation.RotaryWing.Wedge.D70=8
|
ENUMS.Formation.RotaryWing.Wedge.D70 = 8
|
||||||
ENUMS.Formation.RotaryWing.FrontRight={}
|
ENUMS.Formation.RotaryWing.FrontRight={}
|
||||||
ENUMS.Formation.RotaryWing.FrontRight.D300=655361
|
ENUMS.Formation.RotaryWing.FrontRight.D300 = 655361
|
||||||
ENUMS.Formation.RotaryWing.FrontRight.D600=655362
|
ENUMS.Formation.RotaryWing.FrontRight.D600 = 655362
|
||||||
ENUMS.Formation.RotaryWing.FrontLeft={}
|
ENUMS.Formation.RotaryWing.FrontLeft={}
|
||||||
ENUMS.Formation.RotaryWing.FrontLeft.D300=655617
|
ENUMS.Formation.RotaryWing.FrontLeft.D300 = 655617
|
||||||
ENUMS.Formation.RotaryWing.FrontLeft.D600=655618
|
ENUMS.Formation.RotaryWing.FrontLeft.D600 = 655618
|
||||||
ENUMS.Formation.RotaryWing.EchelonRight={}
|
ENUMS.Formation.RotaryWing.EchelonRight={}
|
||||||
ENUMS.Formation.RotaryWing.EchelonRight.D70 =589825
|
ENUMS.Formation.RotaryWing.EchelonRight.D70 = 589825
|
||||||
ENUMS.Formation.RotaryWing.EchelonRight.D300=589826
|
ENUMS.Formation.RotaryWing.EchelonRight.D300 = 589826
|
||||||
ENUMS.Formation.RotaryWing.EchelonRight.D600=589827
|
ENUMS.Formation.RotaryWing.EchelonRight.D600 = 589827
|
||||||
ENUMS.Formation.RotaryWing.EchelonLeft={}
|
ENUMS.Formation.RotaryWing.EchelonLeft={}
|
||||||
ENUMS.Formation.RotaryWing.EchelonLeft.D70 =590081
|
ENUMS.Formation.RotaryWing.EchelonLeft.D70 = 590081
|
||||||
ENUMS.Formation.RotaryWing.EchelonLeft.D300=590082
|
ENUMS.Formation.RotaryWing.EchelonLeft.D300 = 590082
|
||||||
ENUMS.Formation.RotaryWing.EchelonLeft.D600=590083
|
ENUMS.Formation.RotaryWing.EchelonLeft.D600 = 590083
|
||||||
ENUMS.Formation.Vehicle={}
|
ENUMS.Formation.Vehicle={}
|
||||||
ENUMS.Formation.Vehicle.Vee="Vee"
|
ENUMS.Formation.Vehicle.Vee="Vee"
|
||||||
ENUMS.Formation.Vehicle.EchelonRight="EchelonR"
|
ENUMS.Formation.Vehicle.EchelonRight="EchelonR"
|
||||||
@@ -244,25 +244,25 @@ ENUMS.Formation.Vehicle.Cone="Cone"
|
|||||||
ENUMS.Formation.Vehicle.Diamond="Diamond"
|
ENUMS.Formation.Vehicle.Diamond="Diamond"
|
||||||
|
|
||||||
--- Formations (old). The old format is a simplified version of the new formation enums, which allow more sophisticated settings.
|
--- Formations (old). The old format is a simplified version of the new formation enums, which allow more sophisticated settings.
|
||||||
-- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on hoggit wiki.
|
-- See the [Formations](https://wiki.hoggitworld.com/view/DCS_enum_formation) on Hoggit wiki.
|
||||||
-- @type ENUMS.FormationOld
|
-- @type ENUMS.FormationOld
|
||||||
ENUMS.FormationOld={}
|
ENUMS.FormationOld={}
|
||||||
ENUMS.FormationOld.FixedWing={}
|
ENUMS.FormationOld.FixedWing={}
|
||||||
ENUMS.FormationOld.FixedWing.LineAbreast=1
|
ENUMS.FormationOld.FixedWing.LineAbreast = 1
|
||||||
ENUMS.FormationOld.FixedWing.Trail=2
|
ENUMS.FormationOld.FixedWing.Trail = 2
|
||||||
ENUMS.FormationOld.FixedWing.Wedge=3
|
ENUMS.FormationOld.FixedWing.Wedge = 3
|
||||||
ENUMS.FormationOld.FixedWing.EchelonRight=4
|
ENUMS.FormationOld.FixedWing.EchelonRight = 4
|
||||||
ENUMS.FormationOld.FixedWing.EchelonLeft=5
|
ENUMS.FormationOld.FixedWing.EchelonLeft = 5
|
||||||
ENUMS.FormationOld.FixedWing.FingerFour=6
|
ENUMS.FormationOld.FixedWing.FingerFour = 6
|
||||||
ENUMS.FormationOld.FixedWing.SpreadFour=7
|
ENUMS.FormationOld.FixedWing.SpreadFour = 7
|
||||||
ENUMS.FormationOld.FixedWing.BomberElement=12
|
ENUMS.FormationOld.FixedWing.BomberElement = 12
|
||||||
ENUMS.FormationOld.FixedWing.BomberElementHeight=13
|
ENUMS.FormationOld.FixedWing.BomberElementHeight = 13
|
||||||
ENUMS.FormationOld.FixedWing.FighterVic=14
|
ENUMS.FormationOld.FixedWing.FighterVic = 14
|
||||||
ENUMS.FormationOld.RotaryWing={}
|
ENUMS.FormationOld.RotaryWing={}
|
||||||
ENUMS.FormationOld.RotaryWing.Wedge=8
|
ENUMS.FormationOld.RotaryWing.Wedge = 8
|
||||||
ENUMS.FormationOld.RotaryWing.Echelon=9
|
ENUMS.FormationOld.RotaryWing.Echelon = 9
|
||||||
ENUMS.FormationOld.RotaryWing.Front=10
|
ENUMS.FormationOld.RotaryWing.Front = 10
|
||||||
ENUMS.FormationOld.RotaryWing.Column=11
|
ENUMS.FormationOld.RotaryWing.Column = 11
|
||||||
|
|
||||||
|
|
||||||
--- Morse Code. See the [Wikipedia](https://en.wikipedia.org/wiki/Morse_code).
|
--- Morse Code. See the [Wikipedia](https://en.wikipedia.org/wiki/Morse_code).
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
-- @module Utilities.PROFILER
|
-- @module Utilities.PROFILER
|
||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
|
|
||||||
--- PROFILER class.
|
--- PROFILER class.
|
||||||
-- @type PROFILER
|
-- @type PROFILER
|
||||||
-- @field #string ClassName Name of the class.
|
-- @field #string ClassName Name of the class.
|
||||||
@@ -25,7 +24,6 @@
|
|||||||
-- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value.
|
-- @field #number ThreshTtot Total time threshold. Only write output if total function CPU time is more than this value.
|
||||||
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
|
-- @field #string fileNamePrefix Output file name prefix, e.g. "MooseProfiler".
|
||||||
-- @field #string fileNameSuffix Output file name prefix, e.g. "txt"
|
-- @field #string fileNameSuffix Output file name prefix, e.g. "txt"
|
||||||
|
|
||||||
--- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? *
|
--- *The emperor counsels simplicity. First principles. Of each particular thing, ask: What is it in itself, in its own constitution? What is its causal nature? *
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
@@ -35,12 +33,11 @@
|
|||||||
-- # The PROFILER Concept
|
-- # The PROFILER Concept
|
||||||
--
|
--
|
||||||
-- Profile your lua code. This tells you, which functions are called very often and which consume most real time.
|
-- Profile your lua code. This tells you, which functions are called very often and which consume most real time.
|
||||||
-- With this information you can optimize the perfomance of your code.
|
-- With this information you can optimize the performance of your code.
|
||||||
--
|
--
|
||||||
-- # Prerequisites
|
-- # Prerequisites
|
||||||
--
|
--
|
||||||
-- The modules **os** and **lfs** need to be desanizied.
|
-- The modules **os** and **lfs** need to be de-sanitized.
|
||||||
--
|
|
||||||
--
|
--
|
||||||
-- # Start
|
-- # Start
|
||||||
--
|
--
|
||||||
@@ -117,61 +114,60 @@ PROFILER = {
|
|||||||
--- Start profiler.
|
--- Start profiler.
|
||||||
-- @param #number Delay Delay in seconds before profiler is stated. Default is immediately.
|
-- @param #number Delay Delay in seconds before profiler is stated. Default is immediately.
|
||||||
-- @param #number Duration Duration in (game) seconds before the profiler is stopped. Default is when mission ends.
|
-- @param #number Duration Duration in (game) seconds before the profiler is stopped. Default is when mission ends.
|
||||||
function PROFILER.Start(Delay, Duration)
|
function PROFILER.Start( Delay, Duration )
|
||||||
|
|
||||||
-- Check if os, io and lfs are available.
|
-- Check if os, io and lfs are available.
|
||||||
local go=true
|
local go = true
|
||||||
if not os then
|
if not os then
|
||||||
env.error("ERROR: Profiler needs os to be desanitized!")
|
env.error( "ERROR: Profiler needs os to be de-sanitized!" )
|
||||||
go=false
|
go = false
|
||||||
end
|
end
|
||||||
if not io then
|
if not io then
|
||||||
env.error("ERROR: Profiler needs io to be desanitized!")
|
env.error( "ERROR: Profiler needs io to be de-sanitized!" )
|
||||||
go=false
|
go = false
|
||||||
end
|
end
|
||||||
if not lfs then
|
if not lfs then
|
||||||
env.error("ERROR: Profiler needs lfs to be desanitized!")
|
env.error( "ERROR: Profiler needs lfs to be de-sanitized!" )
|
||||||
go=false
|
go = false
|
||||||
end
|
end
|
||||||
if not go then
|
if not go then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay > 0 then
|
||||||
BASE:ScheduleOnce(Delay, PROFILER.Start, 0, Duration)
|
BASE:ScheduleOnce( Delay, PROFILER.Start, 0, Duration )
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Set start time.
|
-- Set start time.
|
||||||
PROFILER.TstartGame=timer.getTime()
|
PROFILER.TstartGame = timer.getTime()
|
||||||
PROFILER.TstartOS=os.clock()
|
PROFILER.TstartOS = os.clock()
|
||||||
|
|
||||||
-- Add event handler.
|
-- Add event handler.
|
||||||
world.addEventHandler(PROFILER.eventHandler)
|
world.addEventHandler( PROFILER.eventHandler )
|
||||||
|
|
||||||
-- Info in log.
|
-- Info in log.
|
||||||
env.info('############################ Profiler Started ############################')
|
env.info( '############################ Profiler Started ############################' )
|
||||||
if Duration then
|
if Duration then
|
||||||
env.info(string.format("- Will be running for %d seconds", Duration))
|
env.info( string.format( "- Will be running for %d seconds", Duration ) )
|
||||||
else
|
else
|
||||||
env.info(string.format("- Will be stopped when mission ends"))
|
env.info( string.format( "- Will be stopped when mission ends" ) )
|
||||||
end
|
end
|
||||||
env.info(string.format("- Calls per second threshold %.3f/sec", PROFILER.ThreshCPS))
|
env.info( string.format( "- Calls per second threshold %.3f/sec", PROFILER.ThreshCPS ) )
|
||||||
env.info(string.format("- Total function time threshold %.3f sec", PROFILER.ThreshTtot))
|
env.info( string.format( "- Total function time threshold %.3f sec", PROFILER.ThreshTtot ) )
|
||||||
env.info(string.format("- Output file \"%s\" in your DCS log file folder", PROFILER.getfilename(PROFILER.fileNameSuffix)))
|
env.info( string.format( "- Output file \"%s\" in your DCS log file folder", PROFILER.getfilename( PROFILER.fileNameSuffix ) ) )
|
||||||
env.info(string.format("- Output file \"%s\" in CSV format", PROFILER.getfilename("csv")))
|
env.info( string.format( "- Output file \"%s\" in CSV format", PROFILER.getfilename( "csv" ) ) )
|
||||||
env.info('###############################################################################')
|
env.info( '###############################################################################' )
|
||||||
|
|
||||||
|
|
||||||
-- Message on screen
|
-- Message on screen
|
||||||
local duration=Duration or 600
|
local duration = Duration or 600
|
||||||
trigger.action.outText("### Profiler running ###", duration)
|
trigger.action.outText( "### Profiler running ###", duration )
|
||||||
|
|
||||||
-- Set hook.
|
-- Set hook.
|
||||||
debug.sethook(PROFILER.hook, "cr")
|
debug.sethook( PROFILER.hook, "cr" )
|
||||||
|
|
||||||
-- Auto stop profiler.
|
-- Auto stop profiler.
|
||||||
if Duration then
|
if Duration then
|
||||||
PROFILER.Stop(Duration)
|
PROFILER.Stop( Duration )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -180,34 +176,33 @@ end
|
|||||||
|
|
||||||
--- Stop profiler.
|
--- Stop profiler.
|
||||||
-- @param #number Delay Delay before stop in seconds.
|
-- @param #number Delay Delay before stop in seconds.
|
||||||
function PROFILER.Stop(Delay)
|
function PROFILER.Stop( Delay )
|
||||||
|
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay > 0 then
|
||||||
|
|
||||||
BASE:ScheduleOnce(Delay, PROFILER.Stop)
|
BASE:ScheduleOnce( Delay, PROFILER.Stop )
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Remove hook.
|
-- Remove hook.
|
||||||
debug.sethook()
|
debug.sethook()
|
||||||
|
|
||||||
|
|
||||||
-- Run time game.
|
-- Run time game.
|
||||||
local runTimeGame=timer.getTime()-PROFILER.TstartGame
|
local runTimeGame = timer.getTime() - PROFILER.TstartGame
|
||||||
|
|
||||||
-- Run time real OS.
|
-- Run time real OS.
|
||||||
local runTimeOS=os.clock()-PROFILER.TstartOS
|
local runTimeOS = os.clock() - PROFILER.TstartOS
|
||||||
|
|
||||||
-- Show info.
|
-- Show info.
|
||||||
PROFILER.showInfo(runTimeGame, runTimeOS)
|
PROFILER.showInfo( runTimeGame, runTimeOS )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Event handler.
|
--- Event handler.
|
||||||
function PROFILER.eventHandler:onEvent(event)
|
function PROFILER.eventHandler:onEvent( event )
|
||||||
if event.id==world.event.S_EVENT_MISSION_END then
|
if event.id == world.event.S_EVENT_MISSION_END then
|
||||||
PROFILER.Stop()
|
PROFILER.Stop()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -218,34 +213,34 @@ end
|
|||||||
|
|
||||||
--- Debug hook.
|
--- Debug hook.
|
||||||
-- @param #table event Event.
|
-- @param #table event Event.
|
||||||
function PROFILER.hook(event)
|
function PROFILER.hook( event )
|
||||||
|
|
||||||
local f=debug.getinfo(2, "f").func
|
local f = debug.getinfo( 2, "f" ).func
|
||||||
|
|
||||||
if event=='call' then
|
if event == 'call' then
|
||||||
|
|
||||||
if PROFILER.Counters[f]==nil then
|
if PROFILER.Counters[f] == nil then
|
||||||
|
|
||||||
PROFILER.Counters[f]=1
|
PROFILER.Counters[f] = 1
|
||||||
PROFILER.dInfo[f]=debug.getinfo(2,"Sn")
|
PROFILER.dInfo[f] = debug.getinfo( 2, "Sn" )
|
||||||
|
|
||||||
if PROFILER.fTimeTotal[f]==nil then
|
if PROFILER.fTimeTotal[f] == nil then
|
||||||
PROFILER.fTimeTotal[f]=0
|
PROFILER.fTimeTotal[f] = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
PROFILER.Counters[f]=PROFILER.Counters[f]+1
|
PROFILER.Counters[f] = PROFILER.Counters[f] + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if PROFILER.fTime[f]==nil then
|
if PROFILER.fTime[f] == nil then
|
||||||
PROFILER.fTime[f]=os.clock()
|
PROFILER.fTime[f] = os.clock()
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif (event=='return') then
|
elseif (event == 'return') then
|
||||||
|
|
||||||
if PROFILER.fTime[f]~=nil then
|
if PROFILER.fTime[f] ~= nil then
|
||||||
PROFILER.fTimeTotal[f]=PROFILER.fTimeTotal[f]+(os.clock()-PROFILER.fTime[f])
|
PROFILER.fTimeTotal[f] = PROFILER.fTimeTotal[f] + (os.clock() - PROFILER.fTime[f])
|
||||||
PROFILER.fTime[f]=nil
|
PROFILER.fTime[f] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -262,11 +257,11 @@ end
|
|||||||
-- @return #string Source file name.
|
-- @return #string Source file name.
|
||||||
-- @return #string Line number.
|
-- @return #string Line number.
|
||||||
-- @return #number Function time in seconds.
|
-- @return #number Function time in seconds.
|
||||||
function PROFILER.getData(func)
|
function PROFILER.getData( func )
|
||||||
|
|
||||||
local n=PROFILER.dInfo[func]
|
local n = PROFILER.dInfo[func]
|
||||||
|
|
||||||
if n.what=="C" then
|
if n.what == "C" then
|
||||||
return n.name, "?", "?", PROFILER.fTimeTotal[func]
|
return n.name, "?", "?", PROFILER.fTimeTotal[func]
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -276,31 +271,31 @@ end
|
|||||||
--- Write text to log file.
|
--- Write text to log file.
|
||||||
-- @param #function f The file.
|
-- @param #function f The file.
|
||||||
-- @param #string txt The text.
|
-- @param #string txt The text.
|
||||||
function PROFILER._flog(f, txt)
|
function PROFILER._flog( f, txt )
|
||||||
f:write(txt.."\r\n")
|
f:write( txt .. "\r\n" )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Show table.
|
--- Show table.
|
||||||
-- @param #table data Data table.
|
-- @param #table data Data table.
|
||||||
-- @param #function f The file.
|
-- @param #function f The file.
|
||||||
-- @param #number runTimeGame Game run time in seconds.
|
-- @param #number runTimeGame Game run time in seconds.
|
||||||
function PROFILER.showTable(data, f, runTimeGame)
|
function PROFILER.showTable( data, f, runTimeGame )
|
||||||
|
|
||||||
-- Loop over data.
|
-- Loop over data.
|
||||||
for i=1, #data do
|
for i = 1, #data do
|
||||||
local t=data[i] --#PROFILER.Data
|
local t = data[i] -- #PROFILER.Data
|
||||||
|
|
||||||
-- Calls per second.
|
-- Calls per second.
|
||||||
local cps=t.count/runTimeGame
|
local cps = t.count / runTimeGame
|
||||||
|
|
||||||
local threshCPS=cps>=PROFILER.ThreshCPS
|
local threshCPS = cps >= PROFILER.ThreshCPS
|
||||||
local threshTot=t.tm>=PROFILER.ThreshTtot
|
local threshTot = t.tm >= PROFILER.ThreshTtot
|
||||||
|
|
||||||
if threshCPS and threshTot then
|
if threshCPS and threshTot then
|
||||||
|
|
||||||
-- Output
|
-- Output
|
||||||
local text=string.format("%30s: %8d calls %8.1f/sec - Time Total %8.3f sec (%.3f %%) %5.3f sec/call %s line %s", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line))
|
local text = string.format( "%30s: %8d calls %8.1f/sec - Time Total %8.3f sec (%.3f %%) %5.3f sec/call %s line %s", t.func, t.count, cps, t.tm, t.tm / runTimeGame * 100, t.tm / t.count, tostring( t.src ), tostring( t.line ) )
|
||||||
PROFILER._flog(f, text)
|
PROFILER._flog( f, text )
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -310,26 +305,26 @@ end
|
|||||||
--- Print csv file.
|
--- Print csv file.
|
||||||
-- @param #table data Data table.
|
-- @param #table data Data table.
|
||||||
-- @param #number runTimeGame Game run time in seconds.
|
-- @param #number runTimeGame Game run time in seconds.
|
||||||
function PROFILER.printCSV(data, runTimeGame)
|
function PROFILER.printCSV( data, runTimeGame )
|
||||||
|
|
||||||
-- Output file.
|
-- Output file.
|
||||||
local file=PROFILER.getfilename("csv")
|
local file = PROFILER.getfilename( "csv" )
|
||||||
local g=io.open(file, 'w')
|
local g = io.open( file, 'w' )
|
||||||
|
|
||||||
-- Header.
|
-- Header.
|
||||||
local text="Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number,"
|
local text = "Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number,"
|
||||||
g:write(text.."\r\n")
|
g:write( text .. "\r\n" )
|
||||||
|
|
||||||
-- Loop over data.
|
-- Loop over data.
|
||||||
for i=1, #data do
|
for i = 1, #data do
|
||||||
local t=data[i] --#PROFILER.Data
|
local t = data[i] -- #PROFILER.Data
|
||||||
|
|
||||||
-- Calls per second.
|
-- Calls per second.
|
||||||
local cps=t.count/runTimeGame
|
local cps = t.count / runTimeGame
|
||||||
|
|
||||||
-- Output
|
-- Output
|
||||||
local txt=string.format("%s,%d,%.1f,%.3f,%.3f,%.3f,%s,%s,", t.func, t.count, cps, t.tm, t.tm/runTimeGame*100, t.tm/t.count, tostring(t.src), tostring(t.line))
|
local txt = string.format( "%s,%d,%.1f,%.3f,%.3f,%.3f,%s,%s,", t.func, t.count, cps, t.tm, t.tm / runTimeGame * 100, t.tm / t.count, tostring( t.src ), tostring( t.line ) )
|
||||||
g:write(txt.."\r\n")
|
g:write( txt .. "\r\n" )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -337,27 +332,26 @@ function PROFILER.printCSV(data, runTimeGame)
|
|||||||
g:close()
|
g:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Write info to output file.
|
--- Write info to output file.
|
||||||
-- @param #string ext Extension.
|
-- @param #string ext Extension.
|
||||||
-- @return #string File name.
|
-- @return #string File name.
|
||||||
function PROFILER.getfilename(ext)
|
function PROFILER.getfilename( ext )
|
||||||
|
|
||||||
local dir=lfs.writedir()..[[Logs\]]
|
local dir = lfs.writedir() .. [[Logs\]]
|
||||||
|
|
||||||
ext=ext or PROFILER.fileNameSuffix
|
ext = ext or PROFILER.fileNameSuffix
|
||||||
|
|
||||||
local file=dir..PROFILER.fileNamePrefix.."."..ext
|
local file = dir .. PROFILER.fileNamePrefix .. "." .. ext
|
||||||
|
|
||||||
if not UTILS.FileExists(file) then
|
if not UTILS.FileExists( file ) then
|
||||||
return file
|
return file
|
||||||
end
|
end
|
||||||
|
|
||||||
for i=1,999 do
|
for i = 1, 999 do
|
||||||
|
|
||||||
local file=string.format("%s%s-%03d.%s", dir,PROFILER.fileNamePrefix, i, ext)
|
local file = string.format( "%s%s-%03d.%s", dir, PROFILER.fileNamePrefix, i, ext )
|
||||||
|
|
||||||
if not UTILS.FileExists(file) then
|
if not UTILS.FileExists( file ) then
|
||||||
return file
|
return file
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -368,81 +362,76 @@ end
|
|||||||
--- Write info to output file.
|
--- Write info to output file.
|
||||||
-- @param #number runTimeGame Game time in seconds.
|
-- @param #number runTimeGame Game time in seconds.
|
||||||
-- @param #number runTimeOS OS time in seconds.
|
-- @param #number runTimeOS OS time in seconds.
|
||||||
function PROFILER.showInfo(runTimeGame, runTimeOS)
|
function PROFILER.showInfo( runTimeGame, runTimeOS )
|
||||||
|
|
||||||
-- Output file.
|
-- Output file.
|
||||||
local file=PROFILER.getfilename(PROFILER.fileNameSuffix)
|
local file = PROFILER.getfilename( PROFILER.fileNameSuffix )
|
||||||
local f=io.open(file, 'w')
|
local f = io.open( file, 'w' )
|
||||||
|
|
||||||
-- Gather data.
|
-- Gather data.
|
||||||
local Ttot=0
|
local Ttot = 0
|
||||||
local Calls=0
|
local Calls = 0
|
||||||
|
|
||||||
local t={}
|
local t = {}
|
||||||
|
|
||||||
local tcopy=nil --#PROFILER.Data
|
local tcopy = nil -- #PROFILER.Data
|
||||||
local tserialize=nil --#PROFILER.Data
|
local tserialize = nil -- #PROFILER.Data
|
||||||
local tforgen=nil --#PROFILER.Data
|
local tforgen = nil -- #PROFILER.Data
|
||||||
local tpairs=nil --#PROFILER.Data
|
local tpairs = nil -- #PROFILER.Data
|
||||||
|
|
||||||
|
for func, count in pairs( PROFILER.Counters ) do
|
||||||
|
|
||||||
for func, count in pairs(PROFILER.Counters) do
|
local s, src, line, tm = PROFILER.getData( func )
|
||||||
|
|
||||||
local s,src,line,tm=PROFILER.getData(func)
|
if PROFILER.logUnknown == true then
|
||||||
|
if s == nil then
|
||||||
if PROFILER.logUnknown==true then
|
s = "<Unknown>"
|
||||||
if s==nil then s="<Unknown>" end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if s~=nil then
|
if s ~= nil then
|
||||||
|
|
||||||
-- Profile data.
|
-- Profile data.
|
||||||
local T=
|
local T = { func = s, src = src, line = line, count = count, tm = tm } -- #PROFILER.Data
|
||||||
{ func=s,
|
|
||||||
src=src,
|
|
||||||
line=line,
|
|
||||||
count=count,
|
|
||||||
tm=tm,
|
|
||||||
} --#PROFILER.Data
|
|
||||||
|
|
||||||
-- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data.
|
-- Collect special cases. Somehow, e.g. "_copy" appears multiple times so we try to gather all data.
|
||||||
if s=="_copy" then
|
if s == "_copy" then
|
||||||
if tcopy==nil then
|
if tcopy == nil then
|
||||||
tcopy=T
|
tcopy = T
|
||||||
else
|
else
|
||||||
tcopy.count=tcopy.count+T.count
|
tcopy.count = tcopy.count + T.count
|
||||||
tcopy.tm=tcopy.tm+T.tm
|
tcopy.tm = tcopy.tm + T.tm
|
||||||
end
|
end
|
||||||
elseif s=="_Serialize" then
|
elseif s == "_Serialize" then
|
||||||
if tserialize==nil then
|
if tserialize == nil then
|
||||||
tserialize=T
|
tserialize = T
|
||||||
else
|
else
|
||||||
tserialize.count=tserialize.count+T.count
|
tserialize.count = tserialize.count + T.count
|
||||||
tserialize.tm=tserialize.tm+T.tm
|
tserialize.tm = tserialize.tm + T.tm
|
||||||
end
|
end
|
||||||
elseif s=="(for generator)" then
|
elseif s == "(for generator)" then
|
||||||
if tforgen==nil then
|
if tforgen == nil then
|
||||||
tforgen=T
|
tforgen = T
|
||||||
else
|
else
|
||||||
tforgen.count=tforgen.count+T.count
|
tforgen.count = tforgen.count + T.count
|
||||||
tforgen.tm=tforgen.tm+T.tm
|
tforgen.tm = tforgen.tm + T.tm
|
||||||
end
|
end
|
||||||
elseif s=="pairs" then
|
elseif s == "pairs" then
|
||||||
if tpairs==nil then
|
if tpairs == nil then
|
||||||
tpairs=T
|
tpairs = T
|
||||||
else
|
else
|
||||||
tpairs.count=tpairs.count+T.count
|
tpairs.count = tpairs.count + T.count
|
||||||
tpairs.tm=tpairs.tm+T.tm
|
tpairs.tm = tpairs.tm + T.tm
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
table.insert(t, T)
|
table.insert( t, T )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Total function time.
|
-- Total function time.
|
||||||
Ttot=Ttot+tm
|
Ttot = Ttot + tm
|
||||||
|
|
||||||
-- Total number of calls.
|
-- Total number of calls.
|
||||||
Calls=Calls+count
|
Calls = Calls + count
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -450,90 +439,95 @@ function PROFILER.showInfo(runTimeGame, runTimeOS)
|
|||||||
|
|
||||||
-- Add special cases.
|
-- Add special cases.
|
||||||
if tcopy then
|
if tcopy then
|
||||||
table.insert(t, tcopy)
|
table.insert( t, tcopy )
|
||||||
end
|
end
|
||||||
if tserialize then
|
if tserialize then
|
||||||
table.insert(t, tserialize)
|
table.insert( t, tserialize )
|
||||||
end
|
end
|
||||||
if tforgen then
|
if tforgen then
|
||||||
table.insert(t, tforgen)
|
table.insert( t, tforgen )
|
||||||
end
|
end
|
||||||
if tpairs then
|
if tpairs then
|
||||||
table.insert(t, tpairs)
|
table.insert( t, tpairs )
|
||||||
end
|
end
|
||||||
|
|
||||||
env.info('############################ Profiler Stopped ############################')
|
env.info( '############################ Profiler Stopped ############################' )
|
||||||
env.info(string.format("* Runtime Game : %s = %d sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame))
|
env.info( string.format( "* Runtime Game : %s = %d sec", UTILS.SecondsToClock( runTimeGame, true ), runTimeGame ) )
|
||||||
env.info(string.format("* Runtime Real : %s = %d sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS))
|
env.info( string.format( "* Runtime Real : %s = %d sec", UTILS.SecondsToClock( runTimeOS, true ), runTimeOS ) )
|
||||||
env.info(string.format("* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100))
|
env.info( string.format( "* Function time : %s = %.1f sec (%.1f percent of runtime game)", UTILS.SecondsToClock( Ttot, true ), Ttot, Ttot / runTimeGame * 100 ) )
|
||||||
env.info(string.format("* Total functions : %d", #t))
|
env.info( string.format( "* Total functions : %d", #t ) )
|
||||||
env.info(string.format("* Total func calls : %d", Calls))
|
env.info( string.format( "* Total func calls : %d", Calls ) )
|
||||||
env.info(string.format("* Writing to file : \"%s\"", file))
|
env.info( string.format( "* Writing to file : \"%s\"", file ) )
|
||||||
env.info(string.format("* Writing to file : \"%s\"", PROFILER.getfilename("csv")))
|
env.info( string.format( "* Writing to file : \"%s\"", PROFILER.getfilename( "csv" ) ) )
|
||||||
env.info("##############################################################################")
|
env.info( "##############################################################################" )
|
||||||
|
|
||||||
-- Sort by total time.
|
-- Sort by total time.
|
||||||
table.sort(t, function(a,b) return a.tm>b.tm end)
|
table.sort( t, function( a, b )
|
||||||
|
return a.tm > b.tm
|
||||||
|
end )
|
||||||
|
|
||||||
-- Write data.
|
-- Write data.
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"-------------------------")
|
PROFILER._flog( f, "-------------------------" )
|
||||||
PROFILER._flog(f,"---- Profiler Report ----")
|
PROFILER._flog( f, "---- Profiler Report ----" )
|
||||||
PROFILER._flog(f,"-------------------------")
|
PROFILER._flog( f, "-------------------------" )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,string.format("* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock(runTimeGame, true), runTimeGame))
|
PROFILER._flog( f, string.format( "* Runtime Game : %s = %.1f sec", UTILS.SecondsToClock( runTimeGame, true ), runTimeGame ) )
|
||||||
PROFILER._flog(f,string.format("* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock(runTimeOS, true), runTimeOS))
|
PROFILER._flog( f, string.format( "* Runtime Real : %s = %.1f sec", UTILS.SecondsToClock( runTimeOS, true ), runTimeOS ) )
|
||||||
PROFILER._flog(f,string.format("* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100))
|
PROFILER._flog( f, string.format( "* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock( Ttot, true ), Ttot, Ttot / runTimeGame * 100 ) )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,string.format("* Total functions = %d", #t))
|
PROFILER._flog( f, string.format( "* Total functions = %d", #t ) )
|
||||||
PROFILER._flog(f,string.format("* Total func calls = %d", Calls))
|
PROFILER._flog( f, string.format( "* Total func calls = %d", Calls ) )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,string.format("* Calls per second threshold = %.3f/sec", PROFILER.ThreshCPS))
|
PROFILER._flog( f, string.format( "* Calls per second threshold = %.3f/sec", PROFILER.ThreshCPS ) )
|
||||||
PROFILER._flog(f,string.format("* Total func time threshold = %.3f sec", PROFILER.ThreshTtot))
|
PROFILER._flog( f, string.format( "* Total func time threshold = %.3f sec", PROFILER.ThreshTtot ) )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER.showTable(t, f, runTimeGame)
|
PROFILER.showTable( t, f, runTimeGame )
|
||||||
|
|
||||||
-- Sort by number of calls.
|
-- Sort by number of calls.
|
||||||
table.sort(t, function(a,b) return a.tm/a.count>b.tm/b.count end)
|
table.sort( t, function( a, b )
|
||||||
|
return a.tm / a.count > b.tm / b.count
|
||||||
|
end )
|
||||||
|
|
||||||
-- Detailed data.
|
-- Detailed data.
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"--------------------------------------")
|
PROFILER._flog( f, "--------------------------------------" )
|
||||||
PROFILER._flog(f,"---- Data Sorted by Time per Call ----")
|
PROFILER._flog( f, "---- Data Sorted by Time per Call ----" )
|
||||||
PROFILER._flog(f,"--------------------------------------")
|
PROFILER._flog( f, "--------------------------------------" )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER.showTable(t, f, runTimeGame)
|
PROFILER.showTable( t, f, runTimeGame )
|
||||||
|
|
||||||
-- Sort by number of calls.
|
-- Sort by number of calls.
|
||||||
table.sort(t, function(a,b) return a.count>b.count end)
|
table.sort( t, function( a, b )
|
||||||
|
return a.count > b.count
|
||||||
|
end )
|
||||||
|
|
||||||
-- Detailed data.
|
-- Detailed data.
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"------------------------------------")
|
PROFILER._flog( f, "------------------------------------" )
|
||||||
PROFILER._flog(f,"---- Data Sorted by Total Calls ----")
|
PROFILER._flog( f, "---- Data Sorted by Total Calls ----" )
|
||||||
PROFILER._flog(f,"------------------------------------")
|
PROFILER._flog( f, "------------------------------------" )
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER.showTable(t, f, runTimeGame)
|
PROFILER.showTable( t, f, runTimeGame )
|
||||||
|
|
||||||
-- Closing.
|
-- Closing.
|
||||||
PROFILER._flog(f,"")
|
PROFILER._flog( f, "" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
PROFILER._flog(f,"************************************************************************************************************************")
|
PROFILER._flog( f, "************************************************************************************************************************" )
|
||||||
-- Close file.
|
-- Close file.
|
||||||
f:close()
|
f:close()
|
||||||
|
|
||||||
-- Print csv file.
|
-- Print csv file.
|
||||||
PROFILER.printCSV(t, runTimeGame)
|
PROFILER.printCSV( t, runTimeGame )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
|||||||
--- **Utilities** DCS Simple Text-To-Speech (STTS).
|
--- **Utilities** DCS Simple Text-To-Speech (STTS).
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
--
|
|
||||||
-- @module Utils.STTS
|
-- @module Utils.STTS
|
||||||
-- @image MOOSE.JPG
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
@@ -15,7 +14,7 @@
|
|||||||
--
|
--
|
||||||
-- # DCS Modification Required
|
-- # DCS Modification Required
|
||||||
--
|
--
|
||||||
-- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitisation.
|
-- You will need to edit MissionScripting.lua in DCS World/Scripts/MissionScripting.lua and remove the sanitization.
|
||||||
-- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)"
|
-- To do this remove all the code below the comment - the line starts "local function sanitizeModule(name)"
|
||||||
-- Do this without DCS running to allow mission scripts to use os functions.
|
-- Do this without DCS running to allow mission scripts to use os functions.
|
||||||
--
|
--
|
||||||
@@ -23,7 +22,7 @@
|
|||||||
--
|
--
|
||||||
-- # USAGE:
|
-- # USAGE:
|
||||||
--
|
--
|
||||||
-- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialise it
|
-- Add this script into the mission as a DO SCRIPT or DO SCRIPT FROM FILE to initialize it
|
||||||
-- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission.
|
-- Make sure to edit the STTS.SRS_PORT and STTS.DIRECTORY to the correct values before adding to the mission.
|
||||||
-- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts.
|
-- Then its as simple as calling the correct function in LUA as a DO SCRIPT or in your own scripts.
|
||||||
--
|
--
|
||||||
@@ -43,7 +42,7 @@
|
|||||||
-- * OPTIONAL - Speed -10 to +10
|
-- * OPTIONAL - Speed -10 to +10
|
||||||
-- * OPTIONAL - Gender male, female or neuter
|
-- * OPTIONAL - Gender male, female or neuter
|
||||||
-- * OPTIONAL - Culture - en-US, en-GB etc
|
-- * OPTIONAL - Culture - en-US, en-GB etc
|
||||||
-- * OPTIONAL - Voice - a specfic voice by name. Run DCS-SR-ExternalAudio.exe with --help to get the ones you can use on the command line
|
-- * OPTIONAL - Voice - a specific voice by name. Run DCS-SR-ExternalAudio.exe with --help to get the ones you can use on the command line
|
||||||
-- * OPTIONAL - Google TTS - Switch to Google Text To Speech - Requires STTS.GOOGLE_CREDENTIALS path and Google project setup correctly
|
-- * OPTIONAL - Google TTS - Switch to Google Text To Speech - Requires STTS.GOOGLE_CREDENTIALS path and Google project setup correctly
|
||||||
--
|
--
|
||||||
--
|
--
|
||||||
@@ -55,7 +54,7 @@
|
|||||||
--
|
--
|
||||||
-- ## Example
|
-- ## Example
|
||||||
--
|
--
|
||||||
--This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only centered on the position of the Unit called "A UNIT"
|
-- This example will say the words "Hello DCS WORLD" on 251 MHz AM at maximum volume with a client called SRS and to the Blue coalition only centered on the position of the Unit called "A UNIT"
|
||||||
--
|
--
|
||||||
-- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2,Unit.getByName("A UNIT"):getPoint(),-5,"male","en-GB")
|
-- STTS.TextToSpeech("Hello DCS WORLD","251","AM","1.0","SRS",2,Unit.getByName("A UNIT"):getPoint(),-5,"male","en-GB")
|
||||||
--
|
--
|
||||||
@@ -75,12 +74,12 @@
|
|||||||
-- STTS.PlayMP3("C:\\Users\\Ciaran\\Downloads\\PR-Music.mp3","255,31","AM,FM","0.5","Multiple",0)
|
-- STTS.PlayMP3("C:\\Users\\Ciaran\\Downloads\\PR-Music.mp3","255,31","AM,FM","0.5","Multiple",0)
|
||||||
--
|
--
|
||||||
-- @field #STTS
|
-- @field #STTS
|
||||||
STTS={
|
STTS = {
|
||||||
ClassName="STTS",
|
ClassName = "STTS",
|
||||||
DIRECTORY="",
|
DIRECTORY = "",
|
||||||
SRS_PORT=5002,
|
SRS_PORT = 5002,
|
||||||
GOOGLE_CREDENTIALS="C:\\Users\\Ciaran\\Downloads\\googletts.json",
|
GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json",
|
||||||
EXECUTABLE="DCS-SR-ExternalAudio.exe",
|
EXECUTABLE = "DCS-SR-ExternalAudio.exe"
|
||||||
}
|
}
|
||||||
|
|
||||||
--- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER
|
--- FULL Path to the FOLDER containing DCS-SR-ExternalAudio.exe - EDIT TO CORRECT FOLDER
|
||||||
@@ -92,40 +91,43 @@ STTS.SRS_PORT = 5002
|
|||||||
--- Google credentials file
|
--- Google credentials file
|
||||||
STTS.GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json"
|
STTS.GOOGLE_CREDENTIALS = "C:\\Users\\Ciaran\\Downloads\\googletts.json"
|
||||||
|
|
||||||
--- DONT CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING
|
--- DON'T CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING
|
||||||
STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe"
|
STTS.EXECUTABLE = "DCS-SR-ExternalAudio.exe"
|
||||||
|
|
||||||
|
|
||||||
--- Function for UUID.
|
--- Function for UUID.
|
||||||
function STTS.uuid()
|
function STTS.uuid()
|
||||||
local random = math.random
|
local random = math.random
|
||||||
local template ='yxxx-xxxxxxxxxxxx'
|
local template = 'yxxx-xxxxxxxxxxxx'
|
||||||
return string.gsub(template, '[xy]', function (c)
|
return string.gsub( template, '[xy]', function( c )
|
||||||
local v = (c == 'x') and random(0, 0xf) or random(8, 0xb)
|
local v = (c == 'x') and random( 0, 0xf ) or random( 8, 0xb )
|
||||||
return string.format('%x', v)
|
return string.format( '%x', v )
|
||||||
end)
|
end )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Round a number.
|
--- Round a number.
|
||||||
-- @param #number x Number.
|
-- @param #number x Number.
|
||||||
-- @param #number n Precision.
|
-- @param #number n Precision.
|
||||||
function STTS.round(x, n)
|
function STTS.round( x, n )
|
||||||
n = math.pow(10, n or 0)
|
n = math.pow( 10, n or 0 )
|
||||||
x = x * n
|
x = x * n
|
||||||
if x >= 0 then x = math.floor(x + 0.5) else x = math.ceil(x - 0.5) end
|
if x >= 0 then
|
||||||
|
x = math.floor( x + 0.5 )
|
||||||
|
else
|
||||||
|
x = math.ceil( x - 0.5 )
|
||||||
|
end
|
||||||
return x / n
|
return x / n
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Function returns estimated speech time in seconds.
|
--- Function returns estimated speech time in seconds.
|
||||||
-- Assumptions for time calc: 100 Words per min, avarage of 5 letters for english word so
|
-- Assumptions for time calc: 100 Words per min, average of 5 letters for english word so
|
||||||
--
|
--
|
||||||
-- * 5 chars * 100wpm = 500 characters per min = 8.3 chars per second
|
-- * 5 chars * 100wpm = 500 characters per min = 8.3 chars per second
|
||||||
--
|
--
|
||||||
-- So lengh of msg / 8.3 = number of seconds needed to read it. rounded down to 8 chars per sec map function:
|
-- So length of msg / 8.3 = number of seconds needed to read it. rounded down to 8 chars per sec map function:
|
||||||
--
|
--
|
||||||
-- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
|
-- * (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
|
||||||
--
|
--
|
||||||
function STTS.getSpeechTime(length,speed,isGoogle)
|
function STTS.getSpeechTime( length, speed, isGoogle )
|
||||||
|
|
||||||
local maxRateRatio = 3
|
local maxRateRatio = 3
|
||||||
|
|
||||||
@@ -137,27 +139,27 @@ function STTS.getSpeechTime(length,speed,isGoogle)
|
|||||||
speedFactor = speed
|
speedFactor = speed
|
||||||
else
|
else
|
||||||
if speed ~= 0 then
|
if speed ~= 0 then
|
||||||
speedFactor = math.abs(speed) * (maxRateRatio - 1) / 10 + 1
|
speedFactor = math.abs( speed ) * (maxRateRatio - 1) / 10 + 1
|
||||||
end
|
end
|
||||||
if speed < 0 then
|
if speed < 0 then
|
||||||
speedFactor = 1/speedFactor
|
speedFactor = 1 / speedFactor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local wpm = math.ceil(100 * speedFactor)
|
local wpm = math.ceil( 100 * speedFactor )
|
||||||
local cps = math.floor((wpm * 5)/60)
|
local cps = math.floor( (wpm * 5) / 60 )
|
||||||
|
|
||||||
if type(length) == "string" then
|
if type( length ) == "string" then
|
||||||
length = string.len(length)
|
length = string.len( length )
|
||||||
end
|
end
|
||||||
|
|
||||||
return math.ceil(length/cps)
|
return math.ceil( length / cps )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Text to speech function.
|
--- Text to speech function.
|
||||||
function STTS.TextToSpeech(message, freqs, modulations, volume, name, coalition, point, speed, gender, culture, voice, googleTTS)
|
function STTS.TextToSpeech( message, freqs, modulations, volume, name, coalition, point, speed, gender, culture, voice, googleTTS )
|
||||||
if os == nil or io == nil then
|
if os == nil or io == nil then
|
||||||
env.info("[DCS-STTS] LUA modules os or io are sanitized. skipping. ")
|
env.info( "[DCS-STTS] LUA modules os or io are sanitized. skipping. " )
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -165,69 +167,68 @@ function STTS.TextToSpeech(message, freqs, modulations, volume, name, coalition,
|
|||||||
gender = gender or "female"
|
gender = gender or "female"
|
||||||
culture = culture or ""
|
culture = culture or ""
|
||||||
voice = voice or ""
|
voice = voice or ""
|
||||||
coalition=coalition or "0"
|
coalition = coalition or "0"
|
||||||
name=name or "ROBOT"
|
name = name or "ROBOT"
|
||||||
volume=1
|
volume = 1
|
||||||
speed=1
|
speed = 1
|
||||||
|
|
||||||
|
message = message:gsub( "\"", "\\\"" )
|
||||||
|
|
||||||
message = message:gsub("\"","\\\"")
|
local cmd = string.format( "start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name )
|
||||||
|
|
||||||
local cmd = string.format("start /min \"\" /d \"%s\" /b \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -h", STTS.DIRECTORY, STTS.EXECUTABLE, freqs or "305", modulations or "AM", coalition, STTS.SRS_PORT, name)
|
|
||||||
|
|
||||||
if voice ~= "" then
|
if voice ~= "" then
|
||||||
cmd = cmd .. string.format(" -V \"%s\"",voice)
|
cmd = cmd .. string.format( " -V \"%s\"", voice )
|
||||||
else
|
else
|
||||||
|
|
||||||
if culture ~= "" then
|
if culture ~= "" then
|
||||||
cmd = cmd .. string.format(" -l %s",culture)
|
cmd = cmd .. string.format( " -l %s", culture )
|
||||||
end
|
end
|
||||||
|
|
||||||
if gender ~= "" then
|
if gender ~= "" then
|
||||||
cmd = cmd .. string.format(" -g %s",gender)
|
cmd = cmd .. string.format( " -g %s", gender )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if googleTTS == true then
|
if googleTTS == true then
|
||||||
cmd = cmd .. string.format(" -G \"%s\"",STTS.GOOGLE_CREDENTIALS)
|
cmd = cmd .. string.format( " -G \"%s\"", STTS.GOOGLE_CREDENTIALS )
|
||||||
end
|
end
|
||||||
|
|
||||||
if speed ~= 1 then
|
if speed ~= 1 then
|
||||||
cmd = cmd .. string.format(" -s %s",speed)
|
cmd = cmd .. string.format( " -s %s", speed )
|
||||||
end
|
end
|
||||||
|
|
||||||
if volume ~= 1.0 then
|
if volume ~= 1.0 then
|
||||||
cmd = cmd .. string.format(" -v %s",volume)
|
cmd = cmd .. string.format( " -v %s", volume )
|
||||||
end
|
end
|
||||||
|
|
||||||
if point and type(point) == "table" and point.x then
|
if point and type( point ) == "table" and point.x then
|
||||||
local lat, lon, alt = coord.LOtoLL(point)
|
local lat, lon, alt = coord.LOtoLL( point )
|
||||||
|
|
||||||
lat = STTS.round(lat,4)
|
lat = STTS.round( lat, 4 )
|
||||||
lon = STTS.round(lon,4)
|
lon = STTS.round( lon, 4 )
|
||||||
alt = math.floor(alt)
|
alt = math.floor( alt )
|
||||||
|
|
||||||
cmd = cmd .. string.format(" -L %s -O %s -A %s",lat,lon,alt)
|
cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
|
||||||
end
|
end
|
||||||
|
|
||||||
cmd = cmd ..string.format(" -t \"%s\"",message)
|
cmd = cmd .. string.format( " -t \"%s\"", message )
|
||||||
|
|
||||||
if string.len(cmd) > 255 then
|
if string.len( cmd ) > 255 then
|
||||||
local filename = os.getenv('TMP') .. "\\DCS_STTS-" .. STTS.uuid() .. ".bat"
|
local filename = os.getenv( 'TMP' ) .. "\\DCS_STTS-" .. STTS.uuid() .. ".bat"
|
||||||
local script = io.open(filename,"w+")
|
local script = io.open( filename, "w+" )
|
||||||
script:write(cmd .. " && exit" )
|
script:write( cmd .. " && exit" )
|
||||||
script:close()
|
script:close()
|
||||||
cmd = string.format("\"%s\"",filename)
|
cmd = string.format( "\"%s\"", filename )
|
||||||
timer.scheduleFunction(os.remove, filename, timer.getTime() + 1)
|
timer.scheduleFunction( os.remove, filename, timer.getTime() + 1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
if string.len(cmd) > 255 then
|
if string.len( cmd ) > 255 then
|
||||||
env.info("[DCS-STTS] - cmd string too long")
|
env.info( "[DCS-STTS] - cmd string too long" )
|
||||||
env.info("[DCS-STTS] TextToSpeech Command :\n" .. cmd.."\n")
|
env.info( "[DCS-STTS] TextToSpeech Command :\n" .. cmd .. "\n" )
|
||||||
end
|
end
|
||||||
os.execute(cmd)
|
os.execute( cmd )
|
||||||
|
|
||||||
return STTS.getSpeechTime(message,speed,googleTTS)
|
return STTS.getSpeechTime( message, speed, googleTTS )
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Play mp3 function.
|
--- Play mp3 function.
|
||||||
@@ -235,22 +236,21 @@ end
|
|||||||
-- @param #string freqs Frequencies, e.g. "305, 256".
|
-- @param #string freqs Frequencies, e.g. "305, 256".
|
||||||
-- @param #string modulations Modulations, e.g. "AM, FM".
|
-- @param #string modulations Modulations, e.g. "AM, FM".
|
||||||
-- @param #string volume Volume, e.g. "0.5".
|
-- @param #string volume Volume, e.g. "0.5".
|
||||||
function STTS.PlayMP3(pathToMP3, freqs, modulations, volume, name, coalition, point)
|
function STTS.PlayMP3( pathToMP3, freqs, modulations, volume, name, coalition, point )
|
||||||
|
|
||||||
local cmd = string.format("start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h",
|
local cmd = string.format( "start \"\" /d \"%s\" /b /min \"%s\" -i \"%s\" -f %s -m %s -c %s -p %s -n \"%s\" -v %s -h", STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1" )
|
||||||
STTS.DIRECTORY, STTS.EXECUTABLE, pathToMP3, freqs or "305", modulations or "AM", coalition or "0", STTS.SRS_PORT, name or "ROBOT", volume or "1")
|
|
||||||
|
|
||||||
if point and type(point) == "table" and point.x then
|
if point and type( point ) == "table" and point.x then
|
||||||
local lat, lon, alt = coord.LOtoLL(point)
|
local lat, lon, alt = coord.LOtoLL( point )
|
||||||
|
|
||||||
lat = STTS.round(lat,4)
|
lat = STTS.round( lat, 4 )
|
||||||
lon = STTS.round(lon,4)
|
lon = STTS.round( lon, 4 )
|
||||||
alt = math.floor(alt)
|
alt = math.floor( alt )
|
||||||
|
|
||||||
cmd = cmd .. string.format(" -L %s -O %s -A %s",lat,lon,alt)
|
cmd = cmd .. string.format( " -L %s -O %s -A %s", lat, lon, alt )
|
||||||
end
|
end
|
||||||
|
|
||||||
env.info("[DCS-STTS] MP3/OGG Command :\n" .. cmd.."\n")
|
env.info( "[DCS-STTS] MP3/OGG Command :\n" .. cmd .. "\n" )
|
||||||
os.execute(cmd)
|
os.execute( cmd )
|
||||||
|
|
||||||
end
|
end
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,7 @@
|
|||||||
-- @field #table CategoryName Names of airbase categories.
|
-- @field #table CategoryName Names of airbase categories.
|
||||||
-- @field #string AirbaseName Name of the airbase.
|
-- @field #string AirbaseName Name of the airbase.
|
||||||
-- @field #number AirbaseID Airbase ID.
|
-- @field #number AirbaseID Airbase ID.
|
||||||
|
-- @field Core.Zone#ZONE AirbaseZone Circular zone around the airbase with a radius of 2500 meters. For ships this is a ZONE_UNIT object.
|
||||||
-- @field #number category Airbase category.
|
-- @field #number category Airbase category.
|
||||||
-- @field #table descriptors DCS descriptors.
|
-- @field #table descriptors DCS descriptors.
|
||||||
-- @field #boolean isAirdrome Airbase is an airdrome.
|
-- @field #boolean isAirdrome Airbase is an airdrome.
|
||||||
@@ -546,6 +547,13 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
self.isHelipad=true
|
self.isHelipad=true
|
||||||
elseif self.category==Airbase.Category.SHIP then
|
elseif self.category==Airbase.Category.SHIP then
|
||||||
self.isShip=true
|
self.isShip=true
|
||||||
|
-- DCS bug: Oil rigs and gas platforms have category=2 (ship). Also they cannot be retrieved by coalition.getStaticObjects()
|
||||||
|
if self.descriptors.typeName=="Oil rig" or self.descriptors.typeName=="Ga" then
|
||||||
|
self.isHelipad=true
|
||||||
|
self.isShip=false
|
||||||
|
self.category=Airbase.Category.HELIPAD
|
||||||
|
_DATABASE:AddStatic(AirbaseName)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
self:E("ERROR: Unknown airbase category!")
|
self:E("ERROR: Unknown airbase category!")
|
||||||
end
|
end
|
||||||
@@ -558,8 +566,14 @@ function AIRBASE:Register(AirbaseName)
|
|||||||
self:GetCoordinate()
|
self:GetCoordinate()
|
||||||
|
|
||||||
if vec2 then
|
if vec2 then
|
||||||
-- TODO: For ships we need a moving zone.
|
if self.isShip then
|
||||||
self.AirbaseZone=ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
|
local unit=UNIT:FindByName(AirbaseName)
|
||||||
|
if unit then
|
||||||
|
self.AirbaseZone=ZONE_UNIT:New(AirbaseName, unit, 2500)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self.AirbaseZone=ZONE_RADIUS:New(AirbaseName, vec2, 2500)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
self:E(string.format("ERROR: Cound not get position Vec2 of airbase %s", AirbaseName))
|
self:E(string.format("ERROR: Cound not get position Vec2 of airbase %s", AirbaseName))
|
||||||
end
|
end
|
||||||
@@ -1006,10 +1020,19 @@ function AIRBASE:GetParkingSpotsTable(termtype)
|
|||||||
|
|
||||||
local spot=self:_GetParkingSpotByID(_spot.Term_Index)
|
local spot=self:_GetParkingSpotByID(_spot.Term_Index)
|
||||||
|
|
||||||
|
if spot then
|
||||||
|
|
||||||
spot.Free=_isfree(_spot) -- updated
|
spot.Free=_isfree(_spot) -- updated
|
||||||
spot.TOAC=_spot.TO_AC -- updated
|
spot.TOAC=_spot.TO_AC -- updated
|
||||||
|
|
||||||
table.insert(spots, spot)
|
table.insert(spots, spot)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
self:E(string.format("ERROR: Parking spot %s is nil!", tostring(_spot.Term_Index)))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -1084,7 +1107,7 @@ function AIRBASE:MarkParkingSpots(termtype, mark)
|
|||||||
|
|
||||||
-- Get airbase name.
|
-- Get airbase name.
|
||||||
local airbasename=self:GetName()
|
local airbasename=self:GetName()
|
||||||
self:E(string.format("Parking spots at %s for termial type %s:", airbasename, tostring(termtype)))
|
self:E(string.format("Parking spots at %s for terminal type %s:", airbasename, tostring(termtype)))
|
||||||
|
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
|
|
||||||
@@ -1161,14 +1184,25 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
|||||||
parkingdata=parkingdata or self:GetParkingSpotsTable(terminaltype)
|
parkingdata=parkingdata or self:GetParkingSpotsTable(terminaltype)
|
||||||
|
|
||||||
-- Get the aircraft size, i.e. it's longest side of x,z.
|
-- Get the aircraft size, i.e. it's longest side of x,z.
|
||||||
local aircraft=group:GetUnit(1)
|
local aircraft = nil -- fix local problem below
|
||||||
local _aircraftsize, ax,ay,az=aircraft:GetObjectSize()
|
local _aircraftsize, ax,ay,az
|
||||||
|
if group and group.ClassName == "GROUP" then
|
||||||
|
aircraft=group:GetUnit(1)
|
||||||
|
_aircraftsize, ax,ay,az=aircraft:GetObjectSize()
|
||||||
|
else
|
||||||
|
-- SU27 dimensions
|
||||||
|
_aircraftsize = 23
|
||||||
|
ax = 23 -- length
|
||||||
|
ay = 7 -- height
|
||||||
|
az = 17 -- width
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Number of spots we are looking for. Note that, e.g. grouping can require a number different from the group size!
|
-- Number of spots we are looking for. Note that, e.g. grouping can require a number different from the group size!
|
||||||
local _nspots=nspots or group:GetSize()
|
local _nspots=nspots or group:GetSize()
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:E(string.format("%s: Looking for %d parking spot(s) for aircraft of size %.1f m (x=%.1f,y=%.1f,z=%.1f) at termial type %s.", airport, _nspots, _aircraftsize, ax, ay, az, tostring(terminaltype)))
|
self:E(string.format("%s: Looking for %d parking spot(s) for aircraft of size %.1f m (x=%.1f,y=%.1f,z=%.1f) at terminal type %s.", airport, _nspots, _aircraftsize, ax, ay, az, tostring(terminaltype)))
|
||||||
|
|
||||||
-- Table of valid spots.
|
-- Table of valid spots.
|
||||||
local validspots={}
|
local validspots={}
|
||||||
@@ -1291,6 +1325,7 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
|||||||
|
|
||||||
-- Retrun spots we found, even if there were not enough.
|
-- Retrun spots we found, even if there were not enough.
|
||||||
return validspots
|
return validspots
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check black and white lists.
|
--- Check black and white lists.
|
||||||
|
|||||||
@@ -3779,8 +3779,9 @@ end
|
|||||||
-- @param #number radius Radius of the relocation zone, default 500
|
-- @param #number radius Radius of the relocation zone, default 500
|
||||||
-- @param #boolean onroad If true, route on road (less problems with AI way finding), default true
|
-- @param #boolean onroad If true, route on road (less problems with AI way finding), default true
|
||||||
-- @param #boolean shortcut If true and onroad is set, take a shorter route - if available - off road, default false
|
-- @param #boolean shortcut If true and onroad is set, take a shorter route - if available - off road, default false
|
||||||
|
-- @param #string formation Formation string as in the mission editor, e.g. "Vee", "Diamond", "Line abreast", etc. Defaults to "Off Road"
|
||||||
-- @return #CONTROLLABLE self
|
-- @return #CONTROLLABLE self
|
||||||
function CONTROLLABLE:RelocateGroundRandomInRadius(speed, radius, onroad, shortcut)
|
function CONTROLLABLE:RelocateGroundRandomInRadius(speed, radius, onroad, shortcut, formation)
|
||||||
self:F2( { self.ControllableName } )
|
self:F2( { self.ControllableName } )
|
||||||
|
|
||||||
local _coord = self:GetCoordinate()
|
local _coord = self:GetCoordinate()
|
||||||
@@ -3791,14 +3792,14 @@ function CONTROLLABLE:RelocateGroundRandomInRadius(speed, radius, onroad, shortc
|
|||||||
local _grptsk = {}
|
local _grptsk = {}
|
||||||
local _candoroad = false
|
local _candoroad = false
|
||||||
local _shortcut = shortcut or false
|
local _shortcut = shortcut or false
|
||||||
|
local _formation = formation or "Off Road"
|
||||||
|
|
||||||
-- create a DCS Task an push it on the group
|
-- create a DCS Task an push it on the group
|
||||||
-- TaskGroundOnRoad(ToCoordinate,Speed,OffRoadFormation,Shortcut,FromCoordinate,WaypointFunction,WaypointFunctionArguments)
|
|
||||||
if onroad then
|
if onroad then
|
||||||
_grptsk, _candoroad = self:TaskGroundOnRoad(_tocoord,_speed,"Off Road",_shortcut)
|
_grptsk, _candoroad = self:TaskGroundOnRoad(_tocoord,_speed,_formation,_shortcut)
|
||||||
self:Route(_grptsk,5)
|
self:Route(_grptsk,5)
|
||||||
else
|
else
|
||||||
self:TaskRouteToVec2(_tocoord:GetVec2(),_speed,"Off Road")
|
self:TaskRouteToVec2(_tocoord:GetVec2(),_speed,_formation)
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -310,8 +310,7 @@ end
|
|||||||
|
|
||||||
--- Returns the @{DCS#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission.
|
--- Returns the @{DCS#Position3} position vectors indicating the point and direction vectors in 3D of the POSITIONABLE within the mission.
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
-- @return DCS#Position The 3D position vectors of the POSITIONABLE.
|
-- @return DCS#Position The 3D position vectors of the POSITIONABLE or #nil if the groups not existing or alive.
|
||||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
|
||||||
function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3()
|
function GROUP:GetPositionVec3() -- Overridden from POSITIONABLE:GetPositionVec3()
|
||||||
self:F2( self.PositionableName )
|
self:F2( self.PositionableName )
|
||||||
|
|
||||||
@@ -339,9 +338,7 @@ end
|
|||||||
-- If the first @{Wrapper.Unit} of the group is inactive, it will return false.
|
-- If the first @{Wrapper.Unit} of the group is inactive, it will return false.
|
||||||
--
|
--
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean true if the group is alive and active.
|
-- @return #boolean `true` if the group is alive *and* active, `false` if the group is alive but inactive or `#nil` if the group does not exist anymore.
|
||||||
-- @return #boolean false if the group is alive but inactive.
|
|
||||||
-- @return #nil if the group does not exist anymore.
|
|
||||||
function GROUP:IsAlive()
|
function GROUP:IsAlive()
|
||||||
self:F2( self.GroupName )
|
self:F2( self.GroupName )
|
||||||
|
|
||||||
@@ -363,8 +360,7 @@ end
|
|||||||
|
|
||||||
--- Returns if the group is activated.
|
--- Returns if the group is activated.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #boolean true if group is activated.
|
-- @return #boolean `true` if group is activated or `#nil` The group is not existing or alive.
|
||||||
-- @return #nil The group is not existing or alive.
|
|
||||||
function GROUP:IsActive()
|
function GROUP:IsActive()
|
||||||
self:F2( self.GroupName )
|
self:F2( self.GroupName )
|
||||||
|
|
||||||
@@ -412,7 +408,6 @@ function GROUP:Destroy( GenerateEvent, delay )
|
|||||||
self:F2( self.GroupName )
|
self:F2( self.GroupName )
|
||||||
|
|
||||||
if delay and delay>0 then
|
if delay and delay>0 then
|
||||||
--SCHEDULER:New(nil, GROUP.Destroy, {self, GenerateEvent}, delay)
|
|
||||||
self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent)
|
self:ScheduleOnce(delay, GROUP.Destroy, self, GenerateEvent)
|
||||||
else
|
else
|
||||||
|
|
||||||
@@ -568,12 +563,12 @@ function GROUP:GetSpeedMax()
|
|||||||
|
|
||||||
local Units=self:GetUnits()
|
local Units=self:GetUnits()
|
||||||
|
|
||||||
local speedmax=nil
|
local speedmax=0
|
||||||
|
|
||||||
for _,unit in pairs(Units) do
|
for _,unit in pairs(Units) do
|
||||||
local unit=unit --Wrapper.Unit#UNIT
|
local unit=unit --Wrapper.Unit#UNIT
|
||||||
local speed=unit:GetSpeedMax()
|
local speed=unit:GetSpeedMax()
|
||||||
if speedmax==nil then
|
if speedmax==0 then
|
||||||
speedmax=speed
|
speedmax=speed
|
||||||
elseif speed<speedmax then
|
elseif speed<speedmax then
|
||||||
speedmax=speed
|
speedmax=speed
|
||||||
@@ -1147,6 +1142,7 @@ function GROUP:GetAmmunition()
|
|||||||
local Nshells=0
|
local Nshells=0
|
||||||
local Nrockets=0
|
local Nrockets=0
|
||||||
local Nmissiles=0
|
local Nmissiles=0
|
||||||
|
local Nbombs=0
|
||||||
|
|
||||||
if DCSControllable then
|
if DCSControllable then
|
||||||
|
|
||||||
@@ -1155,18 +1151,19 @@ function GROUP:GetAmmunition()
|
|||||||
local Unit = UnitData -- Wrapper.Unit#UNIT
|
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||||
|
|
||||||
-- Get ammo of the unit
|
-- Get ammo of the unit
|
||||||
local ntot, nshells, nrockets, nmissiles = Unit:GetAmmunition()
|
local ntot, nshells, nrockets, nbombs, nmissiles = Unit:GetAmmunition()
|
||||||
|
|
||||||
Ntot=Ntot+ntot
|
Ntot=Ntot+ntot
|
||||||
Nshells=Nshells+nshells
|
Nshells=Nshells+nshells
|
||||||
Nrockets=Nrockets+nrockets
|
Nrockets=Nrockets+nrockets
|
||||||
Nmissiles=Nmissiles+nmissiles
|
Nmissiles=Nmissiles+nmissiles
|
||||||
|
Nbombs=Nbombs+nbombs
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return Ntot, Nshells, Nrockets, Nmissiles
|
return Ntot, Nshells, Nrockets, Nbombs, Nmissiles
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -2324,41 +2321,44 @@ function GROUP:GetAttribute()
|
|||||||
local unarmedship=self:HasAttribute("Unarmed ships")
|
local unarmedship=self:HasAttribute("Unarmed ships")
|
||||||
|
|
||||||
|
|
||||||
-- Define attribute. Order is important.
|
-- Define attribute. Order of attack is important.
|
||||||
if transportplane then
|
if fighter then
|
||||||
attribute=GROUP.Attribute.AIR_TRANSPORTPLANE
|
|
||||||
elseif awacs then
|
|
||||||
attribute=GROUP.Attribute.AIR_AWACS
|
|
||||||
elseif fighter then
|
|
||||||
attribute=GROUP.Attribute.AIR_FIGHTER
|
attribute=GROUP.Attribute.AIR_FIGHTER
|
||||||
elseif bomber then
|
elseif bomber then
|
||||||
attribute=GROUP.Attribute.AIR_BOMBER
|
attribute=GROUP.Attribute.AIR_BOMBER
|
||||||
|
elseif awacs then
|
||||||
|
attribute=GROUP.Attribute.AIR_AWACS
|
||||||
|
elseif transportplane then
|
||||||
|
attribute=GROUP.Attribute.AIR_TRANSPORTPLANE
|
||||||
elseif tanker then
|
elseif tanker then
|
||||||
attribute=GROUP.Attribute.AIR_TANKER
|
attribute=GROUP.Attribute.AIR_TANKER
|
||||||
elseif transporthelo then
|
-- helos
|
||||||
attribute=GROUP.Attribute.AIR_TRANSPORTHELO
|
|
||||||
elseif attackhelicopter then
|
elseif attackhelicopter then
|
||||||
attribute=GROUP.Attribute.AIR_ATTACKHELO
|
attribute=GROUP.Attribute.AIR_ATTACKHELO
|
||||||
|
elseif transporthelo then
|
||||||
|
attribute=GROUP.Attribute.AIR_TRANSPORTHELO
|
||||||
elseif uav then
|
elseif uav then
|
||||||
attribute=GROUP.Attribute.AIR_UAV
|
attribute=GROUP.Attribute.AIR_UAV
|
||||||
elseif apc then
|
-- ground - order of attack
|
||||||
attribute=GROUP.Attribute.GROUND_APC
|
|
||||||
elseif infantry then
|
|
||||||
attribute=GROUP.Attribute.GROUND_INFANTRY
|
|
||||||
elseif artillery then
|
|
||||||
attribute=GROUP.Attribute.GROUND_ARTILLERY
|
|
||||||
elseif tank then
|
|
||||||
attribute=GROUP.Attribute.GROUND_TANK
|
|
||||||
elseif aaa then
|
|
||||||
attribute=GROUP.Attribute.GROUND_AAA
|
|
||||||
elseif ewr then
|
elseif ewr then
|
||||||
attribute=GROUP.Attribute.GROUND_EWR
|
attribute=GROUP.Attribute.GROUND_EWR
|
||||||
elseif sam then
|
elseif sam then
|
||||||
attribute=GROUP.Attribute.GROUND_SAM
|
attribute=GROUP.Attribute.GROUND_SAM
|
||||||
|
elseif aaa then
|
||||||
|
attribute=GROUP.Attribute.GROUND_AAA
|
||||||
|
elseif artillery then
|
||||||
|
attribute=GROUP.Attribute.GROUND_ARTILLERY
|
||||||
|
elseif tank then
|
||||||
|
attribute=GROUP.Attribute.GROUND_TANK
|
||||||
|
elseif apc then
|
||||||
|
attribute=GROUP.Attribute.GROUND_APC
|
||||||
|
elseif infantry then
|
||||||
|
attribute=GROUP.Attribute.GROUND_INFANTRY
|
||||||
elseif truck then
|
elseif truck then
|
||||||
attribute=GROUP.Attribute.GROUND_TRUCK
|
attribute=GROUP.Attribute.GROUND_TRUCK
|
||||||
elseif train then
|
elseif train then
|
||||||
attribute=GROUP.Attribute.GROUND_TRAIN
|
attribute=GROUP.Attribute.GROUND_TRAIN
|
||||||
|
-- ships
|
||||||
elseif aircraftcarrier then
|
elseif aircraftcarrier then
|
||||||
attribute=GROUP.Attribute.NAVAL_AIRCRAFTCARRIER
|
attribute=GROUP.Attribute.NAVAL_AIRCRAFTCARRIER
|
||||||
elseif warship then
|
elseif warship then
|
||||||
@@ -2576,8 +2576,10 @@ end
|
|||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:SetCommandInvisible(switch)
|
function GROUP:SetCommandInvisible(switch)
|
||||||
self:F2( self.GroupName )
|
self:F2( self.GroupName )
|
||||||
local switch = switch or false
|
if switch==nil then
|
||||||
local SetInvisible = {id = 'SetInvisible', params = {value = true}}
|
switch=false
|
||||||
|
end
|
||||||
|
local SetInvisible = {id = 'SetInvisible', params = {value = switch}}
|
||||||
self:SetCommand(SetInvisible)
|
self:SetCommand(SetInvisible)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
@@ -2588,12 +2590,25 @@ end
|
|||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:SetCommandImmortal(switch)
|
function GROUP:SetCommandImmortal(switch)
|
||||||
self:F2( self.GroupName )
|
self:F2( self.GroupName )
|
||||||
local switch = switch or false
|
if switch==nil then
|
||||||
local SetInvisible = {id = 'SetImmortal', params = {value = true}}
|
switch=false
|
||||||
self:SetCommand(SetInvisible)
|
end
|
||||||
|
local SetImmortal = {id = 'SetImmortal', params = {value = switch}}
|
||||||
|
self:SetCommand(SetImmortal)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get skill from Group. Effectively gets the skill from Unit 1 as the group holds no skill value.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return #string Skill String of skill name.
|
||||||
|
function GROUP:GetSkill()
|
||||||
|
self:F2( self.GroupName )
|
||||||
|
local unit = self:GetUnit(1)
|
||||||
|
local name = unit:GetName()
|
||||||
|
local skill = _DATABASE.Templates.Units[name].Template.skill or "Random"
|
||||||
|
return skill
|
||||||
|
end
|
||||||
|
|
||||||
--do -- Smoke
|
--do -- Smoke
|
||||||
--
|
--
|
||||||
----- Signal a flare at the position of the GROUP.
|
----- Signal a flare at the position of the GROUP.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -10,11 +10,8 @@
|
|||||||
--
|
--
|
||||||
-- @module Wrapper.Static
|
-- @module Wrapper.Static
|
||||||
-- @image Wrapper_Static.JPG
|
-- @image Wrapper_Static.JPG
|
||||||
|
|
||||||
|
|
||||||
--- @type STATIC
|
--- @type STATIC
|
||||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||||
|
|
||||||
--- Wrapper class to handle Static objects.
|
--- Wrapper class to handle Static objects.
|
||||||
--
|
--
|
||||||
-- Note that Statics are almost the same as Units, but they don't have a controller.
|
-- Note that Statics are almost the same as Units, but they don't have a controller.
|
||||||
@@ -40,13 +37,10 @@
|
|||||||
--
|
--
|
||||||
-- * @{#STATIC.FindByName}(): Find a STATIC instance from the _DATABASE object using a DCS Static name.
|
-- * @{#STATIC.FindByName}(): Find a STATIC instance from the _DATABASE object using a DCS Static name.
|
||||||
--
|
--
|
||||||
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil).
|
-- IMPORTANT: ONE SHOULD NEVER SANITIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil).
|
||||||
--
|
--
|
||||||
-- @field #STATIC
|
-- @field #STATIC
|
||||||
STATIC = {
|
STATIC = { ClassName = "STATIC" }
|
||||||
ClassName = "STATIC",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
--- Register a static object.
|
--- Register a static object.
|
||||||
-- @param #STATIC self
|
-- @param #STATIC self
|
||||||
@@ -58,7 +52,6 @@ function STATIC:Register( StaticName )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Finds a STATIC from the _DATABASE using a DCSStatic object.
|
--- Finds a STATIC from the _DATABASE using a DCSStatic object.
|
||||||
-- @param #STATIC self
|
-- @param #STATIC self
|
||||||
-- @param DCS#StaticObject DCSStatic An existing DCS Static object reference.
|
-- @param DCS#StaticObject DCSStatic An existing DCS Static object reference.
|
||||||
@@ -97,8 +90,9 @@ end
|
|||||||
|
|
||||||
--- Destroys the STATIC.
|
--- Destroys the STATIC.
|
||||||
-- @param #STATIC self
|
-- @param #STATIC self
|
||||||
-- @param #boolean GenerateEvent (Optional) true if you want to generate a crash or dead event for the static.
|
-- @param #boolean GenerateEvent (Optional) true to generate a crash or dead event, false to not generate any event. `nil` (default) creates a remove event.
|
||||||
-- @return #nil The DCS StaticObject is not existing or alive.
|
-- @return #nil The DCS StaticObject is not existing or alive.
|
||||||
|
--
|
||||||
-- @usage
|
-- @usage
|
||||||
-- -- Air static example: destroy the static Helicopter and generate a S_EVENT_CRASH.
|
-- -- Air static example: destroy the static Helicopter and generate a S_EVENT_CRASH.
|
||||||
-- Helicopter = STATIC:FindByName( "Helicopter" )
|
-- Helicopter = STATIC:FindByName( "Helicopter" )
|
||||||
@@ -117,7 +111,7 @@ end
|
|||||||
-- @usage
|
-- @usage
|
||||||
-- -- Destroy without event generation example.
|
-- -- Destroy without event generation example.
|
||||||
-- Ship = STATIC:FindByName( "Boat" )
|
-- Ship = STATIC:FindByName( "Boat" )
|
||||||
-- Ship:Destroy( false ) -- Don't generate an event upon destruction.
|
-- Ship:Destroy( false ) -- Don't generate any event upon destruction.
|
||||||
--
|
--
|
||||||
function STATIC:Destroy( GenerateEvent )
|
function STATIC:Destroy( GenerateEvent )
|
||||||
self:F2( self.ObjectName )
|
self:F2( self.ObjectName )
|
||||||
@@ -148,7 +142,6 @@ function STATIC:Destroy( GenerateEvent )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get DCS object of static of static.
|
--- Get DCS object of static of static.
|
||||||
-- @param #STATIC self
|
-- @param #STATIC self
|
||||||
-- @return DCS static object
|
-- @return DCS static object
|
||||||
@@ -180,7 +173,6 @@ function STATIC:GetUnits()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get threat level of static.
|
--- Get threat level of static.
|
||||||
-- @param #STATIC self
|
-- @param #STATIC self
|
||||||
-- @return #number Threat level 1.
|
-- @return #number Threat level 1.
|
||||||
@@ -194,15 +186,15 @@ end
|
|||||||
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
|
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
|
||||||
-- @param #number Heading The heading of the static respawn in degrees. Default is 0 deg.
|
-- @param #number Heading The heading of the static respawn in degrees. Default is 0 deg.
|
||||||
-- @param #number Delay Delay in seconds before the static is spawned.
|
-- @param #number Delay Delay in seconds before the static is spawned.
|
||||||
function STATIC:SpawnAt(Coordinate, Heading, Delay)
|
function STATIC:SpawnAt( Coordinate, Heading, Delay )
|
||||||
|
|
||||||
Heading=Heading or 0
|
Heading = Heading or 0
|
||||||
|
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay > 0 then
|
||||||
SCHEDULER:New(nil, self.SpawnAt, {self, Coordinate, Heading}, Delay)
|
SCHEDULER:New( nil, self.SpawnAt, { self, Coordinate, Heading }, Delay )
|
||||||
else
|
else
|
||||||
|
|
||||||
local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName)
|
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName )
|
||||||
|
|
||||||
SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName )
|
SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName )
|
||||||
|
|
||||||
@@ -211,47 +203,43 @@ function STATIC:SpawnAt(Coordinate, Heading, Delay)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Respawn the @{Wrapper.Unit} at the same location with the same properties.
|
--- Respawn the @{Wrapper.Unit} at the same location with the same properties.
|
||||||
-- This is useful to respawn a cargo after it has been destroyed.
|
-- This is useful to respawn a cargo after it has been destroyed.
|
||||||
-- @param #STATIC self
|
-- @param #STATIC self
|
||||||
-- @param DCS#country.id CountryID (Optional) The country ID used for spawning the new static. Default is same as currently.
|
-- @param DCS#country.id CountryID (Optional) The country ID used for spawning the new static. Default is same as currently.
|
||||||
-- @param #number Delay (Optional) Delay in seconds before static is respawned. Default now.
|
-- @param #number Delay (Optional) Delay in seconds before static is respawned. Default now.
|
||||||
function STATIC:ReSpawn(CountryID, Delay)
|
function STATIC:ReSpawn( CountryID, Delay )
|
||||||
|
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay > 0 then
|
||||||
SCHEDULER:New(nil, self.ReSpawn, {self, CountryID}, Delay)
|
SCHEDULER:New( nil, self.ReSpawn, { self, CountryID }, Delay )
|
||||||
else
|
else
|
||||||
|
|
||||||
CountryID=CountryID or self:GetCountry()
|
CountryID = CountryID or self:GetCountry()
|
||||||
|
|
||||||
local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, CountryID)
|
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, CountryID )
|
||||||
|
|
||||||
SpawnStatic:Spawn(nil, self.StaticName)
|
SpawnStatic:Spawn( nil, self.StaticName )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Respawn the @{Wrapper.Unit} at a defined Coordinate with an optional heading.
|
--- Respawn the @{Wrapper.Unit} at a defined Coordinate with an optional heading.
|
||||||
-- @param #STATIC self
|
-- @param #STATIC self
|
||||||
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
|
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
|
||||||
-- @param #number Heading (Optional) The heading of the static respawn in degrees. Default the current heading.
|
-- @param #number Heading (Optional) The heading of the static respawn in degrees. Default is the current heading.
|
||||||
-- @param #number Delay (Optional) Delay in seconds before static is respawned. Default now.
|
-- @param #number Delay (Optional) Delay in seconds before static is respawned. Default is now.
|
||||||
function STATIC:ReSpawnAt(Coordinate, Heading, Delay)
|
function STATIC:ReSpawnAt( Coordinate, Heading, Delay )
|
||||||
|
|
||||||
--Heading=Heading or 0
|
-- Heading=Heading or 0
|
||||||
|
|
||||||
if Delay and Delay>0 then
|
if Delay and Delay > 0 then
|
||||||
SCHEDULER:New(nil, self.ReSpawnAt, {self, Coordinate, Heading}, Delay)
|
SCHEDULER:New( nil, self.ReSpawnAt, { self, Coordinate, Heading }, Delay )
|
||||||
else
|
else
|
||||||
|
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, self:GetCountry() )
|
||||||
|
|
||||||
local SpawnStatic=SPAWNSTATIC:NewFromStatic(self.StaticName, self:GetCountry())
|
SpawnStatic:SpawnFromCoordinate( Coordinate, Heading, self.StaticName )
|
||||||
|
|
||||||
SpawnStatic:SpawnFromCoordinate(Coordinate, Heading, self.StaticName)
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -168,9 +168,6 @@ function UNIT:GetDCSObject()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Respawn the @{Wrapper.Unit} using a (tweaked) template of the parent Group.
|
--- Respawn the @{Wrapper.Unit} using a (tweaked) template of the parent Group.
|
||||||
--
|
--
|
||||||
-- This function will:
|
-- This function will:
|
||||||
@@ -263,8 +260,6 @@ function UNIT:ReSpawnAt( Coordinate, Heading )
|
|||||||
_DATABASE:Spawn( SpawnGroupTemplate )
|
_DATABASE:Spawn( SpawnGroupTemplate )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Returns if the unit is activated.
|
--- Returns if the unit is activated.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean `true` if Unit is activated. `nil` The DCS Unit is not existing or alive.
|
-- @return #boolean `true` if Unit is activated. `nil` The DCS Unit is not existing or alive.
|
||||||
@@ -301,8 +296,6 @@ function UNIT:IsAlive()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Returns the Unit's callsign - the localized string.
|
--- Returns the Unit's callsign - the localized string.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #string The Callsign of the Unit.
|
-- @return #string The Callsign of the Unit.
|
||||||
@@ -442,7 +435,7 @@ function UNIT:GetSpeedMax()
|
|||||||
return SpeedMax*3.6
|
return SpeedMax*3.6
|
||||||
end
|
end
|
||||||
|
|
||||||
return nil
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the unit's max range in meters derived from the DCS descriptors.
|
--- Returns the unit's max range in meters derived from the DCS descriptors.
|
||||||
@@ -626,8 +619,8 @@ function UNIT:GetAmmunition()
|
|||||||
-- Type name of current weapon.
|
-- Type name of current weapon.
|
||||||
local Tammo=ammotable[w]["desc"]["typeName"]
|
local Tammo=ammotable[w]["desc"]["typeName"]
|
||||||
|
|
||||||
local _weaponString = UTILS.Split(Tammo,"%.")
|
--local _weaponString = UTILS.Split(Tammo,"%.")
|
||||||
local _weaponName = _weaponString[#_weaponString]
|
--local _weaponName = _weaponString[#_weaponString]
|
||||||
|
|
||||||
-- Get the weapon category: shell=0, missile=1, rocket=2, bomb=3
|
-- Get the weapon category: shell=0, missile=1, rocket=2, bomb=3
|
||||||
local Category=ammotable[w].desc.category
|
local Category=ammotable[w].desc.category
|
||||||
@@ -656,7 +649,8 @@ function UNIT:GetAmmunition()
|
|||||||
|
|
||||||
elseif Category==Weapon.Category.MISSILE then
|
elseif Category==Weapon.Category.MISSILE then
|
||||||
|
|
||||||
-- Add up all cruise missiles (category 5)
|
|
||||||
|
-- Add up all missiles (category 5)
|
||||||
if MissileCategory==Weapon.MissileCategory.AAM then
|
if MissileCategory==Weapon.MissileCategory.AAM then
|
||||||
nmissiles=nmissiles+Nammo
|
nmissiles=nmissiles+Nammo
|
||||||
elseif MissileCategory==Weapon.MissileCategory.ANTI_SHIP then
|
elseif MissileCategory==Weapon.MissileCategory.ANTI_SHIP then
|
||||||
@@ -665,6 +659,10 @@ function UNIT:GetAmmunition()
|
|||||||
nmissiles=nmissiles+Nammo
|
nmissiles=nmissiles+Nammo
|
||||||
elseif MissileCategory==Weapon.MissileCategory.OTHER then
|
elseif MissileCategory==Weapon.MissileCategory.OTHER then
|
||||||
nmissiles=nmissiles+Nammo
|
nmissiles=nmissiles+Nammo
|
||||||
|
elseif MissileCategory==Weapon.MissileCategory.SAM then
|
||||||
|
nmissiles=nmissiles+Nammo
|
||||||
|
elseif MissileCategory==Weapon.MissileCategory.CRUISE then
|
||||||
|
nmissiles=nmissiles+Nammo
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -956,7 +954,6 @@ end
|
|||||||
-- @return #string Some text.
|
-- @return #string Some text.
|
||||||
function UNIT:GetThreatLevel()
|
function UNIT:GetThreatLevel()
|
||||||
|
|
||||||
|
|
||||||
local ThreatLevel = 0
|
local ThreatLevel = 0
|
||||||
local ThreatText = ""
|
local ThreatText = ""
|
||||||
|
|
||||||
@@ -982,7 +979,6 @@ function UNIT:GetThreatLevel()
|
|||||||
"LR SAMs"
|
"LR SAMs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if Attributes["LR SAM"] then ThreatLevel = 10
|
if Attributes["LR SAM"] then ThreatLevel = 10
|
||||||
elseif Attributes["MR SAM"] then ThreatLevel = 9
|
elseif Attributes["MR SAM"] then ThreatLevel = 9
|
||||||
elseif Attributes["SR SAM"] and
|
elseif Attributes["SR SAM"] and
|
||||||
@@ -1018,7 +1014,6 @@ function UNIT:GetThreatLevel()
|
|||||||
"Fighter"
|
"Fighter"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if Attributes["Fighters"] then ThreatLevel = 10
|
if Attributes["Fighters"] then ThreatLevel = 10
|
||||||
elseif Attributes["Multirole fighters"] then ThreatLevel = 9
|
elseif Attributes["Multirole fighters"] then ThreatLevel = 9
|
||||||
elseif Attributes["Battleplanes"] then ThreatLevel = 8
|
elseif Attributes["Battleplanes"] then ThreatLevel = 8
|
||||||
@@ -1136,12 +1131,6 @@ function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Returns if the unit is a friendly unit.
|
--- Returns if the unit is a friendly unit.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #boolean IsFriendly evaluation result.
|
-- @return #boolean IsFriendly evaluation result.
|
||||||
@@ -1426,3 +1415,13 @@ function UNIT:EnableEmission(switch)
|
|||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get skill from Unit.
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @return #string Skill String of skill name.
|
||||||
|
function UNIT:GetSkill()
|
||||||
|
self:F2( self.UnitName )
|
||||||
|
local name = self.UnitName
|
||||||
|
local skill = _DATABASE.Templates.Units[name].Template.skill or "Random"
|
||||||
|
return skill
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user