mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-14 13:18:48 +00:00
Compare commits
116 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 |
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
+1098
-436
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!
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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,12 +119,21 @@ 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.9")
|
|
||||||
|
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
|
||||||
@@ -117,8 +154,8 @@ 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:T( { range } )
|
self:T( { range } )
|
||||||
range = range or 75
|
range = range or 75
|
||||||
@@ -130,54 +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: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 } )
|
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()
|
||||||
_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
|
||||||
self:T( SEADGroupPrefix )
|
self:T( _targetgroupname, SEADGroupPrefix )
|
||||||
if string.find( _targetMimgroupName, SEADGroupPrefix, 1, true ) then
|
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
|
||||||
@@ -186,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
+5828
-6311
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+2838
-1238
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
|
||||||
|
|
||||||
|
|||||||
@@ -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