mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Updates, new classes and fixes
**AI_FORMATION** - Performance improvents. This also affects the **RESCUEHELO** class. **EVENT** - Added events when object is of category BASE. **FSM** - Removed a few tracing calls. - Updated docs. **POINT** - Added Update Vec functions to COORDINATE. - Added *overwrite* option to COORDINATE:Translate() function. - Removed second COORDINATE:Translate() function. - Optimized COORDINATE:GetClosestAirbase() function. - Added *Offset* parameter to COORDINATE:IsLOS() function. **RADIO** - Updated BEACON type and system enums. **RADIOQUEUE** - Use Vec3 instead of COORDINATE. Performance improvement. **SET** - Added some functions. **TIMER** - Added new class. Little sister of SCHEDULER class. **DCS** - Minor changes regarding docs. **ATIS** - Added "Miles.ogg", "StatuteMiles.ogg", "Zulu.ogg". **ENUMS** - Added ENUMS.Formation.Vehicle - Added ENUMS.AlarmState ** PROFILER** - Added new lua profiler. **UTILS** - Minor changes and additions. **AIRBASE** - Improved Registration. - Improved Parking spot handling. - Aded :IsAirdrome(), IsHelipad(), IsShip() functions. - Improved :GetRunwayData() for Syria airports. **CONTROLLABLE** - Fixed bug in :CommandSetFrequency() fuction (Hz vs. MHz). - Updated/fixed :TaskFAC_AttackGroup() function. **GROUP** - Added :GetThreatLevel() function. - Added :IsInZone() function to check if any unit is in the zone. **MARKER** - Added new class handling F10 markers using FSM.
This commit is contained in:
parent
38f5fd8249
commit
15cb9bec40
@ -164,7 +164,7 @@ AI_FORMATION.__Enum.ReportType = {
|
|||||||
--- MENUPARAM type
|
--- MENUPARAM type
|
||||||
-- @type MENUPARAM
|
-- @type MENUPARAM
|
||||||
-- @field #AI_FORMATION ParamSelf
|
-- @field #AI_FORMATION ParamSelf
|
||||||
-- @field #Distance ParamDistance
|
-- @field #number ParamDistance
|
||||||
-- @field #function ParamFunction
|
-- @field #function ParamFunction
|
||||||
-- @field #string ParamMessage
|
-- @field #string ParamMessage
|
||||||
|
|
||||||
@ -207,9 +207,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -222,9 +222,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationLine Trigger for AI_FORMATION
|
--- FormationLine Trigger for AI_FORMATION
|
||||||
@ -232,9 +232,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationLine Asynchronous Trigger for AI_FORMATION
|
--- FormationLine Asynchronous Trigger for AI_FORMATION
|
||||||
@ -243,9 +243,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationTrail", "*" )
|
self:AddTransition( "*", "FormationTrail", "*" )
|
||||||
@ -257,7 +257,7 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
--- FormationTrail Handler OnAfter for AI_FORMATION
|
--- FormationTrail Handler OnAfter for AI_FORMATION
|
||||||
@ -268,14 +268,14 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
|
||||||
--- FormationTrail Trigger for AI_FORMATION
|
--- FormationTrail Trigger for AI_FORMATION
|
||||||
-- @function [parent=#AI_FORMATION] FormationTrail
|
-- @function [parent=#AI_FORMATION] FormationTrail
|
||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
|
||||||
--- FormationTrail Asynchronous Trigger for AI_FORMATION
|
--- FormationTrail Asynchronous Trigger for AI_FORMATION
|
||||||
-- @function [parent=#AI_FORMATION] __FormationTrail
|
-- @function [parent=#AI_FORMATION] __FormationTrail
|
||||||
@ -283,7 +283,7 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationStack", "*" )
|
self:AddTransition( "*", "FormationStack", "*" )
|
||||||
--- FormationStack Handler OnBefore for AI_FORMATION
|
--- FormationStack Handler OnBefore for AI_FORMATION
|
||||||
@ -294,7 +294,7 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -306,7 +306,7 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationStack Trigger for AI_FORMATION
|
--- FormationStack Trigger for AI_FORMATION
|
||||||
@ -314,7 +314,7 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationStack Asynchronous Trigger for AI_FORMATION
|
--- FormationStack Asynchronous Trigger for AI_FORMATION
|
||||||
@ -323,7 +323,7 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationLeftLine", "*" )
|
self:AddTransition( "*", "FormationLeftLine", "*" )
|
||||||
@ -335,8 +335,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -348,16 +348,16 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationLeftLine Trigger for AI_FORMATION
|
--- FormationLeftLine Trigger for AI_FORMATION
|
||||||
-- @function [parent=#AI_FORMATION] FormationLeftLine
|
-- @function [parent=#AI_FORMATION] FormationLeftLine
|
||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationLeftLine Asynchronous Trigger for AI_FORMATION
|
--- FormationLeftLine Asynchronous Trigger for AI_FORMATION
|
||||||
@ -365,8 +365,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationRightLine", "*" )
|
self:AddTransition( "*", "FormationRightLine", "*" )
|
||||||
@ -378,8 +378,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -391,16 +391,16 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationRightLine Trigger for AI_FORMATION
|
--- FormationRightLine Trigger for AI_FORMATION
|
||||||
-- @function [parent=#AI_FORMATION] FormationRightLine
|
-- @function [parent=#AI_FORMATION] FormationRightLine
|
||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationRightLine Asynchronous Trigger for AI_FORMATION
|
--- FormationRightLine Asynchronous Trigger for AI_FORMATION
|
||||||
@ -408,8 +408,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationLeftWing", "*" )
|
self:AddTransition( "*", "FormationLeftWing", "*" )
|
||||||
@ -422,8 +422,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -436,8 +436,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationLeftWing Trigger for AI_FORMATION
|
--- FormationLeftWing Trigger for AI_FORMATION
|
||||||
@ -445,8 +445,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationLeftWing Asynchronous Trigger for AI_FORMATION
|
--- FormationLeftWing Asynchronous Trigger for AI_FORMATION
|
||||||
@ -455,8 +455,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationRightWing", "*" )
|
self:AddTransition( "*", "FormationRightWing", "*" )
|
||||||
@ -469,8 +469,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -483,8 +483,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationRightWing Trigger for AI_FORMATION
|
--- FormationRightWing Trigger for AI_FORMATION
|
||||||
@ -492,8 +492,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationRightWing Asynchronous Trigger for AI_FORMATION
|
--- FormationRightWing Asynchronous Trigger for AI_FORMATION
|
||||||
@ -502,8 +502,8 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationCenterWing", "*" )
|
self:AddTransition( "*", "FormationCenterWing", "*" )
|
||||||
@ -516,9 +516,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -531,9 +531,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationCenterWing Trigger for AI_FORMATION
|
--- FormationCenterWing Trigger for AI_FORMATION
|
||||||
@ -541,9 +541,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationCenterWing Asynchronous Trigger for AI_FORMATION
|
--- FormationCenterWing Asynchronous Trigger for AI_FORMATION
|
||||||
@ -552,9 +552,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationVic", "*" )
|
self:AddTransition( "*", "FormationVic", "*" )
|
||||||
@ -566,9 +566,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
|
|
||||||
@ -580,9 +580,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationVic Trigger for AI_FORMATION
|
--- FormationVic Trigger for AI_FORMATION
|
||||||
@ -590,9 +590,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
--- FormationVic Asynchronous Trigger for AI_FORMATION
|
--- FormationVic Asynchronous Trigger for AI_FORMATION
|
||||||
@ -601,9 +601,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
self:AddTransition( "*", "FormationBox", "*" )
|
self:AddTransition( "*", "FormationBox", "*" )
|
||||||
@ -615,9 +615,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @param #number ZLevels The amount of levels on the Z-axis.
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
-- @return #boolean
|
-- @return #boolean
|
||||||
@ -630,9 +630,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @param #number ZLevels The amount of levels on the Z-axis.
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
|
|
||||||
@ -641,9 +641,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @param #number ZLevels The amount of levels on the Z-axis.
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
|
|
||||||
@ -653,9 +653,9 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
-- @param #number Delay
|
-- @param #number Delay
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @param #number ZLevels The amount of levels on the Z-axis.
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
|
|
||||||
@ -704,9 +704,9 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #AI_FORMATION
|
-- @return #AI_FORMATION
|
||||||
function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, Formation ) --R2.1
|
function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, Formation ) --R2.1
|
||||||
@ -751,7 +751,7 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @return #AI_FORMATION
|
-- @return #AI_FORMATION
|
||||||
function AI_FORMATION:onafterFormationTrail( FollowGroupSet, From , Event , To, XStart, XSpace, YStart ) --R2.1
|
function AI_FORMATION:onafterFormationTrail( FollowGroupSet, From , Event , To, XStart, XSpace, YStart ) --R2.1
|
||||||
|
|
||||||
@ -769,7 +769,7 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @return #AI_FORMATION
|
-- @return #AI_FORMATION
|
||||||
function AI_FORMATION:onafterFormationStack( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace ) --R2.1
|
function AI_FORMATION:onafterFormationStack( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace ) --R2.1
|
||||||
@ -789,8 +789,8 @@ end
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #AI_FORMATION
|
-- @return #AI_FORMATION
|
||||||
function AI_FORMATION:onafterFormationLeftLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
function AI_FORMATION:onafterFormationLeftLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
||||||
@ -808,8 +808,8 @@ end
|
|||||||
-- @param #string Event
|
-- @param #string Event
|
||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #AI_FORMATION
|
-- @return #AI_FORMATION
|
||||||
function AI_FORMATION:onafterFormationRightLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
function AI_FORMATION:onafterFormationRightLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
||||||
@ -828,8 +828,8 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
function AI_FORMATION:onafterFormationLeftWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
function AI_FORMATION:onafterFormationLeftWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
||||||
|
|
||||||
@ -848,8 +848,8 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
function AI_FORMATION:onafterFormationRightWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
function AI_FORMATION:onafterFormationRightWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
||||||
|
|
||||||
@ -867,9 +867,9 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
function AI_FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
function AI_FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||||
|
|
||||||
@ -905,9 +905,9 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @return #AI_FORMATION
|
-- @return #AI_FORMATION
|
||||||
function AI_FORMATION:onafterFormationVic( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
function AI_FORMATION:onafterFormationVic( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||||
@ -924,9 +924,9 @@ end
|
|||||||
-- @param #string To
|
-- @param #string To
|
||||||
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
-- @param #number ZLevels The amount of levels on the Z-axis.
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
-- @return #AI_FORMATION
|
-- @return #AI_FORMATION
|
||||||
@ -1065,7 +1065,7 @@ end
|
|||||||
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @pram #string To The to state.
|
-- @param #string To The to state.
|
||||||
function AI_FORMATION:onafterStop(FollowGroupSet, From, Event, To) --R2.1
|
function AI_FORMATION:onafterStop(FollowGroupSet, From, Event, To) --R2.1
|
||||||
self:E("Stopping formation.")
|
self:E("Stopping formation.")
|
||||||
end
|
end
|
||||||
@ -1075,7 +1075,7 @@ end
|
|||||||
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @pram #string To The to state.
|
-- @param #string To The to state.
|
||||||
function AI_FORMATION:onbeforeFollow( FollowGroupSet, From, Event, To ) --R2.1
|
function AI_FORMATION:onbeforeFollow( FollowGroupSet, From, Event, To ) --R2.1
|
||||||
if From=="Stopped" then
|
if From=="Stopped" then
|
||||||
return false -- Deny transition.
|
return false -- Deny transition.
|
||||||
@ -1083,7 +1083,12 @@ function AI_FORMATION:onbeforeFollow( FollowGroupSet, From, Event, To ) --R2.1
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #AI_FORMATION self
|
--- Enter following state.
|
||||||
|
-- @param #AI_FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To The to state.
|
||||||
function AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
|
function AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
|
||||||
|
|
||||||
if self.FollowUnit:IsAlive() then
|
if self.FollowUnit:IsAlive() then
|
||||||
@ -1093,153 +1098,184 @@ function AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
|
|||||||
local CT1, CT2, CV1, CV2
|
local CT1, CT2, CV1, CV2
|
||||||
CT1 = ClientUnit:GetState( self, "CT1" )
|
CT1 = ClientUnit:GetState( self, "CT1" )
|
||||||
|
|
||||||
|
local CuVec3=ClientUnit:GetVec3()
|
||||||
|
|
||||||
if CT1 == nil or CT1 == 0 then
|
if CT1 == nil or CT1 == 0 then
|
||||||
ClientUnit:SetState( self, "CV1", ClientUnit:GetPointVec3() )
|
ClientUnit:SetState( self, "CV1", CuVec3)
|
||||||
ClientUnit:SetState( self, "CT1", timer.getTime() )
|
ClientUnit:SetState( self, "CT1", timer.getTime() )
|
||||||
else
|
else
|
||||||
CT1 = ClientUnit:GetState( self, "CT1" )
|
CT1 = ClientUnit:GetState( self, "CT1" )
|
||||||
CT2 = timer.getTime()
|
CT2 = timer.getTime()
|
||||||
CV1 = ClientUnit:GetState( self, "CV1" )
|
CV1 = ClientUnit:GetState( self, "CV1" )
|
||||||
CV2 = ClientUnit:GetPointVec3()
|
CV2 = CuVec3
|
||||||
|
|
||||||
ClientUnit:SetState( self, "CT1", CT2 )
|
ClientUnit:SetState( self, "CT1", CT2 )
|
||||||
ClientUnit:SetState( self, "CV1", CV2 )
|
ClientUnit:SetState( self, "CV1", CV2 )
|
||||||
end
|
end
|
||||||
|
|
||||||
FollowGroupSet:ForEachGroupAlive(
|
--FollowGroupSet:ForEachGroupAlive( bla, self, ClientUnit, CT1, CV1, CT2, CV2)
|
||||||
--- @param Wrapper.Group#GROUP FollowGroup
|
|
||||||
-- @param Wrapper.Unit#UNIT ClientUnit
|
|
||||||
function( FollowGroup, Formation, ClientUnit, CT1, CV1, CT2, CV2 )
|
|
||||||
|
|
||||||
if FollowGroup:GetState( FollowGroup, "Mode" ) == self.__Enum.Mode.Formation then
|
for _,_group in pairs(FollowGroupSet:GetSet()) do
|
||||||
|
local group=_group --Wrapper.Group#GROUP
|
||||||
self:T({Mode=FollowGroup:GetState( FollowGroup, "Mode" )})
|
if group and group:IsAlive() then
|
||||||
|
self:FollowMe(group, ClientUnit, CT1, CV1, CT2, CV2)
|
||||||
FollowGroup:OptionROTEvadeFire()
|
end
|
||||||
FollowGroup:OptionROEReturnFire()
|
end
|
||||||
|
|
||||||
local GroupUnit = FollowGroup:GetUnit( 1 )
|
|
||||||
local FollowFormation = FollowGroup:GetState( self, "FormationVec3" )
|
|
||||||
if FollowFormation then
|
|
||||||
local FollowDistance = FollowFormation.x
|
|
||||||
|
|
||||||
local GT1 = GroupUnit:GetState( self, "GT1" )
|
|
||||||
|
|
||||||
if CT1 == nil or CT1 == 0 or GT1 == nil or GT1 == 0 then
|
|
||||||
GroupUnit:SetState( self, "GV1", GroupUnit:GetPointVec3() )
|
|
||||||
GroupUnit:SetState( self, "GT1", timer.getTime() )
|
|
||||||
else
|
|
||||||
local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5
|
|
||||||
local CT = CT2 - CT1
|
|
||||||
|
|
||||||
local CS = ( 3600 / CT ) * ( CD / 1000 ) / 3.6
|
|
||||||
|
|
||||||
local CDv = { x = CV2.x - CV1.x, y = CV2.y - CV1.y, z = CV2.z - CV1.z }
|
|
||||||
local Ca = math.atan2( CDv.x, CDv.z )
|
|
||||||
|
|
||||||
local GT1 = GroupUnit:GetState( self, "GT1" )
|
|
||||||
local GT2 = timer.getTime()
|
|
||||||
local GV1 = GroupUnit:GetState( self, "GV1" )
|
|
||||||
local GV2 = GroupUnit:GetPointVec3()
|
|
||||||
GV2:AddX( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
|
||||||
GV2:AddY( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
|
||||||
GV2:AddZ( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
|
||||||
GroupUnit:SetState( self, "GT1", GT2 )
|
|
||||||
GroupUnit:SetState( self, "GV1", GV2 )
|
|
||||||
|
|
||||||
|
|
||||||
local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5
|
|
||||||
local GT = GT2 - GT1
|
|
||||||
|
|
||||||
|
|
||||||
-- Calculate the distance
|
|
||||||
local GDv = { x = GV2.x - CV1.x, y = GV2.y - CV1.y, z = GV2.z - CV1.z }
|
|
||||||
local Alpha_T = math.atan2( GDv.x, GDv.z ) - math.atan2( CDv.x, CDv.z )
|
|
||||||
local Alpha_R = ( Alpha_T < 0 ) and Alpha_T + 2 * math.pi or Alpha_T
|
|
||||||
local Position = math.cos( Alpha_R )
|
|
||||||
local GD = ( ( GDv.x )^2 + ( GDv.z )^2 ) ^ 0.5
|
|
||||||
local Distance = GD * Position + - CS * 0.5
|
|
||||||
|
|
||||||
-- Calculate the group direction vector
|
|
||||||
local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z }
|
|
||||||
|
|
||||||
-- Calculate GH2, GH2 with the same height as CV2.
|
|
||||||
local GH2 = { x = GV2.x, y = CV2.y + FollowFormation.y, z = GV2.z }
|
|
||||||
|
|
||||||
-- Calculate the angle of GV to the orthonormal plane
|
|
||||||
local alpha = math.atan2( GV.x, GV.z )
|
|
||||||
|
|
||||||
local GVx = FollowFormation.z * math.cos( Ca ) + FollowFormation.x * math.sin( Ca )
|
|
||||||
local GVz = FollowFormation.x * math.cos( Ca ) - FollowFormation.z * math.sin( Ca )
|
|
||||||
|
|
||||||
|
|
||||||
-- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2.
|
|
||||||
-- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2))
|
|
||||||
local Inclination = ( Distance + FollowFormation.x ) / 10
|
|
||||||
if Inclination < -30 then
|
|
||||||
Inclination = - 30
|
|
||||||
end
|
|
||||||
local CVI = { x = CV2.x + CS * 10 * math.sin(Ca),
|
|
||||||
y = GH2.y + Inclination, -- + FollowFormation.y,
|
|
||||||
y = GH2.y,
|
|
||||||
z = CV2.z + CS * 10 * math.cos(Ca),
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction.
|
|
||||||
local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z }
|
|
||||||
|
|
||||||
-- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s.
|
|
||||||
-- We need to calculate this vector to predict the point the escort group needs to fly to according its speed.
|
|
||||||
-- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right...
|
|
||||||
local DVu = { x = DV.x / FollowDistance, y = DV.y, z = DV.z / FollowDistance }
|
|
||||||
|
|
||||||
-- Now we can calculate the group destination vector GDV.
|
|
||||||
local GDV = { x = CVI.x, y = CVI.y, z = CVI.z }
|
|
||||||
|
|
||||||
local ADDx = FollowFormation.x * math.cos(alpha) - FollowFormation.z * math.sin(alpha)
|
|
||||||
local ADDz = FollowFormation.z * math.cos(alpha) + FollowFormation.x * math.sin(alpha)
|
|
||||||
|
|
||||||
local GDV_Formation = {
|
|
||||||
x = GDV.x - GVx,
|
|
||||||
y = GDV.y,
|
|
||||||
z = GDV.z - GVz
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.SmokeDirectionVector == true then
|
|
||||||
trigger.action.smoke( GDV, trigger.smokeColor.Green )
|
|
||||||
trigger.action.smoke( GDV_Formation, trigger.smokeColor.White )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local Time = 120
|
|
||||||
|
|
||||||
local Speed = - ( Distance + FollowFormation.x ) / Time
|
|
||||||
|
|
||||||
if Distance > -10000 then
|
|
||||||
Speed = - ( Distance + FollowFormation.x ) / 60
|
|
||||||
end
|
|
||||||
|
|
||||||
if Distance > -2500 then
|
|
||||||
Speed = - ( Distance + FollowFormation.x ) / 20
|
|
||||||
end
|
|
||||||
|
|
||||||
local GS = Speed + CS
|
|
||||||
|
|
||||||
self:F( { Distance = Distance, Speed = Speed, CS = CS, GS = GS } )
|
|
||||||
|
|
||||||
|
|
||||||
-- Now route the escort to the desired point with the desired speed.
|
|
||||||
FollowGroup:RouteToVec3( GDV_Formation, GS ) -- DCS models speed in Mps (Miles per second)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
self, ClientUnit, CT1, CV1, CT2, CV2
|
|
||||||
)
|
|
||||||
|
|
||||||
self:__Follow( -self.dtFollow )
|
self:__Follow( -self.dtFollow )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Follow me.
|
||||||
|
-- @param #AI_FORMATION self
|
||||||
|
-- @param Wrapper.Group#GROUP FollowGroup Follow group.
|
||||||
|
-- @param Wrapper.Unit#UNIT ClientUnit Client Unit.
|
||||||
|
-- @param DCS#Time CT1 Time
|
||||||
|
-- @param DCS#Vec3 CV1 Vec3
|
||||||
|
-- @param DCS#Time CT2 Time
|
||||||
|
-- @param DCS#Vec3 CV2 Vec3
|
||||||
|
function AI_FORMATION:FollowMe(FollowGroup, ClientUnit, CT1, CV1, CT2, CV2)
|
||||||
|
|
||||||
|
if FollowGroup:GetState( FollowGroup, "Mode" ) == self.__Enum.Mode.Formation then
|
||||||
|
|
||||||
|
self:T({Mode=FollowGroup:GetState( FollowGroup, "Mode" )})
|
||||||
|
|
||||||
|
FollowGroup:OptionROTEvadeFire()
|
||||||
|
FollowGroup:OptionROEReturnFire()
|
||||||
|
|
||||||
|
local GroupUnit = FollowGroup:GetUnit( 1 )
|
||||||
|
|
||||||
|
local GuVec3=GroupUnit:GetVec3()
|
||||||
|
|
||||||
|
local FollowFormation = FollowGroup:GetState( self, "FormationVec3" )
|
||||||
|
|
||||||
|
if FollowFormation then
|
||||||
|
local FollowDistance = FollowFormation.x
|
||||||
|
|
||||||
|
local GT1 = GroupUnit:GetState( self, "GT1" )
|
||||||
|
|
||||||
|
if CT1 == nil or CT1 == 0 or GT1 == nil or GT1 == 0 then
|
||||||
|
GroupUnit:SetState( self, "GV1", GuVec3)
|
||||||
|
GroupUnit:SetState( self, "GT1", timer.getTime() )
|
||||||
|
else
|
||||||
|
local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5
|
||||||
|
local CT = CT2 - CT1
|
||||||
|
|
||||||
|
local CS = ( 3600 / CT ) * ( CD / 1000 ) / 3.6
|
||||||
|
|
||||||
|
local CDv = { x = CV2.x - CV1.x, y = CV2.y - CV1.y, z = CV2.z - CV1.z }
|
||||||
|
local Ca = math.atan2( CDv.x, CDv.z )
|
||||||
|
|
||||||
|
local GT1 = GroupUnit:GetState( self, "GT1" )
|
||||||
|
local GT2 = timer.getTime()
|
||||||
|
|
||||||
|
local GV1 = GroupUnit:GetState( self, "GV1" )
|
||||||
|
local GV2 = GuVec3
|
||||||
|
|
||||||
|
--[[
|
||||||
|
GV2:AddX( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
||||||
|
GV2:AddY( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
||||||
|
GV2:AddZ( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
||||||
|
]]
|
||||||
|
|
||||||
|
GV2.x=GV2.x+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 )
|
||||||
|
GV2.y=GV2.y+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 )
|
||||||
|
GV2.z=GV2.z+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 )
|
||||||
|
|
||||||
|
|
||||||
|
GroupUnit:SetState( self, "GT1", GT2 )
|
||||||
|
GroupUnit:SetState( self, "GV1", GV2 )
|
||||||
|
|
||||||
|
|
||||||
|
local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5
|
||||||
|
local GT = GT2 - GT1
|
||||||
|
|
||||||
|
|
||||||
|
-- Calculate the distance
|
||||||
|
local GDv = { x = GV2.x - CV1.x, y = GV2.y - CV1.y, z = GV2.z - CV1.z }
|
||||||
|
local Alpha_T = math.atan2( GDv.x, GDv.z ) - math.atan2( CDv.x, CDv.z )
|
||||||
|
local Alpha_R = ( Alpha_T < 0 ) and Alpha_T + 2 * math.pi or Alpha_T
|
||||||
|
local Position = math.cos( Alpha_R )
|
||||||
|
local GD = ( ( GDv.x )^2 + ( GDv.z )^2 ) ^ 0.5
|
||||||
|
local Distance = GD * Position + - CS * 0.5
|
||||||
|
|
||||||
|
-- Calculate the group direction vector
|
||||||
|
local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z }
|
||||||
|
|
||||||
|
-- Calculate GH2, GH2 with the same height as CV2.
|
||||||
|
local GH2 = { x = GV2.x, y = CV2.y + FollowFormation.y, z = GV2.z }
|
||||||
|
|
||||||
|
-- Calculate the angle of GV to the orthonormal plane
|
||||||
|
local alpha = math.atan2( GV.x, GV.z )
|
||||||
|
|
||||||
|
local GVx = FollowFormation.z * math.cos( Ca ) + FollowFormation.x * math.sin( Ca )
|
||||||
|
local GVz = FollowFormation.x * math.cos( Ca ) - FollowFormation.z * math.sin( Ca )
|
||||||
|
|
||||||
|
|
||||||
|
-- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2.
|
||||||
|
-- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2))
|
||||||
|
local Inclination = ( Distance + FollowFormation.x ) / 10
|
||||||
|
if Inclination < -30 then
|
||||||
|
Inclination = - 30
|
||||||
|
end
|
||||||
|
|
||||||
|
local CVI = {
|
||||||
|
x = CV2.x + CS * 10 * math.sin(Ca),
|
||||||
|
y = GH2.y + Inclination, -- + FollowFormation.y,
|
||||||
|
y = GH2.y,
|
||||||
|
z = CV2.z + CS * 10 * math.cos(Ca),
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction.
|
||||||
|
local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z }
|
||||||
|
|
||||||
|
-- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s.
|
||||||
|
-- We need to calculate this vector to predict the point the escort group needs to fly to according its speed.
|
||||||
|
-- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right...
|
||||||
|
local DVu = { x = DV.x / FollowDistance, y = DV.y, z = DV.z / FollowDistance }
|
||||||
|
|
||||||
|
-- Now we can calculate the group destination vector GDV.
|
||||||
|
local GDV = { x = CVI.x, y = CVI.y, z = CVI.z }
|
||||||
|
|
||||||
|
local ADDx = FollowFormation.x * math.cos(alpha) - FollowFormation.z * math.sin(alpha)
|
||||||
|
local ADDz = FollowFormation.z * math.cos(alpha) + FollowFormation.x * math.sin(alpha)
|
||||||
|
|
||||||
|
local GDV_Formation = {
|
||||||
|
x = GDV.x - GVx,
|
||||||
|
y = GDV.y,
|
||||||
|
z = GDV.z - GVz
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Debug smoke.
|
||||||
|
if self.SmokeDirectionVector == true then
|
||||||
|
trigger.action.smoke( GDV, trigger.smokeColor.Green )
|
||||||
|
trigger.action.smoke( GDV_Formation, trigger.smokeColor.White )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local Time = 120
|
||||||
|
|
||||||
|
local Speed = - ( Distance + FollowFormation.x ) / Time
|
||||||
|
|
||||||
|
if Distance > -10000 then
|
||||||
|
Speed = - ( Distance + FollowFormation.x ) / 60
|
||||||
|
end
|
||||||
|
|
||||||
|
if Distance > -2500 then
|
||||||
|
Speed = - ( Distance + FollowFormation.x ) / 20
|
||||||
|
end
|
||||||
|
|
||||||
|
local GS = Speed + CS
|
||||||
|
|
||||||
|
--self:F( { Distance = Distance, Speed = Speed, CS = CS, GS = GS } )
|
||||||
|
|
||||||
|
-- Now route the escort to the desired point with the desired speed.
|
||||||
|
FollowGroup:RouteToVec3( GDV_Formation, GS ) -- DCS models speed in Mps (Miles per second)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
@ -26,8 +26,6 @@
|
|||||||
-- @module Core.Base
|
-- @module Core.Base
|
||||||
-- @image Core_Base.JPG
|
-- @image Core_Base.JPG
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local _TraceOnOff = true
|
local _TraceOnOff = true
|
||||||
local _TraceLevel = 1
|
local _TraceLevel = 1
|
||||||
local _TraceAll = false
|
local _TraceAll = false
|
||||||
@ -256,6 +254,8 @@ end
|
|||||||
-- @param #BASE Parent is the Parent class that the Child inherits from.
|
-- @param #BASE Parent is the Parent class that the Child inherits from.
|
||||||
-- @return #BASE Child
|
-- @return #BASE Child
|
||||||
function BASE:Inherit( Child, Parent )
|
function BASE:Inherit( Child, Parent )
|
||||||
|
|
||||||
|
-- Create child.
|
||||||
local Child = routines.utils.deepCopy( Child )
|
local Child = routines.utils.deepCopy( Child )
|
||||||
|
|
||||||
if Child ~= nil then
|
if Child ~= nil then
|
||||||
@ -271,6 +271,7 @@ function BASE:Inherit( Child, Parent )
|
|||||||
|
|
||||||
--Child:_SetDestructor()
|
--Child:_SetDestructor()
|
||||||
end
|
end
|
||||||
|
|
||||||
return Child
|
return Child
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -82,6 +82,9 @@ DATABASE = {
|
|||||||
DESTROYS = {},
|
DESTROYS = {},
|
||||||
ZONES = {},
|
ZONES = {},
|
||||||
ZONES_GOAL = {},
|
ZONES_GOAL = {},
|
||||||
|
WAREHOUSES = {},
|
||||||
|
FLIGHTGROUPS = {},
|
||||||
|
FLIGHTCONTROLS = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local _DATABASECoalition =
|
local _DATABASECoalition =
|
||||||
@ -893,31 +896,25 @@ function DATABASE:_RegisterStatics()
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #DATABASE self
|
--- Register all world airbases.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @return #DATABASE self
|
||||||
function DATABASE:_RegisterAirbases()
|
function DATABASE:_RegisterAirbases()
|
||||||
|
|
||||||
--[[
|
|
||||||
local CoalitionsData = { AirbasesRed = coalition.getAirbases( coalition.side.RED ), AirbasesBlue = coalition.getAirbases( coalition.side.BLUE ), AirbasesNeutral = coalition.getAirbases( coalition.side.NEUTRAL ) }
|
|
||||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
|
||||||
for DCSAirbaseId, DCSAirbase in pairs( CoalitionData ) do
|
|
||||||
|
|
||||||
local DCSAirbaseName = DCSAirbase:getName()
|
|
||||||
|
|
||||||
self:T( { "Register Airbase:", DCSAirbaseName, DCSAirbase:getID() } )
|
|
||||||
self:AddAirbase( DCSAirbaseName )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
]]
|
|
||||||
|
|
||||||
for DCSAirbaseId, DCSAirbase in pairs(world.getAirbases()) do
|
for DCSAirbaseId, DCSAirbase in pairs(world.getAirbases()) do
|
||||||
local DCSAirbaseName = DCSAirbase:getName()
|
|
||||||
|
|
||||||
-- This gives the incorrect value to be inserted into the airdromeID for DCS 2.5.6!
|
-- Get the airbase name.
|
||||||
local airbaseID=DCSAirbase:getID()
|
local DCSAirbaseName = DCSAirbase:getName()
|
||||||
|
|
||||||
local airbase=self:AddAirbase( DCSAirbaseName )
|
-- This gave the incorrect value to be inserted into the airdromeID for DCS 2.5.6. Is fixed now.
|
||||||
|
local airbaseID=DCSAirbase:getID()
|
||||||
|
|
||||||
|
-- Add and register airbase.
|
||||||
|
local airbase=self:AddAirbase( DCSAirbaseName )
|
||||||
|
|
||||||
|
-- Debug output.
|
||||||
|
self:I(string.format("Register Airbase: %s, getID=%d, GetID=%d (unique=%d)", DCSAirbaseName, DCSAirbase:getID(), airbase:GetID(), airbase:GetID(true)))
|
||||||
|
|
||||||
self:I(string.format("Register Airbase: %s, getID=%d, GetID=%d (unique=%d)", DCSAirbaseName, DCSAirbase:getID(), airbase:GetID(), airbase:GetID(true)))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -1252,8 +1249,44 @@ function DATABASE:SetPlayerSettings( PlayerName, Settings )
|
|||||||
self.PLAYERSETTINGS[PlayerName] = Settings
|
self.PLAYERSETTINGS[PlayerName] = Settings
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add a flight group to the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Ops.FlightGroup#FLIGHTGROUP flightgroup
|
||||||
|
function DATABASE:AddFlightGroup(flightgroup)
|
||||||
|
self:I({NewFlightGroup=flightgroup.groupname})
|
||||||
|
self.FLIGHTGROUPS[flightgroup.groupname]=flightgroup
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get a flight group from the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param #string groupname Group name of the flight group. Can also be passed as GROUP object.
|
||||||
|
-- @return Ops.FlightGroup#FLIGHTGROUP Flight group object.
|
||||||
|
function DATABASE:GetFlightGroup(groupname)
|
||||||
|
|
||||||
|
-- Get group and group name.
|
||||||
|
if type(groupname)=="string" then
|
||||||
|
else
|
||||||
|
groupname=groupname:GetName()
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.FLIGHTGROUPS[groupname]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a flight control to the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param Ops.FlightControl#FLIGHTCONTROL flightcontrol
|
||||||
|
function DATABASE:AddFlightControl(flightcontrol)
|
||||||
|
self:F2( { flightcontrol } )
|
||||||
|
self.FLIGHTCONTROLS[flightcontrol.airbasename]=flightcontrol
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get a flight control object from the data base.
|
||||||
|
-- @param #DATABASE self
|
||||||
|
-- @param #string airbasename Name of the associated airbase.
|
||||||
|
-- @return Ops.FlightControl#FLIGHTCONTROL The FLIGHTCONTROL object.s
|
||||||
|
function DATABASE:GetFlightControl(airbasename)
|
||||||
|
return self.FLIGHTCONTROLS[airbasename]
|
||||||
|
end
|
||||||
|
|
||||||
--- @param #DATABASE self
|
--- @param #DATABASE self
|
||||||
function DATABASE:_RegisterTemplates()
|
function DATABASE:_RegisterTemplates()
|
||||||
@ -1436,8 +1469,3 @@ end
|
|||||||
self.DESTROYS[Event.IniUnitName] = true
|
self.DESTROYS[Event.IniUnitName] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1001,6 +1001,16 @@ function EVENT:onEvent( Event )
|
|||||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||||
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" -- TODO: Bug fix for 2.1!
|
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" -- TODO: Bug fix for 2.1!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if Event.IniObjectCategory == Object.Category.BASE then
|
||||||
|
Event.IniDCSUnit = Event.initiator
|
||||||
|
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||||
|
Event.IniUnitName = Event.IniDCSUnitName
|
||||||
|
Event.IniUnit = AIRBASE:FindByName(Event.IniDCSUnitName)
|
||||||
|
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||||
|
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||||
|
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if Event.target then
|
if Event.target then
|
||||||
|
|||||||
@ -71,7 +71,7 @@
|
|||||||
--
|
--
|
||||||
--
|
--
|
||||||
-- ### Author: **FlightControl**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions: **funkyfranky**
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -81,6 +81,12 @@
|
|||||||
do -- FSM
|
do -- FSM
|
||||||
|
|
||||||
--- @type FSM
|
--- @type FSM
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field Core.Scheduler#SCHEDULER CallScheduler Call scheduler.
|
||||||
|
-- @field #table options Options.
|
||||||
|
-- @field #table subs Subs.
|
||||||
|
-- @field #table Scores Scores.
|
||||||
|
-- @field #string current Current state name.
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
|
||||||
@ -370,7 +376,6 @@ do -- FSM
|
|||||||
|
|
||||||
self.CallScheduler = SCHEDULER:New( self )
|
self.CallScheduler = SCHEDULER:New( self )
|
||||||
|
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -379,7 +384,6 @@ do -- 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.
|
||||||
function FSM:SetStartState( State )
|
function FSM:SetStartState( State )
|
||||||
|
|
||||||
self._StartState = State
|
self._StartState = State
|
||||||
self.current = State
|
self.current = State
|
||||||
end
|
end
|
||||||
@ -389,7 +393,6 @@ do -- FSM
|
|||||||
-- @param #FSM self
|
-- @param #FSM self
|
||||||
-- @return #string A string containing the start state.
|
-- @return #string A string containing the start state.
|
||||||
function FSM:GetStartState()
|
function FSM:GetStartState()
|
||||||
|
|
||||||
return self._StartState or {}
|
return self._StartState or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -406,6 +409,7 @@ do -- FSM
|
|||||||
Transition.Event = Event
|
Transition.Event = Event
|
||||||
Transition.To = To
|
Transition.To = To
|
||||||
|
|
||||||
|
-- Debug message.
|
||||||
self:T2( Transition )
|
self:T2( Transition )
|
||||||
|
|
||||||
self._Transitions[Transition] = Transition
|
self._Transitions[Transition] = Transition
|
||||||
@ -414,9 +418,9 @@ do -- FSM
|
|||||||
|
|
||||||
|
|
||||||
--- Returns a table of the transition rules defined within the FSM.
|
--- Returns a table of the transition rules defined within the FSM.
|
||||||
-- @return #table
|
-- @param #FSM self
|
||||||
|
-- @return #table Transitions.
|
||||||
function FSM:GetTransitions()
|
function FSM:GetTransitions()
|
||||||
|
|
||||||
return self._Transitions or {}
|
return self._Transitions or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -448,7 +452,8 @@ do -- FSM
|
|||||||
|
|
||||||
|
|
||||||
--- Returns a table of the SubFSM rules defined within the FSM.
|
--- Returns a table of the SubFSM rules defined within the FSM.
|
||||||
-- @return #table
|
-- @param #FSM self
|
||||||
|
-- @return #table Sub processes.
|
||||||
function FSM:GetProcesses()
|
function FSM:GetProcesses()
|
||||||
|
|
||||||
self:F( { Processes = self._Processes } )
|
self:F( { Processes = self._Processes } )
|
||||||
@ -480,15 +485,17 @@ do -- FSM
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Adds an End state.
|
--- Adds an End state.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string State The FSM state.
|
||||||
function FSM:AddEndState( State )
|
function FSM:AddEndState( State )
|
||||||
|
|
||||||
self._EndStates[State] = State
|
self._EndStates[State] = State
|
||||||
self.endstates[State] = State
|
self.endstates[State] = State
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the End states.
|
--- Returns the End states.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @return #table End states.
|
||||||
function FSM:GetEndStates()
|
function FSM:GetEndStates()
|
||||||
|
|
||||||
return self._EndStates or {}
|
return self._EndStates or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -532,18 +539,22 @@ do -- FSM
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a table with the scores defined.
|
--- Returns a table with the scores defined.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #table Scores.
|
||||||
function FSM:GetScores()
|
function FSM:GetScores()
|
||||||
|
|
||||||
return self._Scores or {}
|
return self._Scores or {}
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a table with the Subs defined.
|
--- Returns a table with the Subs defined.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @return #table Sub processes.
|
||||||
function FSM:GetSubs()
|
function FSM:GetSubs()
|
||||||
|
|
||||||
return self.options.subs
|
return self.options.subs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Load call backs.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #table CallBackTable Table of call backs.
|
||||||
function FSM:LoadCallBacks( CallBackTable )
|
function FSM:LoadCallBacks( CallBackTable )
|
||||||
|
|
||||||
for name, callback in pairs( CallBackTable or {} ) do
|
for name, callback in pairs( CallBackTable or {} ) do
|
||||||
@ -552,20 +563,33 @@ do -- FSM
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Event map.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #table Events Events.
|
||||||
|
-- @param #table EventStructure Event structure.
|
||||||
function FSM:_eventmap( Events, EventStructure )
|
function FSM:_eventmap( Events, EventStructure )
|
||||||
|
|
||||||
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.
|
||||||
self:T2( "Added methods: " .. Event .. ", " .. __Event )
|
self:T2( "Added methods: " .. Event .. ", " .. __Event )
|
||||||
|
|
||||||
Events[Event] = self.Events[Event] or { map = {} }
|
Events[Event] = self.Events[Event] or { map = {} }
|
||||||
self:_add_to_map( Events[Event].map, EventStructure )
|
self:_add_to_map( Events[Event].map, EventStructure )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Sub maps.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #table subs Subs.
|
||||||
|
-- @param #table sub Sub.
|
||||||
|
-- @param #string name Name.
|
||||||
function FSM:_submap( subs, sub, name )
|
function FSM:_submap( subs, sub, name )
|
||||||
--self:F( { sub = sub, name = name } )
|
|
||||||
subs[sub.From] = subs[sub.From] or {}
|
subs[sub.From] = subs[sub.From] or {}
|
||||||
subs[sub.From][sub.Event] = subs[sub.From][sub.Event] or {}
|
subs[sub.From][sub.Event] = subs[sub.From][sub.Event] or {}
|
||||||
|
|
||||||
@ -578,22 +602,24 @@ do -- FSM
|
|||||||
subs[sub.From][sub.Event][sub].ReturnEvents = sub.ReturnEvents or {} -- these events need to be given to find the correct continue event ... if none given, the processing will stop.
|
subs[sub.From][sub.Event][sub].ReturnEvents = sub.ReturnEvents or {} -- these events need to be given to find the correct continue event ... if none given, the processing will stop.
|
||||||
subs[sub.From][sub.Event][sub].name = name
|
subs[sub.From][sub.Event][sub].name = name
|
||||||
subs[sub.From][sub.Event][sub].fsmparent = self
|
subs[sub.From][sub.Event][sub].fsmparent = self
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Call handler.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string step Step "onafter", "onbefore", "onenter", "onleave".
|
||||||
|
-- @param #string trigger Trigger.
|
||||||
|
-- @param #table params Parameters.
|
||||||
|
-- @param #string EventName Event name.
|
||||||
|
-- @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))
|
||||||
|
|
||||||
local handler = step .. trigger
|
local handler = step .. trigger
|
||||||
local ErrorHandler = function( errmsg )
|
|
||||||
|
|
||||||
env.info( "Error in SCHEDULER function:" .. errmsg )
|
|
||||||
if BASE.Debug ~= nil then
|
|
||||||
env.info( BASE.Debug.traceback() )
|
|
||||||
end
|
|
||||||
|
|
||||||
return errmsg
|
|
||||||
end
|
|
||||||
if self[handler] then
|
if self[handler] then
|
||||||
|
|
||||||
|
--[[
|
||||||
if step == "onafter" or step == "OnAfter" then
|
if step == "onafter" or step == "OnAfter" then
|
||||||
self:T( ":::>" .. step .. params[2] .. " : " .. params[1] .. " >> " .. params[2] .. ">" .. step .. params[2] .. "()" .. " >> " .. params[3] )
|
self:T( ":::>" .. step .. params[2] .. " : " .. params[1] .. " >> " .. params[2] .. ">" .. step .. params[2] .. "()" .. " >> " .. params[3] )
|
||||||
elseif step == "onbefore" or step == "OnBefore" then
|
elseif step == "onbefore" or step == "OnBefore" then
|
||||||
@ -605,13 +631,32 @@ do -- FSM
|
|||||||
else
|
else
|
||||||
self:T( ":::>" .. step .. " : " .. params[1] .. " >> " .. params[2] .. " >> " .. params[3] )
|
self:T( ":::>" .. step .. " : " .. params[1] .. " >> " .. params[2] .. " >> " .. params[3] )
|
||||||
end
|
end
|
||||||
|
]]
|
||||||
|
|
||||||
self._EventSchedules[EventName] = nil
|
self._EventSchedules[EventName] = nil
|
||||||
|
|
||||||
|
-- Error handler.
|
||||||
|
local ErrorHandler = function( errmsg )
|
||||||
|
env.info( "Error in SCHEDULER function:" .. errmsg )
|
||||||
|
if BASE.Debug ~= nil then
|
||||||
|
env.info( BASE.Debug.traceback() )
|
||||||
|
end
|
||||||
|
return errmsg
|
||||||
|
end
|
||||||
|
|
||||||
|
--return self[handler](self, unpack( params ))
|
||||||
|
|
||||||
|
-- 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
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param #FSM self
|
--- Handler.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string EventName Event name.
|
||||||
|
-- @param ... Arguments.
|
||||||
function FSM._handler( self, EventName, ... )
|
function FSM._handler( self, EventName, ... )
|
||||||
|
|
||||||
local Can, To = self:can( EventName )
|
local Can, To = self:can( EventName )
|
||||||
@ -621,7 +666,11 @@ do -- FSM
|
|||||||
end
|
end
|
||||||
|
|
||||||
if Can then
|
if Can then
|
||||||
|
|
||||||
|
-- From state.
|
||||||
local From = self.current
|
local From = self.current
|
||||||
|
|
||||||
|
-- Parameters.
|
||||||
local Params = { From, EventName, To, ... }
|
local Params = { From, EventName, To, ... }
|
||||||
|
|
||||||
|
|
||||||
@ -632,8 +681,8 @@ do -- FSM
|
|||||||
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]
|
self["OnEnter".. To] then
|
||||||
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 )
|
||||||
return false
|
return false
|
||||||
@ -653,8 +702,11 @@ do -- FSM
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
local ClassName = self:GetClassName()
|
local ClassName = self:GetClassName()
|
||||||
|
|
||||||
if ClassName == "FSM" then
|
if ClassName == "FSM" then
|
||||||
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To )
|
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To )
|
||||||
end
|
end
|
||||||
@ -672,46 +724,56 @@ do -- FSM
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- New current state.
|
||||||
self.current = To
|
self.current = To
|
||||||
|
|
||||||
local execute = true
|
local execute = true
|
||||||
|
|
||||||
local subtable = self:_gosub( From, EventName )
|
local subtable = self:_gosub( From, EventName )
|
||||||
|
|
||||||
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 )
|
||||||
|
|
||||||
sub.fsm.fsmparent = self
|
sub.fsm.fsmparent = self
|
||||||
sub.fsm.ReturnEvents = sub.ReturnEvents
|
sub.fsm.ReturnEvents = sub.ReturnEvents
|
||||||
sub.fsm[sub.StartEvent]( sub.fsm )
|
sub.fsm[sub.StartEvent]( sub.fsm )
|
||||||
|
|
||||||
execute = false
|
execute = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local fsmparent, Event = self:_isendstate( To )
|
local fsmparent, Event = self:_isendstate( To )
|
||||||
|
|
||||||
if fsmparent and Event then
|
if fsmparent and Event then
|
||||||
|
|
||||||
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 )
|
||||||
|
|
||||||
execute = false
|
execute = false
|
||||||
end
|
end
|
||||||
|
|
||||||
if execute then
|
if execute then
|
||||||
self:_call_handler("onafter", EventName, Params, EventName )
|
|
||||||
self:_call_handler("OnAfter", EventName, Params, EventName )
|
|
||||||
|
|
||||||
-- only execute the call if the From state is not equal to the To state! Otherwise this function should never execute!
|
self:_call_handler("onafter", EventName, Params, EventName )
|
||||||
--if from ~= to then
|
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 )
|
||||||
--end
|
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
|
||||||
self:T( "*** FSM *** NO Transition *** " .. self.current .. " --> " .. EventName .. " --> ? " )
|
self:T( "*** FSM *** NO Transition *** " .. self.current .. " --> " .. EventName .. " --> ? " )
|
||||||
@ -720,36 +782,67 @@ do -- FSM
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Delayed transition.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string EventName Event name.
|
||||||
|
-- @return #function Function.
|
||||||
function FSM:_delayed_transition( EventName )
|
function FSM:_delayed_transition( EventName )
|
||||||
|
|
||||||
return function( self, DelaySeconds, ... )
|
return function( self, DelaySeconds, ... )
|
||||||
|
|
||||||
|
-- Debug.
|
||||||
self:T2( "Delayed Event: " .. EventName )
|
self:T2( "Delayed Event: " .. EventName )
|
||||||
|
|
||||||
local CallID = 0
|
local CallID = 0
|
||||||
if DelaySeconds ~= nil then
|
if DelaySeconds ~= nil then
|
||||||
|
|
||||||
if DelaySeconds < 0 then -- Only call the event ONCE!
|
if DelaySeconds < 0 then -- Only call the event ONCE!
|
||||||
|
|
||||||
DelaySeconds = math.abs( DelaySeconds )
|
DelaySeconds = math.abs( DelaySeconds )
|
||||||
|
|
||||||
if not self._EventSchedules[EventName] then
|
if not self._EventSchedules[EventName] then
|
||||||
|
|
||||||
|
-- Call _handler.
|
||||||
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 )
|
||||||
|
|
||||||
|
-- Set call ID.
|
||||||
self._EventSchedules[EventName] = CallID
|
self._EventSchedules[EventName] = CallID
|
||||||
|
|
||||||
|
-- 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." )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Debug.
|
||||||
self:T2( { CallID = CallID } )
|
self:T2( { CallID = CallID } )
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create transition.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string EventName Event name.
|
||||||
|
-- @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.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string ParentFrom Parent from state.
|
||||||
|
-- @param #string ParentEvent Parent event name.
|
||||||
|
-- @return #table Subs.
|
||||||
function FSM:_gosub( ParentFrom, ParentEvent )
|
function FSM:_gosub( ParentFrom, ParentEvent )
|
||||||
local fsmtable = {}
|
local fsmtable = {}
|
||||||
if self.subs[ParentFrom] and self.subs[ParentFrom][ParentEvent] then
|
if self.subs[ParentFrom] and self.subs[ParentFrom][ParentEvent] then
|
||||||
@ -760,8 +853,14 @@ do -- FSM
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Is end state.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string Current Current state name.
|
||||||
|
-- @return #table FSM parent.
|
||||||
|
-- @return #string Event name.
|
||||||
function FSM:_isendstate( Current )
|
function FSM:_isendstate( Current )
|
||||||
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
|
||||||
@ -779,8 +878,13 @@ do -- FSM
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Add to map.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #table Map Map.
|
||||||
|
-- @param #table Event Event table.
|
||||||
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
|
||||||
@ -788,33 +892,60 @@ do -- FSM
|
|||||||
Map[From] = Event.To
|
Map[From] = Event.To
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T3( { Map, Event } )
|
self:T3( { Map, Event } )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get current state.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @return #string Current FSM state.
|
||||||
function FSM:GetState()
|
function FSM:GetState()
|
||||||
return self.current
|
return self.current
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get current state.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @return #string Current FSM state.
|
||||||
function FSM:GetCurrentState()
|
function FSM:GetCurrentState()
|
||||||
return self.current
|
return self.current
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check if FSM is in state.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string State State name.
|
||||||
|
-- @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
|
||||||
|
|
||||||
|
--- Check if FSM is in state.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string State State name.
|
||||||
|
-- @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
|
||||||
|
|
||||||
|
--- Check if can do an event.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string e Event name.
|
||||||
|
-- @return #boolean If true, FSM can do the event.
|
||||||
|
-- @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['*']
|
||||||
|
|
||||||
return To ~= nil, To
|
return To ~= nil, To
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Check if cannot do an event.
|
||||||
|
-- @param #FSM self
|
||||||
|
-- @param #string e Event name.
|
||||||
|
-- @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
|
||||||
|
|||||||
@ -175,10 +175,6 @@ do -- COORDINATE
|
|||||||
-- In order to use the most optimal road system to transport vehicles, the method @{#COORDINATE.GetPathOnRoad}() will calculate
|
-- In order to use the most optimal road system to transport vehicles, the method @{#COORDINATE.GetPathOnRoad}() will calculate
|
||||||
-- the most optimal path following the road between two coordinates.
|
-- the most optimal path following the road between two coordinates.
|
||||||
--
|
--
|
||||||
--
|
|
||||||
--
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ## 8) Metric or imperial system
|
-- ## 8) Metric or imperial system
|
||||||
--
|
--
|
||||||
-- * @{#COORDINATE.IsMetric}(): Returns if the 3D point is Metric or Nautical Miles.
|
-- * @{#COORDINATE.IsMetric}(): Returns if the 3D point is Metric or Nautical Miles.
|
||||||
@ -204,23 +200,23 @@ do -- COORDINATE
|
|||||||
|
|
||||||
--- @field COORDINATE.WaypointAction
|
--- @field COORDINATE.WaypointAction
|
||||||
COORDINATE.WaypointAction = {
|
COORDINATE.WaypointAction = {
|
||||||
TurningPoint = "Turning Point",
|
TurningPoint = "Turning Point",
|
||||||
FlyoverPoint = "Fly Over Point",
|
FlyoverPoint = "Fly Over Point",
|
||||||
FromParkingArea = "From Parking Area",
|
FromParkingArea = "From Parking Area",
|
||||||
FromParkingAreaHot = "From Parking Area Hot",
|
FromParkingAreaHot = "From Parking Area Hot",
|
||||||
FromRunway = "From Runway",
|
FromRunway = "From Runway",
|
||||||
Landing = "Landing",
|
Landing = "Landing",
|
||||||
LandingReFuAr = "LandingReFuAr",
|
LandingReFuAr = "LandingReFuAr",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- @field COORDINATE.WaypointType
|
--- @field COORDINATE.WaypointType
|
||||||
COORDINATE.WaypointType = {
|
COORDINATE.WaypointType = {
|
||||||
TakeOffParking = "TakeOffParking",
|
TakeOffParking = "TakeOffParking",
|
||||||
TakeOffParkingHot = "TakeOffParkingHot",
|
TakeOffParkingHot = "TakeOffParkingHot",
|
||||||
TakeOff = "TakeOffParkingHot",
|
TakeOff = "TakeOffParkingHot",
|
||||||
TurningPoint = "Turning Point",
|
TurningPoint = "Turning Point",
|
||||||
Land = "Land",
|
Land = "Land",
|
||||||
LandingReFuAr = "LandingReFuAr",
|
LandingReFuAr = "LandingReFuAr",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -232,6 +228,7 @@ do -- COORDINATE
|
|||||||
-- @return #COORDINATE
|
-- @return #COORDINATE
|
||||||
function COORDINATE:New( x, y, z )
|
function COORDINATE:New( x, y, z )
|
||||||
|
|
||||||
|
--env.info("FF COORDINATE New")
|
||||||
local self = BASE:Inherit( self, BASE:New() ) -- #COORDINATE
|
local self = BASE:Inherit( self, BASE:New() ) -- #COORDINATE
|
||||||
self.x = x
|
self.x = x
|
||||||
self.y = y
|
self.y = y
|
||||||
@ -303,6 +300,45 @@ do -- COORDINATE
|
|||||||
return { x = self.x, y = self.z }
|
return { x = self.x, y = self.z }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Update x,y,z coordinates from a given 3D vector.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param DCS#Vec3 Vec3 The 3D vector with x,y,z components.
|
||||||
|
-- @return #COORDINATE The modified COORDINATE itself.
|
||||||
|
function COORDINATE:UpdateFromVec3(Vec3)
|
||||||
|
|
||||||
|
self.x=Vec3.x
|
||||||
|
self.y=Vec3.y
|
||||||
|
self.z=Vec3.z
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Update x,y,z coordinates from another given COORDINATE.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #COORDINATE Coordinate The coordinate with the new x,y,z positions.
|
||||||
|
-- @return #COORDINATE The modified COORDINATE itself.
|
||||||
|
function COORDINATE:UpdateFromCoordinate(Coordinate)
|
||||||
|
|
||||||
|
self.x=Coordinate.x
|
||||||
|
self.y=Coordinate.y
|
||||||
|
self.z=Coordinate.z
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Update x and z coordinates from a given 2D vector.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param DCS#Vec2 Vec2 The 2D vector with x,y components. x is overwriting COORDINATE.x while y is overwriting COORDINATE.z.
|
||||||
|
-- @return #COORDINATE The modified COORDINATE itself.
|
||||||
|
function COORDINATE:UpdateFromVec2(Vec2)
|
||||||
|
|
||||||
|
self.x=Vec2.x
|
||||||
|
self.z=Vec2.y
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns the coordinate from the latitude and longitude given in decimal degrees.
|
--- Returns the coordinate from the latitude and longitude given in decimal degrees.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #number latitude Latitude in decimal degrees.
|
-- @param #number latitude Latitude in decimal degrees.
|
||||||
@ -506,19 +542,28 @@ do -- COORDINATE
|
|||||||
-- @param DCS#Distance Distance The Distance to be added in meters.
|
-- @param DCS#Distance Distance The Distance to be added in meters.
|
||||||
-- @param DCS#Angle Angle The Angle in degrees. Defaults to 0 if not specified (nil).
|
-- @param DCS#Angle Angle The Angle in degrees. Defaults to 0 if not specified (nil).
|
||||||
-- @param #boolean Keepalt If true, keep altitude of original coordinate. Default is that the new coordinate is created at the translated land height.
|
-- @param #boolean Keepalt If true, keep altitude of original coordinate. Default is that the new coordinate is created at the translated land height.
|
||||||
-- @return Core.Point#COORDINATE The new calculated COORDINATE.
|
-- @param #boolean Overwrite If true, overwrite the original COORDINATE with the translated one. Otherwise, create a new COODINATE.
|
||||||
function COORDINATE:Translate( Distance, Angle, Keepalt )
|
-- @return #COORDINATE The new calculated COORDINATE.
|
||||||
local SX = self.x
|
function COORDINATE:Translate( Distance, Angle, Keepalt, Overwrite )
|
||||||
local SY = self.z
|
|
||||||
local Radians = (Angle or 0) / 180 * math.pi
|
|
||||||
local TX = Distance * math.cos( Radians ) + SX
|
|
||||||
local TY = Distance * math.sin( Radians ) + SY
|
|
||||||
|
|
||||||
if Keepalt then
|
-- Angle in rad.
|
||||||
return COORDINATE:NewFromVec3( { x = TX, y=self.y, z = TY } )
|
local alpha = math.rad((Angle or 0))
|
||||||
|
|
||||||
|
local x = Distance * math.cos(alpha) + self.x -- New x
|
||||||
|
local z = Distance * math.sin(alpha) + self.z -- New z
|
||||||
|
|
||||||
|
local y=Keepalt and self.y or land.getHeight({x=x, y=z})
|
||||||
|
|
||||||
|
if Overwrite then
|
||||||
|
self.x=x
|
||||||
|
self.y=y
|
||||||
|
self.z=z
|
||||||
|
return self
|
||||||
else
|
else
|
||||||
return COORDINATE:NewFromVec2( { x = TX, y = TY } )
|
--env.info("FF translate with NEW coordinate T="..timer.getTime())
|
||||||
|
return COORDINATE:New(x, y, z)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Rotate coordinate in 2D (x,z) space.
|
--- Rotate coordinate in 2D (x,z) space.
|
||||||
@ -721,12 +766,18 @@ do -- COORDINATE
|
|||||||
|
|
||||||
--- Return the 2D distance in meters between the target COORDINATE and the COORDINATE.
|
--- Return the 2D distance in meters between the target COORDINATE and the COORDINATE.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #COORDINATE TargetCoordinate The target COORDINATE.
|
-- @param #COORDINATE TargetCoordinate The target COORDINATE. Can also be a DCS#Vec3.
|
||||||
-- @return DCS#Distance Distance The distance in meters.
|
-- @return DCS#Distance Distance The distance in meters.
|
||||||
function COORDINATE:Get2DDistance( TargetCoordinate )
|
function COORDINATE:Get2DDistance( TargetCoordinate )
|
||||||
local TargetVec3 = TargetCoordinate:GetVec3()
|
|
||||||
local SourceVec3 = self:GetVec3()
|
local a={x=TargetCoordinate.x-self.x, y=0, z=TargetCoordinate.z-self.z}
|
||||||
return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
|
||||||
|
return UTILS.VecNorm(a)
|
||||||
|
|
||||||
|
--local TargetVec3 = TargetCoordinate:GetVec3()
|
||||||
|
--local SourceVec3 = self:GetVec3()
|
||||||
|
|
||||||
|
--return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the temperature in Degrees Celsius.
|
--- Returns the temperature in Degrees Celsius.
|
||||||
@ -1086,23 +1137,6 @@ do -- COORDINATE
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Add a Distance in meters from the COORDINATE horizontal plane, with the given angle, and calculate the new COORDINATE.
|
|
||||||
-- @param #COORDINATE self
|
|
||||||
-- @param DCS#Distance Distance The Distance to be added in meters.
|
|
||||||
-- @param DCS#Angle Angle The Angle in degrees.
|
|
||||||
-- @return #COORDINATE The new calculated COORDINATE.
|
|
||||||
function COORDINATE:Translate( Distance, Angle )
|
|
||||||
local SX = self.x
|
|
||||||
local SZ = self.z
|
|
||||||
local Radians = Angle / 180 * math.pi
|
|
||||||
local TX = Distance * math.cos( Radians ) + SX
|
|
||||||
local TZ = Distance * math.sin( Radians ) + SZ
|
|
||||||
|
|
||||||
return COORDINATE:New( TX, self.y, TZ )
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Build an air type route point.
|
--- Build an air type route point.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||||
@ -1290,9 +1324,11 @@ do -- COORDINATE
|
|||||||
RoutePoint.x = self.x
|
RoutePoint.x = self.x
|
||||||
RoutePoint.y = self.z
|
RoutePoint.y = self.z
|
||||||
|
|
||||||
RoutePoint.alt = self:GetLandHeight()+1 -- self.y
|
RoutePoint.alt = self:GetLandHeight()+1
|
||||||
RoutePoint.alt_type = COORDINATE.WaypointAltType.BARO
|
RoutePoint.alt_type = COORDINATE.WaypointAltType.BARO
|
||||||
|
|
||||||
|
RoutePoint.type = "Turning Point"
|
||||||
|
|
||||||
RoutePoint.action = Formation or "Off Road"
|
RoutePoint.action = Formation or "Off Road"
|
||||||
RoutePoint.formation_template=""
|
RoutePoint.formation_template=""
|
||||||
|
|
||||||
@ -1351,7 +1387,7 @@ do -- COORDINATE
|
|||||||
-- @param #number Coalition (Optional) Coalition of the airbase.
|
-- @param #number Coalition (Optional) Coalition of the airbase.
|
||||||
-- @return Wrapper.Airbase#AIRBASE Closest Airbase to the given coordinate.
|
-- @return Wrapper.Airbase#AIRBASE Closest Airbase to the given coordinate.
|
||||||
-- @return #number Distance to the closest airbase in meters.
|
-- @return #number Distance to the closest airbase in meters.
|
||||||
function COORDINATE:GetClosestAirbase(Category, Coalition)
|
function COORDINATE:GetClosestAirbase2(Category, Coalition)
|
||||||
|
|
||||||
-- Get all airbases of the map.
|
-- Get all airbases of the map.
|
||||||
local airbases=AIRBASE.GetAllAirbases(Coalition)
|
local airbases=AIRBASE.GetAllAirbases(Coalition)
|
||||||
@ -1385,6 +1421,36 @@ do -- COORDINATE
|
|||||||
return closest,distmin
|
return closest,distmin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the nearest airbase with respect to the current coordinates.
|
||||||
|
-- @param #COORDINATE self
|
||||||
|
-- @param #number Category (Optional) Category of the airbase. Enumerator of @{Wrapper.Airbase#AIRBASE.Category}.
|
||||||
|
-- @param #number Coalition (Optional) Coalition of the airbase.
|
||||||
|
-- @return Wrapper.Airbase#AIRBASE Closest Airbase to the given coordinate.
|
||||||
|
-- @return #number Distance to the closest airbase in meters.
|
||||||
|
function COORDINATE:GetClosestAirbase(Category, Coalition)
|
||||||
|
|
||||||
|
local a=self:GetVec3()
|
||||||
|
|
||||||
|
local distmin=math.huge
|
||||||
|
local airbase=nil
|
||||||
|
for DCSairbaseID, DCSairbase in pairs(world.getAirbases(Coalition)) do
|
||||||
|
local b=DCSairbase:getPoint()
|
||||||
|
|
||||||
|
local c=UTILS.VecSubstract(a,b)
|
||||||
|
local dist=UTILS.VecNorm(c)
|
||||||
|
|
||||||
|
--env.info(string.format("Airbase %s dist=%d category=%d", DCSairbase:getName(), dist, DCSairbase:getCategory()))
|
||||||
|
|
||||||
|
if dist<distmin and (Category==nil or Category==DCSairbase:getDesc().category) then
|
||||||
|
distmin=dist
|
||||||
|
airbase=DCSairbase
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return AIRBASE:Find(airbase)
|
||||||
|
end
|
||||||
|
|
||||||
--- Gets the nearest parking spot.
|
--- Gets the nearest parking spot.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param Wrapper.Airbase#AIRBASE airbase (Optional) Search only parking spots at this airbase.
|
-- @param Wrapper.Airbase#AIRBASE airbase (Optional) Search only parking spots at this airbase.
|
||||||
@ -1526,25 +1592,6 @@ do -- COORDINATE
|
|||||||
local coord=COORDINATE:NewFromVec2(_vec2)
|
local coord=COORDINATE:NewFromVec2(_vec2)
|
||||||
|
|
||||||
Path[#Path+1]=coord
|
Path[#Path+1]=coord
|
||||||
|
|
||||||
if MarkPath then
|
|
||||||
coord:MarkToAll(string.format("Path segment %d.", _i))
|
|
||||||
end
|
|
||||||
if SmokePath then
|
|
||||||
coord:SmokeGreen()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Mark/smoke endpoints
|
|
||||||
if IncludeEndpoints then
|
|
||||||
if MarkPath then
|
|
||||||
COORDINATE:NewFromVec2(path[1]):MarkToAll("Path Initinal Point")
|
|
||||||
COORDINATE:NewFromVec2(path[1]):MarkToAll("Path Final Point")
|
|
||||||
end
|
|
||||||
if SmokePath then
|
|
||||||
COORDINATE:NewFromVec2(path[1]):SmokeBlue()
|
|
||||||
COORDINATE:NewFromVec2(path[#path]):SmokeBlue()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -1557,6 +1604,23 @@ do -- COORDINATE
|
|||||||
Path[#Path+1]=ToCoord
|
Path[#Path+1]=ToCoord
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Mark or smoke.
|
||||||
|
if MarkPath or SmokePath then
|
||||||
|
for i,c in pairs(Path) do
|
||||||
|
local coord=c --#COORDINATE
|
||||||
|
if MarkPath then
|
||||||
|
coord:MarkToAll(string.format("Path segment %d", i))
|
||||||
|
end
|
||||||
|
if SmokePath then
|
||||||
|
if i==1 or i==#Path then
|
||||||
|
coord:SmokeBlue()
|
||||||
|
else
|
||||||
|
coord:SmokeGreen()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Sum up distances.
|
-- Sum up distances.
|
||||||
if #Path>=2 then
|
if #Path>=2 then
|
||||||
for i=1,#Path-1 do
|
for i=1,#Path-1 do
|
||||||
@ -1564,7 +1628,7 @@ do -- COORDINATE
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- There are cases where no path on road can be found.
|
-- There are cases where no path on road can be found.
|
||||||
return nil,nil
|
return nil,nil,false
|
||||||
end
|
end
|
||||||
|
|
||||||
return Path, Way, GotPath
|
return Path, Way, GotPath
|
||||||
@ -1921,15 +1985,18 @@ do -- COORDINATE
|
|||||||
--- Returns if a Coordinate has Line of Sight (LOS) with the ToCoordinate.
|
--- Returns if a Coordinate has Line of Sight (LOS) with the ToCoordinate.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #COORDINATE ToCoordinate
|
-- @param #COORDINATE ToCoordinate
|
||||||
|
-- @param #number Offset Height offset in meters. Default 2 m.
|
||||||
-- @return #boolean true If the ToCoordinate has LOS with the Coordinate, otherwise false.
|
-- @return #boolean true If the ToCoordinate has LOS with the Coordinate, otherwise false.
|
||||||
function COORDINATE:IsLOS( ToCoordinate )
|
function COORDINATE:IsLOS( ToCoordinate, Offset )
|
||||||
|
|
||||||
|
Offset=Offset or 2
|
||||||
|
|
||||||
-- Measurement of visibility should not be from the ground, so Adding a hypotethical 2 meters to each Coordinate.
|
-- Measurement of visibility should not be from the ground, so Adding a hypotethical 2 meters to each Coordinate.
|
||||||
local FromVec3 = self:GetVec3()
|
local FromVec3 = self:GetVec3()
|
||||||
FromVec3.y = FromVec3.y + 2
|
FromVec3.y = FromVec3.y + Offset
|
||||||
|
|
||||||
local ToVec3 = ToCoordinate:GetVec3()
|
local ToVec3 = ToCoordinate:GetVec3()
|
||||||
ToVec3.y = ToVec3.y + 2
|
ToVec3.y = ToVec3.y + Offset
|
||||||
|
|
||||||
local IsLOS = land.isVisible( FromVec3, ToVec3 )
|
local IsLOS = land.isVisible( FromVec3, ToVec3 )
|
||||||
|
|
||||||
|
|||||||
@ -429,7 +429,7 @@ BEACON = {
|
|||||||
-- @field #number VOR
|
-- @field #number VOR
|
||||||
-- @field #number DME
|
-- @field #number DME
|
||||||
-- @field #number VOR_DME
|
-- @field #number VOR_DME
|
||||||
-- @field #number TACAN
|
-- @field #number TACAN TACtical Air Navigation system.
|
||||||
-- @field #number VORTAC
|
-- @field #number VORTAC
|
||||||
-- @field #number RSBN
|
-- @field #number RSBN
|
||||||
-- @field #number BROADCAST_STATION
|
-- @field #number BROADCAST_STATION
|
||||||
@ -440,45 +440,74 @@ BEACON = {
|
|||||||
-- @field #number ILS_NEAR_HOMER
|
-- @field #number ILS_NEAR_HOMER
|
||||||
-- @field #number ILS_LOCALIZER
|
-- @field #number ILS_LOCALIZER
|
||||||
-- @field #number ILS_GLIDESLOPE
|
-- @field #number ILS_GLIDESLOPE
|
||||||
|
-- @field #number PRMG_LOCALIZER
|
||||||
|
-- @field #number PRMG_GLIDESLOPE
|
||||||
|
-- @field #number ICLS Same as ICLS glideslope.
|
||||||
|
-- @field #number ICLS_LOCALIZER
|
||||||
|
-- @field #number ICLS_GLIDESLOPE
|
||||||
-- @field #number NAUTICAL_HOMER
|
-- @field #number NAUTICAL_HOMER
|
||||||
-- @field #number ICLS
|
|
||||||
BEACON.Type={
|
BEACON.Type={
|
||||||
NULL = 0,
|
NULL = 0,
|
||||||
VOR = 1,
|
VOR = 1,
|
||||||
DME = 2,
|
DME = 2,
|
||||||
VOR_DME = 3,
|
VOR_DME = 3,
|
||||||
TACAN = 4,
|
TACAN = 4,
|
||||||
VORTAC = 5,
|
VORTAC = 5,
|
||||||
RSBN = 32,
|
RSBN = 128,
|
||||||
BROADCAST_STATION = 1024,
|
BROADCAST_STATION = 1024,
|
||||||
HOMER = 8,
|
HOMER = 8,
|
||||||
AIRPORT_HOMER = 4104,
|
AIRPORT_HOMER = 4104,
|
||||||
AIRPORT_HOMER_WITH_MARKER = 4136,
|
AIRPORT_HOMER_WITH_MARKER = 4136,
|
||||||
ILS_FAR_HOMER = 16408,
|
ILS_FAR_HOMER = 16408,
|
||||||
ILS_NEAR_HOMER = 16456,
|
ILS_NEAR_HOMER = 16424,
|
||||||
ILS_LOCALIZER = 16640,
|
ILS_LOCALIZER = 16640,
|
||||||
ILS_GLIDESLOPE = 16896,
|
ILS_GLIDESLOPE = 16896,
|
||||||
NAUTICAL_HOMER = 32776,
|
PRMG_LOCALIZER = 33024,
|
||||||
ICLS = 131584,
|
PRMG_GLIDESLOPE = 33280,
|
||||||
|
ICLS = 131584, --leaving this in here but it is the same as ICLS_GLIDESLOPE
|
||||||
|
ICLS_LOCALIZER = 131328,
|
||||||
|
ICLS_GLIDESLOPE = 131584,
|
||||||
|
NAUTICAL_HOMER = 65536,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Beacon systems supported by DCS. https://wiki.hoggitworld.com/view/DCS_command_activateBeacon
|
--- Beacon systems supported by DCS. https://wiki.hoggitworld.com/view/DCS_command_activateBeacon
|
||||||
-- @type BEACON.System
|
-- @type BEACON.System
|
||||||
-- @field #number PAR_10
|
-- @field #number PAR_10 ?
|
||||||
-- @field #number RSBN_5
|
-- @field #number RSBN_5 Russian VOR/DME system.
|
||||||
-- @field #number TACAN
|
-- @field #number TACAN TACtical Air Navigation system on ground.
|
||||||
-- @field #number TACAN_TANKER
|
-- @field #number TACAN_TANKER_X TACtical Air Navigation system for tankers on X band.
|
||||||
-- @field #number ILS_LOCALIZER (This is the one to be used for AA TACAN Tanker!)
|
-- @field #number TACAN_TANKER_Y TACtical Air Navigation system for tankers on Y band.
|
||||||
-- @field #number ILS_GLIDESLOPE
|
-- @field #number VOR Very High Frequency Omni-Directional Range
|
||||||
-- @field #number BROADCAST_STATION
|
-- @field #number ILS_LOCALIZER ILS localizer
|
||||||
|
-- @field #number ILS_GLIDESLOPE ILS glideslope.
|
||||||
|
-- @field #number PRGM_LOCALIZER PRGM localizer.
|
||||||
|
-- @field #number PRGM_GLIDESLOPE PRGM glideslope.
|
||||||
|
-- @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 TACAN_AA_MODE_X TACtical Air Navigation for aircraft on X band.
|
||||||
|
-- @field #number TACAN_AA_MODE_Y TACtical Air Navigation for aircraft on Y band.
|
||||||
|
-- @field #number VORDME Radio beacon that combines a VHF omnidirectional range (VOR) with a distance measuring equipment (DME).
|
||||||
|
-- @field #number ICLS_LOCALIZER Carrier landing system.
|
||||||
|
-- @field #number ICLS_GLIDESLOPE Carrier landing system.
|
||||||
BEACON.System={
|
BEACON.System={
|
||||||
PAR_10 = 1,
|
PAR_10 = 1,
|
||||||
RSBN_5 = 2,
|
RSBN_5 = 2,
|
||||||
TACAN = 3,
|
TACAN = 3,
|
||||||
TACAN_TANKER = 4,
|
TACAN_TANKER_X = 4,
|
||||||
ILS_LOCALIZER = 5,
|
TACAN_TANKER_Y = 5,
|
||||||
ILS_GLIDESLOPE = 6,
|
VOR = 6,
|
||||||
BROADCAST_STATION = 7,
|
ILS_LOCALIZER = 7,
|
||||||
|
ILS_GLIDESLOPE = 8,
|
||||||
|
PRMG_LOCALIZER = 9,
|
||||||
|
PRMG_GLIDESLOPE = 10,
|
||||||
|
BROADCAST_STATION = 11,
|
||||||
|
VORTAC = 12,
|
||||||
|
TACAN_AA_MODE_X = 13,
|
||||||
|
TACAN_AA_MODE_Y = 14,
|
||||||
|
VORDME = 15,
|
||||||
|
ICLS_LOCALIZER = 16,
|
||||||
|
ICLS_GLIDESLOPE = 17,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Create a new BEACON Object. This doesn't activate the beacon, though, use @{#BEACON.ActivateTACAN} etc.
|
--- Create a new BEACON Object. This doesn't activate the beacon, though, use @{#BEACON.ActivateTACAN} etc.
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
--
|
--
|
||||||
-- @type RADIOQUEUE
|
-- @type RADIOQUEUE
|
||||||
-- @field #string ClassName Name of the class "RADIOQUEUE".
|
-- @field #string ClassName Name of the class "RADIOQUEUE".
|
||||||
-- @field #boolean Debug Debug mode. More info.
|
-- @field #boolean Debugmode Debug mode. More info.
|
||||||
-- @field #string lid ID for dcs.log.
|
-- @field #string lid ID for dcs.log.
|
||||||
-- @field #number frequency The radio frequency in Hz.
|
-- @field #number frequency The radio frequency in Hz.
|
||||||
-- @field #number modulation The radio modulation. Either radio.modulation.AM or radio.modulation.FM.
|
-- @field #number modulation The radio modulation. Either radio.modulation.AM or radio.modulation.FM.
|
||||||
@ -38,7 +38,7 @@
|
|||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
RADIOQUEUE = {
|
RADIOQUEUE = {
|
||||||
ClassName = "RADIOQUEUE",
|
ClassName = "RADIOQUEUE",
|
||||||
Debug = nil,
|
Debugmode = nil,
|
||||||
lid = nil,
|
lid = nil,
|
||||||
frequency = nil,
|
frequency = nil,
|
||||||
modulation = nil,
|
modulation = nil,
|
||||||
@ -55,7 +55,7 @@ RADIOQUEUE = {
|
|||||||
power = nil,
|
power = nil,
|
||||||
numbers = {},
|
numbers = {},
|
||||||
checking = nil,
|
checking = nil,
|
||||||
schedonce = nil,
|
schedonce = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Radio queue transmission data.
|
--- Radio queue transmission data.
|
||||||
@ -375,8 +375,10 @@ function RADIOQUEUE:Broadcast(transmission)
|
|||||||
sender:SetCommand(commandTransmit)
|
sender:SetCommand(commandTransmit)
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
local text=string.format("file=%s, freq=%.2f MHz, duration=%.2f sec, subtitle=%s", filename, self.frequency/1000000, transmission.duration, transmission.subtitle or "")
|
if self.Debugmode then
|
||||||
MESSAGE:New(text, 2, "RADIOQUEUE "..self.alias):ToAllIf(self.Debug)
|
local text=string.format("file=%s, freq=%.2f MHz, duration=%.2f sec, subtitle=%s", filename, self.frequency/1000000, transmission.duration, transmission.subtitle or "")
|
||||||
|
MESSAGE:New(text, 2, "RADIOQUEUE "..self.alias):ToAll()
|
||||||
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
@ -388,10 +390,7 @@ function RADIOQUEUE:Broadcast(transmission)
|
|||||||
|
|
||||||
-- Try to get positon from sender unit/static.
|
-- Try to get positon from sender unit/static.
|
||||||
if self.sendername then
|
if self.sendername then
|
||||||
local coord=self:_GetRadioSenderCoord()
|
vec3=self:_GetRadioSenderCoord()
|
||||||
if coord then
|
|
||||||
vec3=coord:GetVec3()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Try to get fixed positon.
|
-- Try to get fixed positon.
|
||||||
@ -408,8 +407,10 @@ function RADIOQUEUE:Broadcast(transmission)
|
|||||||
trigger.action.radioTransmission(filename, vec3, self.modulation, false, self.frequency, self.power)
|
trigger.action.radioTransmission(filename, vec3, self.modulation, false, self.frequency, self.power)
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
local text=string.format("file=%s, freq=%.2f MHz, duration=%.2f sec, subtitle=%s", filename, self.frequency/1000000, transmission.duration, transmission.subtitle or "")
|
if self.Debugmode then
|
||||||
MESSAGE:New(string.format(text, filename, transmission.duration, transmission.subtitle or ""), 5, "RADIOQUEUE "..self.alias):ToAllIf(self.Debug)
|
local text=string.format("file=%s, freq=%.2f MHz, duration=%.2f sec, subtitle=%s", filename, self.frequency/1000000, transmission.duration, transmission.subtitle or "")
|
||||||
|
MESSAGE:New(string.format(text, filename, transmission.duration, transmission.subtitle or ""), 5, "RADIOQUEUE "..self.alias):ToAll()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -532,6 +533,7 @@ function RADIOQUEUE:_GetRadioSender()
|
|||||||
|
|
||||||
-- Try the general default.
|
-- Try the general default.
|
||||||
if self.sendername then
|
if self.sendername then
|
||||||
|
|
||||||
-- First try to find a unit
|
-- First try to find a unit
|
||||||
sender=UNIT:FindByName(self.sendername)
|
sender=UNIT:FindByName(self.sendername)
|
||||||
|
|
||||||
@ -547,7 +549,7 @@ end
|
|||||||
|
|
||||||
--- Get unit from which we want to transmit a radio message. This has to be an aircraft for subtitles to work.
|
--- Get unit from which we want to transmit a radio message. This has to be an aircraft for subtitles to work.
|
||||||
-- @param #RADIOQUEUE self
|
-- @param #RADIOQUEUE self
|
||||||
-- @return Core.Point#COORDINATE Coordinate of the sender unit.
|
-- @return DCS#Vec3 Vector 3D.
|
||||||
function RADIOQUEUE:_GetRadioSenderCoord()
|
function RADIOQUEUE:_GetRadioSenderCoord()
|
||||||
|
|
||||||
local vec3=nil
|
local vec3=nil
|
||||||
@ -560,7 +562,7 @@ function RADIOQUEUE:_GetRadioSenderCoord()
|
|||||||
|
|
||||||
-- Check that sender is alive and an aircraft.
|
-- Check that sender is alive and an aircraft.
|
||||||
if sender and sender:IsAlive() then
|
if sender and sender:IsAlive() then
|
||||||
return sender:GetCoordinate()
|
return sender:GetVec3()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Now try a static.
|
-- Now try a static.
|
||||||
@ -568,7 +570,7 @@ function RADIOQUEUE:_GetRadioSenderCoord()
|
|||||||
|
|
||||||
-- Check that sender is alive and an aircraft.
|
-- Check that sender is alive and an aircraft.
|
||||||
if sender then
|
if sender then
|
||||||
return sender:GetCoordinate()
|
return sender:GetVec3()
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -37,7 +37,7 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **FlightControl**
|
-- ### Author: **FlightControl**
|
||||||
-- ### Contributions:
|
-- ### Contributions: **funkyfranky**
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@ -48,9 +48,10 @@
|
|||||||
do -- SET_BASE
|
do -- SET_BASE
|
||||||
|
|
||||||
--- @type SET_BASE
|
--- @type SET_BASE
|
||||||
-- @field #table Filter
|
-- @field #table Filter Table of filters.
|
||||||
-- @field #table Set
|
-- @field #table Set Table of objects.
|
||||||
-- @field #table List
|
-- @field #table Index Table of indicies.
|
||||||
|
-- @field #table List Unused table.
|
||||||
-- @field Core.Scheduler#SCHEDULER CallScheduler
|
-- @field Core.Scheduler#SCHEDULER CallScheduler
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
@ -77,6 +78,10 @@ do -- SET_BASE
|
|||||||
Set = {},
|
Set = {},
|
||||||
List = {},
|
List = {},
|
||||||
Index = {},
|
Index = {},
|
||||||
|
Database = nil,
|
||||||
|
CallScheduler=nil,
|
||||||
|
TimeInterval=nil,
|
||||||
|
YieldInterval=nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -224,8 +229,8 @@ do -- SET_BASE
|
|||||||
|
|
||||||
--- Adds a @{Core.Base#BASE} object in the @{Core.Set#SET_BASE}, using a given ObjectName as the index.
|
--- Adds a @{Core.Base#BASE} object in the @{Core.Set#SET_BASE}, using a given ObjectName as the index.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @param #string ObjectName
|
-- @param #string ObjectName The name of the object.
|
||||||
-- @param Core.Base#BASE Object
|
-- @param Core.Base#BASE Object The object itself.
|
||||||
-- @return Core.Base#BASE The added BASE Object.
|
-- @return Core.Base#BASE The added BASE Object.
|
||||||
function SET_BASE:Add( ObjectName, Object )
|
function SET_BASE:Add( ObjectName, Object )
|
||||||
self:F2( { ObjectName = ObjectName, Object = Object } )
|
self:F2( { ObjectName = ObjectName, Object = Object } )
|
||||||
@ -234,9 +239,14 @@ do -- SET_BASE
|
|||||||
if self.Set[ObjectName] then
|
if self.Set[ObjectName] then
|
||||||
self:Remove( ObjectName, true )
|
self:Remove( ObjectName, true )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add object to set.
|
||||||
self.Set[ObjectName] = Object
|
self.Set[ObjectName] = Object
|
||||||
|
|
||||||
|
-- Add Object name to Index.
|
||||||
table.insert( self.Index, ObjectName )
|
table.insert( self.Index, ObjectName )
|
||||||
|
|
||||||
|
-- Trigger Added event.
|
||||||
self:Added( ObjectName, Object )
|
self:Added( ObjectName, Object )
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -254,6 +264,81 @@ do -- SET_BASE
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get the *union* of two sets.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param Core.Set#SET_BASE SetB Set *B*.
|
||||||
|
-- @return Core.Set#SET_BASE The union set, i.e. contains objects that are in set *A* **or** in set *B*.
|
||||||
|
function SET_BASE:GetSetUnion(SetB)
|
||||||
|
|
||||||
|
local union=SET_BASE:New()
|
||||||
|
|
||||||
|
for _,ObjectA in pairs(self.Set) do
|
||||||
|
union:AddObject(ObjectA)
|
||||||
|
end
|
||||||
|
|
||||||
|
for _,ObjectB in pairs(SetB.Set) do
|
||||||
|
union:AddObject(ObjectB)
|
||||||
|
end
|
||||||
|
|
||||||
|
return union
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the *intersection* of this set, called *A*, and another set.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param Core.Set#SET_BASE SetB Set other set, called *B*.
|
||||||
|
-- @return Core.Set#SET_BASE A set of objects that is included in set *A* **and** in set *B*.
|
||||||
|
function SET_BASE:GetSetIntersection(SetB)
|
||||||
|
|
||||||
|
local intersection=SET_BASE:New()
|
||||||
|
|
||||||
|
local union=self:GetSetUnion(SetB)
|
||||||
|
|
||||||
|
for _,Object in pairs(union.Set) do
|
||||||
|
if self:IsIncludeObject(Object) and SetB:IsIncludeObject(Object) then
|
||||||
|
intersection:AddObject(intersection)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return intersection
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the *complement* of two sets.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param Core.Set#SET_BASE SetB Set other set, called *B*.
|
||||||
|
-- @return Core.Set#SET_BASE The set of objects that are in set *B* but **not** in this set *A*.
|
||||||
|
function SET_BASE:GetSetComplement(SetB)
|
||||||
|
|
||||||
|
local complement=SET_BASE:New()
|
||||||
|
|
||||||
|
local union=self:GetSetUnion(SetA, SetB)
|
||||||
|
|
||||||
|
for _,Object in pairs(union.Set) do
|
||||||
|
if SetA:IsIncludeObject(Object) and SetB:IsIncludeObject(Object) then
|
||||||
|
intersection:Add(intersection)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return intersection
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Compare two sets.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param Core.Set#SET_BASE SetA First set.
|
||||||
|
-- @param Core.Set#SET_BASE SetB Set to be merged into first set.
|
||||||
|
-- @return Core.Set#SET_BASE The set of objects that are included in SetA and SetB.
|
||||||
|
function SET_BASE:CompareSets(SetA, SetB)
|
||||||
|
|
||||||
|
for _,ObjectB in pairs(SetB.Set) do
|
||||||
|
if SetA:IsIncludeObject(ObjectB) then
|
||||||
|
SetA:Add(ObjectB)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return SetA
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Gets a @{Core.Base#BASE} object from the @{Core.Set#SET_BASE} and derived classes, based on the Object Name.
|
--- Gets a @{Core.Base#BASE} object from the @{Core.Set#SET_BASE} and derived classes, based on the Object Name.
|
||||||
@ -712,7 +797,7 @@ do -- SET_BASE
|
|||||||
--end
|
--end
|
||||||
|
|
||||||
|
|
||||||
--- Decides whether to include the Object
|
--- Decides whether to include the Object.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @param #table Object
|
-- @param #table Object
|
||||||
-- @return #SET_BASE self
|
-- @return #SET_BASE self
|
||||||
@ -722,6 +807,16 @@ do -- SET_BASE
|
|||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Decides whether to include the Object.
|
||||||
|
-- @param #SET_BASE self
|
||||||
|
-- @param #table Object
|
||||||
|
-- @return #SET_BASE self
|
||||||
|
function SET_BASE:IsInSet(ObjectName)
|
||||||
|
self:F3( Object )
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
--- Gets a string with all the object names.
|
--- Gets a string with all the object names.
|
||||||
-- @param #SET_BASE self
|
-- @param #SET_BASE self
|
||||||
-- @return #string A string with the names of the objects.
|
-- @return #string A string with the names of the objects.
|
||||||
@ -965,7 +1060,7 @@ do -- SET_GROUP
|
|||||||
-- Note that for each unit in the group that is set, a default cargo bay limit is initialized.
|
-- Note that for each unit in the group that is set, a default cargo bay limit is initialized.
|
||||||
-- @param Core.Set#SET_GROUP self
|
-- @param Core.Set#SET_GROUP self
|
||||||
-- @param Wrapper.Group#GROUP group The group which should be added to the set.
|
-- @param Wrapper.Group#GROUP group The group which should be added to the set.
|
||||||
-- @return self
|
-- @return Core.Set#SET_GROUP self
|
||||||
function SET_GROUP:AddGroup( group )
|
function SET_GROUP:AddGroup( group )
|
||||||
|
|
||||||
self:Add( group:GetName(), group )
|
self:Add( group:GetName(), group )
|
||||||
@ -981,7 +1076,7 @@ do -- SET_GROUP
|
|||||||
--- Add GROUP(s) to SET_GROUP.
|
--- Add GROUP(s) to SET_GROUP.
|
||||||
-- @param Core.Set#SET_GROUP self
|
-- @param Core.Set#SET_GROUP self
|
||||||
-- @param #string AddGroupNames A single name or an array of GROUP names.
|
-- @param #string AddGroupNames A single name or an array of GROUP names.
|
||||||
-- @return self
|
-- @return Core.Set#SET_GROUP self
|
||||||
function SET_GROUP:AddGroupsByName( AddGroupNames )
|
function SET_GROUP:AddGroupsByName( AddGroupNames )
|
||||||
|
|
||||||
local AddGroupNamesArray = ( type( AddGroupNames ) == "table" ) and AddGroupNames or { AddGroupNames }
|
local AddGroupNamesArray = ( type( AddGroupNames ) == "table" ) and AddGroupNames or { AddGroupNames }
|
||||||
@ -996,7 +1091,7 @@ do -- SET_GROUP
|
|||||||
--- Remove GROUP(s) from SET_GROUP.
|
--- Remove GROUP(s) from SET_GROUP.
|
||||||
-- @param Core.Set#SET_GROUP self
|
-- @param Core.Set#SET_GROUP self
|
||||||
-- @param Wrapper.Group#GROUP RemoveGroupNames A single name or an array of GROUP names.
|
-- @param Wrapper.Group#GROUP RemoveGroupNames A single name or an array of GROUP names.
|
||||||
-- @return self
|
-- @return Core.Set#SET_GROUP self
|
||||||
function SET_GROUP:RemoveGroupsByName( RemoveGroupNames )
|
function SET_GROUP:RemoveGroupsByName( RemoveGroupNames )
|
||||||
|
|
||||||
local RemoveGroupNamesArray = ( type( RemoveGroupNames ) == "table" ) and RemoveGroupNames or { RemoveGroupNames }
|
local RemoveGroupNamesArray = ( type( RemoveGroupNames ) == "table" ) and RemoveGroupNames or { RemoveGroupNames }
|
||||||
@ -1909,8 +2004,8 @@ do -- SET_UNIT
|
|||||||
|
|
||||||
--- Remove UNIT(s) from SET_UNIT.
|
--- Remove UNIT(s) from SET_UNIT.
|
||||||
-- @param Core.Set#SET_UNIT self
|
-- @param Core.Set#SET_UNIT self
|
||||||
-- @param Wrapper.Unit#UNIT RemoveUnitNames A single name or an array of UNIT names.
|
-- @param #table RemoveUnitNames A single name or an array of UNIT names.
|
||||||
-- @return self
|
-- @return Core.Set#SET_UNIT self
|
||||||
function SET_UNIT:RemoveUnitsByName( RemoveUnitNames )
|
function SET_UNIT:RemoveUnitsByName( RemoveUnitNames )
|
||||||
|
|
||||||
local RemoveUnitNamesArray = ( type( RemoveUnitNames ) == "table" ) and RemoveUnitNames or { RemoveUnitNames }
|
local RemoveUnitNamesArray = ( type( RemoveUnitNames ) == "table" ) and RemoveUnitNames or { RemoveUnitNames }
|
||||||
@ -2080,7 +2175,23 @@ do -- SET_UNIT
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Iterate the SET_UNIT and count how many UNITs are alive.
|
||||||
|
-- @param #SET_UNIT self
|
||||||
|
-- @return #number The number of UNITs alive.
|
||||||
|
function SET_UNIT:CountAlive()
|
||||||
|
|
||||||
|
local Set = self:GetSet()
|
||||||
|
|
||||||
|
local CountU = 0
|
||||||
|
for UnitID, UnitData in pairs(Set) do -- For each GROUP in SET_GROUP
|
||||||
|
if UnitData and UnitData:IsAlive() then
|
||||||
|
CountU = CountU + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return CountU
|
||||||
|
end
|
||||||
|
|
||||||
--- Starts the filtering.
|
--- Starts the filtering.
|
||||||
-- @param #SET_UNIT self
|
-- @param #SET_UNIT self
|
||||||
@ -3099,6 +3210,24 @@ do -- SET_STATIC
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Iterate the SET_STATIC and count how many STATICSs are alive.
|
||||||
|
-- @param #SET_STATIC self
|
||||||
|
-- @return #number The number of UNITs alive.
|
||||||
|
function SET_STATIC:CountAlive()
|
||||||
|
|
||||||
|
local Set = self:GetSet()
|
||||||
|
|
||||||
|
local CountU = 0
|
||||||
|
for UnitID, UnitData in pairs(Set) do
|
||||||
|
if UnitData and UnitData:IsAlive() then
|
||||||
|
CountU = CountU + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return CountU
|
||||||
|
end
|
||||||
|
|
||||||
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
||||||
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
||||||
-- @param #SET_STATIC self
|
-- @param #SET_STATIC self
|
||||||
|
|||||||
250
Moose Development/Moose/Core/Timer.lua
Normal file
250
Moose Development/Moose/Core/Timer.lua
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
--- **Core** - Timer scheduler.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Delay function calls
|
||||||
|
-- * Easy set up and little overhead
|
||||||
|
-- * Set start, stop and time interval
|
||||||
|
-- * Define max function calls
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **funkyfranky**
|
||||||
|
-- @module Core.Timer
|
||||||
|
-- @image CORE_Timer.png
|
||||||
|
|
||||||
|
|
||||||
|
--- TIMER class.
|
||||||
|
-- @type TIMER
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #string lid Class id string for output to DCS log file.
|
||||||
|
-- @field #number tid Timer ID returned by the DCS API function.
|
||||||
|
-- @field #function func Timer function.
|
||||||
|
-- @field #table para Parameters passed to the timer function.
|
||||||
|
-- @field #number Tstart Relative start time in seconds.
|
||||||
|
-- @field #number Tstop Relative stop time in seconds.
|
||||||
|
-- @field #number dT Time interval between function calls in seconds.
|
||||||
|
-- @field #number ncalls Counter of function calls.
|
||||||
|
-- @field #number ncallsMax Max number of function calls. If reached, timer is stopped.
|
||||||
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
|
--- *Better three hours too soon than a minute too late.* – William Shakespeare
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- # The TIMER Concept
|
||||||
|
--
|
||||||
|
-- The TIMER class is the little sister of the SCHEDULER class. It does the same thing but is a bit easier to use and has less overhead. It should be sufficient in many cases.
|
||||||
|
--
|
||||||
|
-- # Construction
|
||||||
|
--
|
||||||
|
-- A new TIMER is created by the @{#TIMER.New}(*func*, *...*) function
|
||||||
|
--
|
||||||
|
-- local mytimer=TIMER:New(myfunction, a, b)
|
||||||
|
--
|
||||||
|
-- The first parameter *func* is the function that is called followed by the necessary comma separeted parameters that are passed to that function.
|
||||||
|
--
|
||||||
|
-- ## Starting the Timer
|
||||||
|
--
|
||||||
|
-- The timer is started by the @{#TIMER.Start}(*Tstart*, *dT*, *Duration*) function
|
||||||
|
--
|
||||||
|
-- mytimer:Start(5, 1, 20)
|
||||||
|
--
|
||||||
|
-- where
|
||||||
|
--
|
||||||
|
-- * *Tstart* is the relative start time in seconds. In the example, the first function call happens after 5 sec.
|
||||||
|
-- * *dT* is the time interval between function calls in seconds. Above, the function is called once per second.
|
||||||
|
-- * *Duration* is the duration in seconds after which the timer is stopped. This is relative to the start time. Here, the timer will run for 20 seconds.
|
||||||
|
--
|
||||||
|
-- Note that
|
||||||
|
--
|
||||||
|
-- * if *Tstart* is not specified (*nil*), the first function call happens immediately.
|
||||||
|
-- * if *dT* is not specified (*nil*), the function is called only once.
|
||||||
|
-- * if *Duration* is not specified (*nil*), the timer runs forever or until stopped manually or until the max function calls are reached (see below).
|
||||||
|
--
|
||||||
|
-- For example,
|
||||||
|
--
|
||||||
|
-- mytimer:Start(3) -- Will call the function once after 3 seconds.
|
||||||
|
-- mytimer:Start(nil, 0.5) -- Will call right now and then every 0.5 sec until all eternaty.
|
||||||
|
-- mytimer:Start(nil, 2.0, 20) -- Will call right now and then every 2.0 sec for 20 sec.
|
||||||
|
-- mytimer:Start(1.0, nil, 10) -- Does not make sense as the function is only called once anyway.
|
||||||
|
--
|
||||||
|
-- ## Stopping the Timer
|
||||||
|
--
|
||||||
|
-- The timer can be stopped manually by the @{#TIMER.Start}(*Delay*) function
|
||||||
|
--
|
||||||
|
-- mytimer:Stop()
|
||||||
|
--
|
||||||
|
-- If the optional paramter *Delay* is specified, the timer is stopped after *delay* seconds.
|
||||||
|
--
|
||||||
|
-- ## Limit Function Calls
|
||||||
|
--
|
||||||
|
-- The timer can be stopped after a certain amount of function calles with the @{#TIMER.SetMaxFunctionCalls}(*Nmax*) function
|
||||||
|
--
|
||||||
|
-- mytimer:SetMaxFunctionCalls(20)
|
||||||
|
--
|
||||||
|
-- where *Nmax* is the number of calls after which the timer is stopped, here 20.
|
||||||
|
--
|
||||||
|
-- For example,
|
||||||
|
--
|
||||||
|
-- mytimer:SetMaxFunctionCalls(66):Start(1.0, 0.1)
|
||||||
|
--
|
||||||
|
-- will start the timer after one second and call the function every 0.1 seconds. Once the function has been called 66 times, the timer is stopped.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- @field #TIMER
|
||||||
|
TIMER = {
|
||||||
|
ClassName = "TIMER",
|
||||||
|
lid = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- TIMER class version.
|
||||||
|
-- @field #string version
|
||||||
|
TIMER.version="0.1.0"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- TODO list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: A lot.
|
||||||
|
-- TODO: Write docs.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new TIMER object.
|
||||||
|
-- @param #TIMER self
|
||||||
|
-- @param #function Function The function to call.
|
||||||
|
-- @param ... Parameters passed to the function if any.
|
||||||
|
-- @return #TIMER self
|
||||||
|
function TIMER:New(Function, ...)
|
||||||
|
|
||||||
|
-- Inherit BASE.
|
||||||
|
local self=BASE:Inherit(self, BASE:New()) --#TIMER
|
||||||
|
|
||||||
|
self.lid="TIMER | "
|
||||||
|
|
||||||
|
-- Function to call.
|
||||||
|
self.func=Function
|
||||||
|
|
||||||
|
-- Function arguments.
|
||||||
|
self.para=arg or {}
|
||||||
|
|
||||||
|
-- Number of function calls.
|
||||||
|
self.ncalls=0
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Create a new TIMER object.
|
||||||
|
-- @param #TIMER self
|
||||||
|
-- @param #number Tstart Relative start time in seconds.
|
||||||
|
-- @param #number dT Interval between function calls in seconds. If not specified `nil`, the function is called only once.
|
||||||
|
-- @param #number Duration Time in seconds for how long the timer is running. If not specified `nil`, the timer runs forever or until stopped manually by the `TIMER:Stop()` function.
|
||||||
|
-- @return #TIMER self
|
||||||
|
function TIMER:Start(Tstart, dT, Duration)
|
||||||
|
|
||||||
|
-- Current time.
|
||||||
|
local Tnow=timer.getTime()
|
||||||
|
|
||||||
|
-- Start time in sec.
|
||||||
|
self.Tstart=Tstart or Tnow
|
||||||
|
|
||||||
|
-- Set time interval.
|
||||||
|
self.dT=dT
|
||||||
|
|
||||||
|
-- Stop time.
|
||||||
|
if Duration then
|
||||||
|
self.Tstop=self.Tstart+Duration
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Call DCS timer function.
|
||||||
|
self.tid=timer.scheduleFunction(TIMER._Function, self, self.Tstart)
|
||||||
|
|
||||||
|
-- Set log id.
|
||||||
|
self.lid=string.format("TIMER ID=%d | ", self.tid)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("Starting Timer in %.3f sec, dT=%s, Tstop=%s", self.Tstart-Tnow, tostring(self.dT), tostring(self.Tstop)))
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Stop the timer by removing the timer function.
|
||||||
|
-- @param #TIMER self
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the timer is stopped.
|
||||||
|
-- @return #TIMER self
|
||||||
|
function TIMER:Stop(Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
|
||||||
|
self.Tstop=timer.getTime()+Delay
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if self.tid then
|
||||||
|
self:T(self.lid..string.format("Stopping timer by removing timer function after %d calls!", self.ncalls))
|
||||||
|
timer.removeFunction(self.tid)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set max number of function calls. When the function has been called this many times, the TIMER is stopped.
|
||||||
|
-- @param #TIMER self
|
||||||
|
-- @param #number Nmax Set number of max function calls.
|
||||||
|
-- @return #TIMER self
|
||||||
|
function TIMER:SetMaxFunctionCalls(Nmax)
|
||||||
|
self.ncallsMax=Nmax
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Call timer function.
|
||||||
|
-- @param #TIMER self
|
||||||
|
-- @param #number time DCS model time in seconds.
|
||||||
|
-- @return #number Time when the function is called again or `nil` if the timer is stopped.
|
||||||
|
function TIMER:_Function(time)
|
||||||
|
|
||||||
|
-- Call function.
|
||||||
|
self.func(unpack(self.para))
|
||||||
|
|
||||||
|
-- Increase number of calls.
|
||||||
|
self.ncalls=self.ncalls+1
|
||||||
|
|
||||||
|
-- Next time.
|
||||||
|
local Tnext=self.dT and time+self.dT or nil
|
||||||
|
|
||||||
|
-- Check if we stop the timer.
|
||||||
|
local stopme=false
|
||||||
|
if Tnext==nil then
|
||||||
|
-- No next time.
|
||||||
|
self:T(self.lid..string.format("No next time as dT=nil ==> Stopping timer after %d function calls", self.ncalls))
|
||||||
|
stopme=true
|
||||||
|
elseif self.Tstop and Tnext>self.Tstop then
|
||||||
|
-- Stop time passed.
|
||||||
|
self:T(self.lid..string.format("Stop time passed %.3f > %.3f ==> Stopping timer after %d function calls", Tnext, self.Tstop, self.ncalls))
|
||||||
|
stopme=true
|
||||||
|
elseif self.ncallsMax and self.ncalls>=self.ncallsMax then
|
||||||
|
-- Number of max function calls reached.
|
||||||
|
self:T(self.lid..string.format("Max function calls Nmax=%d reached ==> Stopping timer after %d function calls", self.ncallsMax, self.ncalls))
|
||||||
|
stopme=true
|
||||||
|
end
|
||||||
|
|
||||||
|
if stopme then
|
||||||
|
-- Remove timer function.
|
||||||
|
self:Stop()
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
-- Call again in Tnext seconds.
|
||||||
|
return Tnext
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -96,6 +96,11 @@ do -- world
|
|||||||
-- @function [parent=#world] getMarkPanels
|
-- @function [parent=#world] getMarkPanels
|
||||||
-- @return #table Table of marks.
|
-- @return #table Table of marks.
|
||||||
|
|
||||||
|
--- Returns a table of DCS airbase objects.
|
||||||
|
-- @function [parent=#world] getAirbases
|
||||||
|
-- @param #number coalitionId The coalition side number ID. Default is all airbases are returned.
|
||||||
|
-- @return #table Table of DCS airbase objects.
|
||||||
|
|
||||||
end -- world
|
end -- world
|
||||||
|
|
||||||
|
|
||||||
@ -360,7 +365,7 @@ do -- Types
|
|||||||
|
|
||||||
--- Time is given in seconds.
|
--- Time is given in seconds.
|
||||||
-- @type Time
|
-- @type Time
|
||||||
-- @extends #number
|
-- @extends #number Time in seconds.
|
||||||
|
|
||||||
--- Model time is the time that drives the simulation. Model time may be stopped, accelerated and decelerated relative real time.
|
--- Model time is the time that drives the simulation. Model time may be stopped, accelerated and decelerated relative real time.
|
||||||
-- @type ModelTime
|
-- @type ModelTime
|
||||||
@ -368,20 +373,20 @@ do -- Types
|
|||||||
|
|
||||||
--- Mission time is a model time plus time of the mission start.
|
--- Mission time is a model time plus time of the mission start.
|
||||||
-- @type MissionTime
|
-- @type MissionTime
|
||||||
-- @extends #number
|
-- @extends #number Time in seconds.
|
||||||
|
|
||||||
|
|
||||||
--- Distance is given in meters.
|
--- Distance is given in meters.
|
||||||
-- @type Distance
|
-- @type Distance
|
||||||
-- @extends #number
|
-- @extends #number Distance in meters.
|
||||||
|
|
||||||
--- Angle is given in radians.
|
--- Angle is given in radians.
|
||||||
-- @type Angle
|
-- @type Angle
|
||||||
-- @extends #number
|
-- @extends #number Angle in radians.
|
||||||
|
|
||||||
--- Azimuth is an angle of rotation around world axis y counter-clockwise.
|
--- Azimuth is an angle of rotation around world axis y counter-clockwise.
|
||||||
-- @type Azimuth
|
-- @type Azimuth
|
||||||
-- @extends #number
|
-- @extends #number Angle in radians.
|
||||||
|
|
||||||
--- Mass is given in kilograms.
|
--- Mass is given in kilograms.
|
||||||
-- @type Mass
|
-- @type Mass
|
||||||
@ -401,15 +406,15 @@ do -- Types
|
|||||||
|
|
||||||
--- Position is a composite structure. It consists of both coordinate vector and orientation matrix. Position3 (also known as "Pos3" for short) is a table that has following format:
|
--- Position is a composite structure. It consists of both coordinate vector and orientation matrix. Position3 (also known as "Pos3" for short) is a table that has following format:
|
||||||
-- @type Position3
|
-- @type Position3
|
||||||
-- @field #Vec3 p
|
-- @field #Vec3 p 3D position vector.
|
||||||
-- @field #Vec3 x
|
-- @field #Vec3 x Orientation component of vector pointing East.
|
||||||
-- @field #Vec3 y
|
-- @field #Vec3 y Orientation component of vector pointing up.
|
||||||
-- @field #Vec3 z
|
-- @field #Vec3 z Orientation component of vector pointing North.
|
||||||
|
|
||||||
--- 3-dimensional box.
|
--- 3-dimensional box.
|
||||||
-- @type Box3
|
-- @type Box3
|
||||||
-- @field #Vec3 min
|
-- @field #Vec3 min Min.
|
||||||
-- @field #Vec3 max
|
-- @field #Vec3 max Max
|
||||||
|
|
||||||
--- Each object belongs to a type. Object type is a named couple of properties those independent of mission and common for all units of the same type. Name of unit type is a string. Samples of unit type: "Su-27", "KAMAZ" and "M2 Bradley".
|
--- Each object belongs to a type. Object type is a named couple of properties those independent of mission and common for all units of the same type. Name of unit type is a string. Samples of unit type: "Su-27", "KAMAZ" and "M2 Bradley".
|
||||||
-- @type TypeName
|
-- @type TypeName
|
||||||
@ -514,7 +519,7 @@ do -- Object
|
|||||||
--- Returns object coordinates for current time.
|
--- Returns object coordinates for current time.
|
||||||
-- @function [parent=#Object] getPoint
|
-- @function [parent=#Object] getPoint
|
||||||
-- @param #Object self
|
-- @param #Object self
|
||||||
-- @return #Vec3
|
-- @return #Vec3 3D position vector with x,y,z components.
|
||||||
|
|
||||||
--- Returns object position for current time.
|
--- Returns object position for current time.
|
||||||
-- @function [parent=#Object] getPosition
|
-- @function [parent=#Object] getPosition
|
||||||
@ -524,7 +529,7 @@ do -- Object
|
|||||||
--- Returns the unit's velocity vector.
|
--- Returns the unit's velocity vector.
|
||||||
-- @function [parent=#Object] getVelocity
|
-- @function [parent=#Object] getVelocity
|
||||||
-- @param #Object self
|
-- @param #Object self
|
||||||
-- @return #Vec3
|
-- @return #Vec3 3D velocity vector.
|
||||||
|
|
||||||
--- Returns true if the unit is in air.
|
--- Returns true if the unit is in air.
|
||||||
-- @function [parent=#Object] inAir
|
-- @function [parent=#Object] inAir
|
||||||
|
|||||||
@ -513,7 +513,7 @@ ATIS.Sound = {
|
|||||||
MegaHertz={filename="MegaHertz.ogg", duration=0.87},
|
MegaHertz={filename="MegaHertz.ogg", duration=0.87},
|
||||||
Meters={filename="Meters.ogg", duration=0.59},
|
Meters={filename="Meters.ogg", duration=0.59},
|
||||||
MetersPerSecond={filename="MetersPerSecond.ogg", duration=1.14},
|
MetersPerSecond={filename="MetersPerSecond.ogg", duration=1.14},
|
||||||
Miles={filename="Miles.ogg", duration=1.04},
|
Miles={filename="Miles.ogg", duration=0.60},
|
||||||
MillimetersOfMercury={filename="MillimetersOfMercury.ogg", duration=1.53},
|
MillimetersOfMercury={filename="MillimetersOfMercury.ogg", duration=1.53},
|
||||||
Minus={filename="Minus.ogg", duration=0.64},
|
Minus={filename="Minus.ogg", duration=0.64},
|
||||||
N0={filename="N-0.ogg", duration=0.55},
|
N0={filename="N-0.ogg", duration=0.55},
|
||||||
@ -534,6 +534,7 @@ ATIS.Sound = {
|
|||||||
Right={filename="Right.ogg", duration=0.44},
|
Right={filename="Right.ogg", duration=0.44},
|
||||||
Snow={filename="Snow.ogg", duration=0.48},
|
Snow={filename="Snow.ogg", duration=0.48},
|
||||||
SnowStorm={filename="SnowStorm.ogg", duration=0.82},
|
SnowStorm={filename="SnowStorm.ogg", duration=0.82},
|
||||||
|
StatuteMiles={filename="StatuteMiles.ogg", duration=1.15},
|
||||||
SunriseAt={filename="SunriseAt.ogg", duration=0.92},
|
SunriseAt={filename="SunriseAt.ogg", duration=0.92},
|
||||||
SunsetAt={filename="SunsetAt.ogg", duration=0.95},
|
SunsetAt={filename="SunsetAt.ogg", duration=0.95},
|
||||||
Temperature={filename="Temperature.ogg", duration=0.64},
|
Temperature={filename="Temperature.ogg", duration=0.64},
|
||||||
@ -553,6 +554,7 @@ ATIS.Sound = {
|
|||||||
TACANChannel={filename="TACANChannel.ogg", duration=0.88},
|
TACANChannel={filename="TACANChannel.ogg", duration=0.88},
|
||||||
PRMGChannel={filename="PRMGChannel.ogg", duration=1.18},
|
PRMGChannel={filename="PRMGChannel.ogg", duration=1.18},
|
||||||
RSBNChannel={filename="RSBNChannel.ogg", duration=1.14},
|
RSBNChannel={filename="RSBNChannel.ogg", duration=1.14},
|
||||||
|
Zulu={filename="Zulu.ogg", duration=0.62},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -925,7 +927,7 @@ function ATIS:SetAltimeterQNH(switch)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Suppresses QFE readout. Default is to report both QNH and QFE.
|
--- Suppresses QFE readout. Default is to report both QNH and QFE.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:ReportQNHOnly()
|
function ATIS:ReportQNHOnly()
|
||||||
@ -995,7 +997,7 @@ function ATIS:SetZuluTimeDifference(delta)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Suppresses local time, sunrise, and sunset. Default is to report all these times.
|
--- Suppresses local time, sunrise, and sunset. Default is to report all these times.
|
||||||
-- @param #ATIS self
|
-- @param #ATIS self
|
||||||
-- @return #ATIS self
|
-- @return #ATIS self
|
||||||
function ATIS:ReportZuluTimeOnly()
|
function ATIS:ReportZuluTimeOnly()
|
||||||
@ -1502,7 +1504,7 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
-- Zulu Time
|
-- Zulu Time
|
||||||
subtitle=string.format("%s Zulu", ZULU)
|
subtitle=string.format("%s Zulu", ZULU)
|
||||||
self.radioqueue:Number2Transmission(ZULU, nil, 0.5)
|
self.radioqueue:Number2Transmission(ZULU, nil, 0.5)
|
||||||
self:Transmission(ATIS.Sound.TimeZulu, 0.2, subtitle)
|
self:Transmission(ATIS.Sound.Zulu, 0.2, subtitle)
|
||||||
alltext=alltext..";\n"..subtitle
|
alltext=alltext..";\n"..subtitle
|
||||||
|
|
||||||
if not self.zulutimeonly then
|
if not self.zulutimeonly then
|
||||||
@ -1557,7 +1559,7 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
if self.metric then
|
if self.metric then
|
||||||
self:Transmission(ATIS.Sound.Kilometers, 0.2)
|
self:Transmission(ATIS.Sound.Kilometers, 0.2)
|
||||||
else
|
else
|
||||||
self:Transmission(ATIS.Sound.Miles, 0.2)
|
self:Transmission(ATIS.Sound.StatuteMiles, 0.2)
|
||||||
end
|
end
|
||||||
alltext=alltext..";\n"..subtitle
|
alltext=alltext..";\n"..subtitle
|
||||||
|
|
||||||
@ -1975,13 +1977,6 @@ function ATIS:onafterBroadcast(From, Event, To)
|
|||||||
alltext=alltext..";\n"..subtitle
|
alltext=alltext..";\n"..subtitle
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
|
||||||
-- End of Information Alpha, Bravo, ...
|
|
||||||
subtitle=string.format("End of information %s", NATO)
|
|
||||||
self:Transmission(ATIS.Sound.EndOfInformation, 0.5, subtitle)
|
|
||||||
self.radioqueue:NewTransmission(string.format("NATO Alphabet/%s.ogg", NATO), 0.75, self.soundpath)
|
|
||||||
--]]
|
|
||||||
|
|
||||||
-- Advice on initial...
|
-- Advice on initial...
|
||||||
subtitle=string.format("Advise on initial contact, you have information %s", NATO)
|
subtitle=string.format("Advise on initial contact, you have information %s", NATO)
|
||||||
self:Transmission(ATIS.Sound.AdviceOnInitial, 0.5, subtitle)
|
self:Transmission(ATIS.Sound.AdviceOnInitial, 0.5, subtitle)
|
||||||
|
|||||||
@ -1345,7 +1345,6 @@ function RECOVERYTANKER:OnEventEngineShutdown(EventData)
|
|||||||
group:InitModex(self.modex)
|
group:InitModex(self.modex)
|
||||||
|
|
||||||
-- Respawn tanker. Delaying respawn due to DCS bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
-- Respawn tanker. Delaying respawn due to DCS bug https://github.com/FlightControl-Master/MOOSE/issues/1076
|
||||||
--SCHEDULER:New(nil , group.RespawnAtCurrentAirbase, {group}, 1)
|
|
||||||
self:ScheduleOnce(1, GROUP.RespawnAtCurrentAirbase, group)
|
self:ScheduleOnce(1, GROUP.RespawnAtCurrentAirbase, group)
|
||||||
|
|
||||||
-- Create tanker beacon and activate TACAN.
|
-- Create tanker beacon and activate TACAN.
|
||||||
@ -1364,7 +1363,6 @@ function RECOVERYTANKER:OnEventEngineShutdown(EventData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Initial route.
|
-- Initial route.
|
||||||
--SCHEDULER:New(nil, self._InitRoute, {self, -self.distStern+UTILS.NMToMeters(3)}, 2)
|
|
||||||
self:ScheduleOnce(2, RECOVERYTANKER._InitRoute, self, -self.distStern+UTILS.NMToMeters(3))
|
self:ScheduleOnce(2, RECOVERYTANKER._InitRoute, self, -self.distStern+UTILS.NMToMeters(3))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -56,6 +56,17 @@ ENUMS.ROT = {
|
|||||||
AllowAbortMission=4,
|
AllowAbortMission=4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Alarm state.
|
||||||
|
-- @type ENUMS.AlarmState
|
||||||
|
-- @field #number Auto AI will automatically switch alarm states based on the presence of threats. The AI kind of cheats in this regard.
|
||||||
|
-- @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.
|
||||||
|
ENUMS.AlarmState = {
|
||||||
|
Auto=0,
|
||||||
|
Green=1,
|
||||||
|
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) enumerotor on hoggit wiki.
|
||||||
-- @type ENUMS.WeaponFlag
|
-- @type ENUMS.WeaponFlag
|
||||||
ENUMS.WeaponFlag={
|
ENUMS.WeaponFlag={
|
||||||
@ -222,6 +233,15 @@ 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.Vee="Vee"
|
||||||
|
ENUMS.Formation.Vehicle.EchelonRight="EchelonR"
|
||||||
|
ENUMS.Formation.Vehicle.OffRoad="Off Road"
|
||||||
|
ENUMS.Formation.Vehicle.Rank="Rank"
|
||||||
|
ENUMS.Formation.Vehicle.EchelonLeft="EchelonL"
|
||||||
|
ENUMS.Formation.Vehicle.OnRoad="On Road"
|
||||||
|
ENUMS.Formation.Vehicle.Cone="Cone"
|
||||||
|
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.
|
||||||
|
|||||||
539
Moose Development/Moose/Utilities/Profiler.lua
Normal file
539
Moose Development/Moose/Utilities/Profiler.lua
Normal file
@ -0,0 +1,539 @@
|
|||||||
|
--- **Utils** - Lua Profiler.
|
||||||
|
--
|
||||||
|
-- Find out how many times functions are called and how much real time it costs.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **TAW CougarNL**, *funkyfranky*
|
||||||
|
--
|
||||||
|
-- @module Utilities.PROFILER
|
||||||
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
|
|
||||||
|
--- PROFILER class.
|
||||||
|
-- @type PROFILER
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #table Counters Function counters.
|
||||||
|
-- @field #table dInfo Info.
|
||||||
|
-- @field #table fTime Function time.
|
||||||
|
-- @field #table fTimeTotal Total function time.
|
||||||
|
-- @field #table eventhandler Event handler to get mission end event.
|
||||||
|
-- @field #number TstartGame Game start time timer.getTime().
|
||||||
|
-- @field #number TstartOS OS real start time os.clock.
|
||||||
|
-- @field #boolean logUnknown Log unknown functions. Default is off.
|
||||||
|
-- @field #number ThreshCPS Low calls per second threshold. Only write output if function has more calls per second 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 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 PROFILER Concept
|
||||||
|
--
|
||||||
|
-- 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.
|
||||||
|
--
|
||||||
|
-- # Prerequisites
|
||||||
|
--
|
||||||
|
-- The modules **os** and **lfs** need to be desanizied.
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- # Start
|
||||||
|
--
|
||||||
|
-- The profiler can simply be started with the @{#PROFILER.Start}(*Delay, Duration*) function
|
||||||
|
--
|
||||||
|
-- PROFILER.Start()
|
||||||
|
--
|
||||||
|
-- The optional parameter *Delay* can be used to delay the start by a certain amount of seconds and the optional parameter *Duration* can be used to
|
||||||
|
-- stop the profiler after a certain amount of seconds.
|
||||||
|
--
|
||||||
|
-- # Stop
|
||||||
|
--
|
||||||
|
-- The profiler automatically stops when the mission ends. But it can be stopped any time with the @{#PROFILER.Stop}(*Delay*) function
|
||||||
|
--
|
||||||
|
-- PROFILER.Stop()
|
||||||
|
--
|
||||||
|
-- The optional parameter *Delay* can be used to specify a delay after which the profiler is stopped.
|
||||||
|
--
|
||||||
|
-- When the profiler is stopped, the output is written to a file.
|
||||||
|
--
|
||||||
|
-- # Output
|
||||||
|
--
|
||||||
|
-- The profiler output is written to a file in your DCS home folder
|
||||||
|
--
|
||||||
|
-- X:\User\<Your User Name>\Saved Games\DCS OpenBeta\Logs
|
||||||
|
--
|
||||||
|
-- The default file name is "MooseProfiler.txt". If that file exists, the file name is "MooseProfiler-001.txt" etc.
|
||||||
|
--
|
||||||
|
-- ## Data
|
||||||
|
--
|
||||||
|
-- The data in the output file provides information on the functions that were called in the mission.
|
||||||
|
--
|
||||||
|
-- It will tell you how many times a function was called in total, how many times per second, how much time in total and the percentage of time.
|
||||||
|
--
|
||||||
|
-- If you only want output for functions that are called more than *X* times per second, you can set
|
||||||
|
--
|
||||||
|
-- PROFILER.ThreshCPS=1.5
|
||||||
|
--
|
||||||
|
-- With this setting, only functions which are called more than 1.5 times per second are displayed. The default setting is PROFILER.ThreshCPS=0.0 (no threshold).
|
||||||
|
--
|
||||||
|
-- Furthermore, you can limit the output for functions that consumed a certain amount of CPU time in total by
|
||||||
|
--
|
||||||
|
-- PROFILER.ThreshTtot=0.005
|
||||||
|
--
|
||||||
|
-- With this setting, which is also the default, only functions which in total used more than 5 milliseconds CPU time.
|
||||||
|
--
|
||||||
|
-- @field #PROFILER
|
||||||
|
PROFILER = {
|
||||||
|
ClassName = "PROFILER",
|
||||||
|
Counters = {},
|
||||||
|
dInfo = {},
|
||||||
|
fTime = {},
|
||||||
|
fTimeTotal = {},
|
||||||
|
eventHandler = {},
|
||||||
|
logUnknown = false,
|
||||||
|
ThreshCPS = 0.0,
|
||||||
|
ThreshTtot = 0.005,
|
||||||
|
fileNamePrefix = "MooseProfiler",
|
||||||
|
fileNameSuffix = "txt"
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Waypoint data.
|
||||||
|
-- @type PROFILER.Data
|
||||||
|
-- @field #string func The function name.
|
||||||
|
-- @field #string src The source file.
|
||||||
|
-- @field #number line The line number
|
||||||
|
-- @field #number count Number of function calls.
|
||||||
|
-- @field #number tm Total time in seconds.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Start/Stop Profiler
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Start profiler.
|
||||||
|
-- @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.
|
||||||
|
function PROFILER.Start(Delay, Duration)
|
||||||
|
|
||||||
|
-- Check if os, io and lfs are available.
|
||||||
|
local go=true
|
||||||
|
if not os then
|
||||||
|
env.error("ERROR: Profiler needs os to be desanitized!")
|
||||||
|
go=false
|
||||||
|
end
|
||||||
|
if not io then
|
||||||
|
env.error("ERROR: Profiler needs io to be desanitized!")
|
||||||
|
go=false
|
||||||
|
end
|
||||||
|
if not lfs then
|
||||||
|
env.error("ERROR: Profiler needs lfs to be desanitized!")
|
||||||
|
go=false
|
||||||
|
end
|
||||||
|
if not go then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
BASE:ScheduleOnce(Delay, PROFILER.Start, 0, Duration)
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Set start time.
|
||||||
|
PROFILER.TstartGame=timer.getTime()
|
||||||
|
PROFILER.TstartOS=os.clock()
|
||||||
|
|
||||||
|
-- Add event handler.
|
||||||
|
world.addEventHandler(PROFILER.eventHandler)
|
||||||
|
|
||||||
|
-- Info in log.
|
||||||
|
env.info('############################ Profiler Started ############################')
|
||||||
|
if Duration then
|
||||||
|
env.info(string.format("- Will be running for %d seconds", Duration))
|
||||||
|
else
|
||||||
|
env.info(string.format("- Will be stopped when mission ends"))
|
||||||
|
end
|
||||||
|
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("- 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('###############################################################################')
|
||||||
|
|
||||||
|
|
||||||
|
-- Message on screen
|
||||||
|
local duration=Duration or 600
|
||||||
|
trigger.action.outText("### Profiler running ###", duration)
|
||||||
|
|
||||||
|
-- Set hook.
|
||||||
|
debug.sethook(PROFILER.hook, "cr")
|
||||||
|
|
||||||
|
-- Auto stop profiler.
|
||||||
|
if Duration then
|
||||||
|
PROFILER.Stop(Duration)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Stop profiler.
|
||||||
|
-- @param #number Delay Delay before stop in seconds.
|
||||||
|
function PROFILER.Stop(Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
|
||||||
|
BASE:ScheduleOnce(Delay, PROFILER.Stop)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Remove hook.
|
||||||
|
debug.sethook()
|
||||||
|
|
||||||
|
|
||||||
|
-- Run time game.
|
||||||
|
local runTimeGame=timer.getTime()-PROFILER.TstartGame
|
||||||
|
|
||||||
|
-- Run time real OS.
|
||||||
|
local runTimeOS=os.clock()-PROFILER.TstartOS
|
||||||
|
|
||||||
|
-- Show info.
|
||||||
|
PROFILER.showInfo(runTimeGame, runTimeOS)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Event handler.
|
||||||
|
function PROFILER.eventHandler:onEvent(event)
|
||||||
|
if event.id==world.event.S_EVENT_MISSION_END then
|
||||||
|
PROFILER.Stop()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Hook
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Debug hook.
|
||||||
|
-- @param #table event Event.
|
||||||
|
function PROFILER.hook(event)
|
||||||
|
|
||||||
|
local f=debug.getinfo(2, "f").func
|
||||||
|
|
||||||
|
if event=='call' then
|
||||||
|
|
||||||
|
if PROFILER.Counters[f]==nil then
|
||||||
|
|
||||||
|
PROFILER.Counters[f]=1
|
||||||
|
PROFILER.dInfo[f]=debug.getinfo(2,"Sn")
|
||||||
|
|
||||||
|
if PROFILER.fTimeTotal[f]==nil then
|
||||||
|
PROFILER.fTimeTotal[f]=0
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
PROFILER.Counters[f]=PROFILER.Counters[f]+1
|
||||||
|
end
|
||||||
|
|
||||||
|
if PROFILER.fTime[f]==nil then
|
||||||
|
PROFILER.fTime[f]=os.clock()
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif (event=='return') then
|
||||||
|
|
||||||
|
if PROFILER.fTime[f]~=nil then
|
||||||
|
PROFILER.fTimeTotal[f]=PROFILER.fTimeTotal[f]+(os.clock()-PROFILER.fTime[f])
|
||||||
|
PROFILER.fTime[f]=nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Data
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Get data.
|
||||||
|
-- @param #function func Function.
|
||||||
|
-- @return #string Function name.
|
||||||
|
-- @return #string Source file name.
|
||||||
|
-- @return #string Line number.
|
||||||
|
-- @return #number Function time in seconds.
|
||||||
|
function PROFILER.getData(func)
|
||||||
|
|
||||||
|
local n=PROFILER.dInfo[func]
|
||||||
|
|
||||||
|
if n.what=="C" then
|
||||||
|
return n.name, "?", "?", PROFILER.fTimeTotal[func]
|
||||||
|
end
|
||||||
|
|
||||||
|
return n.name, n.short_src, n.linedefined, PROFILER.fTimeTotal[func]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Write text to log file.
|
||||||
|
-- @param #function f The file.
|
||||||
|
-- @param #string txt The text.
|
||||||
|
function PROFILER._flog(f, txt)
|
||||||
|
f:write(txt.."\r\n")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Show table.
|
||||||
|
-- @param #table data Data table.
|
||||||
|
-- @param #function f The file.
|
||||||
|
-- @param #number runTimeGame Game run time in seconds.
|
||||||
|
function PROFILER.showTable(data, f, runTimeGame)
|
||||||
|
|
||||||
|
-- Loop over data.
|
||||||
|
for i=1, #data do
|
||||||
|
local t=data[i] --#PROFILER.Data
|
||||||
|
|
||||||
|
-- Calls per second.
|
||||||
|
local cps=t.count/runTimeGame
|
||||||
|
|
||||||
|
local threshCPS=cps>=PROFILER.ThreshCPS
|
||||||
|
local threshTot=t.tm>=PROFILER.ThreshTtot
|
||||||
|
|
||||||
|
if threshCPS and threshTot then
|
||||||
|
|
||||||
|
-- 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))
|
||||||
|
PROFILER._flog(f, text)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Print csv file.
|
||||||
|
-- @param #table data Data table.
|
||||||
|
-- @param #number runTimeGame Game run time in seconds.
|
||||||
|
function PROFILER.printCSV(data, runTimeGame)
|
||||||
|
|
||||||
|
-- Output file.
|
||||||
|
local file=PROFILER.getfilename("csv")
|
||||||
|
local g=io.open(file, 'w')
|
||||||
|
|
||||||
|
-- Header.
|
||||||
|
local text="Function,Total Calls,Calls per Sec,Total Time,Total in %,Sec per Call,Source File;Line Number,"
|
||||||
|
g:write(text.."\r\n")
|
||||||
|
|
||||||
|
-- Loop over data.
|
||||||
|
for i=1, #data do
|
||||||
|
local t=data[i] --#PROFILER.Data
|
||||||
|
|
||||||
|
-- Calls per second.
|
||||||
|
local cps=t.count/runTimeGame
|
||||||
|
|
||||||
|
-- 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))
|
||||||
|
g:write(txt.."\r\n")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Close file.
|
||||||
|
g:close()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Write info to output file.
|
||||||
|
-- @param #string ext Extension.
|
||||||
|
-- @return #string File name.
|
||||||
|
function PROFILER.getfilename(ext)
|
||||||
|
|
||||||
|
local dir=lfs.writedir()..[[Logs\]]
|
||||||
|
|
||||||
|
ext=ext or PROFILER.fileNameSuffix
|
||||||
|
|
||||||
|
local file=dir..PROFILER.fileNamePrefix.."."..ext
|
||||||
|
|
||||||
|
if not UTILS.FileExists(file) then
|
||||||
|
return file
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1,999 do
|
||||||
|
|
||||||
|
local file=string.format("%s%s-%03d.%s", dir,PROFILER.fileNamePrefix, i, ext)
|
||||||
|
|
||||||
|
if not UTILS.FileExists(file) then
|
||||||
|
return file
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Write info to output file.
|
||||||
|
-- @param #number runTimeGame Game time in seconds.
|
||||||
|
-- @param #number runTimeOS OS time in seconds.
|
||||||
|
function PROFILER.showInfo(runTimeGame, runTimeOS)
|
||||||
|
|
||||||
|
-- Output file.
|
||||||
|
local file=PROFILER.getfilename(PROFILER.fileNameSuffix)
|
||||||
|
local f=io.open(file, 'w')
|
||||||
|
|
||||||
|
-- Gather data.
|
||||||
|
local Ttot=0
|
||||||
|
local Calls=0
|
||||||
|
|
||||||
|
local t={}
|
||||||
|
|
||||||
|
local tcopy=nil --#PROFILER.Data
|
||||||
|
local tserialize=nil --#PROFILER.Data
|
||||||
|
local tforgen=nil --#PROFILER.Data
|
||||||
|
local tpairs=nil --#PROFILER.Data
|
||||||
|
|
||||||
|
|
||||||
|
for func, count in pairs(PROFILER.Counters) do
|
||||||
|
|
||||||
|
local s,src,line,tm=PROFILER.getData(func)
|
||||||
|
|
||||||
|
if PROFILER.logUnknown==true then
|
||||||
|
if s==nil then s="<Unknown>" end
|
||||||
|
end
|
||||||
|
|
||||||
|
if s~=nil then
|
||||||
|
|
||||||
|
-- Profile data.
|
||||||
|
local T=
|
||||||
|
{ 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.
|
||||||
|
if s=="_copy" then
|
||||||
|
if tcopy==nil then
|
||||||
|
tcopy=T
|
||||||
|
else
|
||||||
|
tcopy.count=tcopy.count+T.count
|
||||||
|
tcopy.tm=tcopy.tm+T.tm
|
||||||
|
end
|
||||||
|
elseif s=="_Serialize" then
|
||||||
|
if tserialize==nil then
|
||||||
|
tserialize=T
|
||||||
|
else
|
||||||
|
tserialize.count=tserialize.count+T.count
|
||||||
|
tserialize.tm=tserialize.tm+T.tm
|
||||||
|
end
|
||||||
|
elseif s=="(for generator)" then
|
||||||
|
if tforgen==nil then
|
||||||
|
tforgen=T
|
||||||
|
else
|
||||||
|
tforgen.count=tforgen.count+T.count
|
||||||
|
tforgen.tm=tforgen.tm+T.tm
|
||||||
|
end
|
||||||
|
elseif s=="pairs" then
|
||||||
|
if tpairs==nil then
|
||||||
|
tpairs=T
|
||||||
|
else
|
||||||
|
tpairs.count=tpairs.count+T.count
|
||||||
|
tpairs.tm=tpairs.tm+T.tm
|
||||||
|
end
|
||||||
|
else
|
||||||
|
table.insert(t, T)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Total function time.
|
||||||
|
Ttot=Ttot+tm
|
||||||
|
|
||||||
|
-- Total number of calls.
|
||||||
|
Calls=Calls+count
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Add special cases.
|
||||||
|
if tcopy then
|
||||||
|
table.insert(t, tcopy)
|
||||||
|
end
|
||||||
|
if tserialize then
|
||||||
|
table.insert(t, tserialize)
|
||||||
|
end
|
||||||
|
if tforgen then
|
||||||
|
table.insert(t, tforgen)
|
||||||
|
end
|
||||||
|
if tpairs then
|
||||||
|
table.insert(t, tpairs)
|
||||||
|
end
|
||||||
|
|
||||||
|
env.info('############################ Profiler Stopped ############################')
|
||||||
|
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("* 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 func calls : %d", Calls))
|
||||||
|
env.info(string.format("* Writing to file : \"%s\"", file))
|
||||||
|
env.info(string.format("* Writing to file : \"%s\"", PROFILER.getfilename("csv")))
|
||||||
|
env.info("##############################################################################")
|
||||||
|
|
||||||
|
-- Sort by total time.
|
||||||
|
table.sort(t, function(a,b) return a.tm>b.tm end)
|
||||||
|
|
||||||
|
-- Write data.
|
||||||
|
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._flog(f,"")
|
||||||
|
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("* Function time : %s = %.1f sec (%.1f %% of runtime game)", UTILS.SecondsToClock(Ttot, true), Ttot, Ttot/runTimeGame*100))
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER._flog(f,string.format("* Total functions = %d", #t))
|
||||||
|
PROFILER._flog(f,string.format("* Total func calls = %d", Calls))
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
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,"")
|
||||||
|
PROFILER._flog(f,"************************************************************************************************************************")
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER.showTable(t, f, runTimeGame)
|
||||||
|
|
||||||
|
-- Sort by number of calls.
|
||||||
|
table.sort(t, function(a,b) return a.tm/a.count>b.tm/b.count end)
|
||||||
|
|
||||||
|
-- Detailed data.
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER._flog(f,"************************************************************************************************************************")
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER._flog(f,"--------------------------------------")
|
||||||
|
PROFILER._flog(f,"---- Data Sorted by Time per Call ----")
|
||||||
|
PROFILER._flog(f,"--------------------------------------")
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER.showTable(t, f, runTimeGame)
|
||||||
|
|
||||||
|
-- Sort by number of calls.
|
||||||
|
table.sort(t, function(a,b) return a.count>b.count end)
|
||||||
|
|
||||||
|
-- Detailed data.
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER._flog(f,"************************************************************************************************************************")
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER._flog(f,"------------------------------------")
|
||||||
|
PROFILER._flog(f,"---- Data Sorted by Total Calls ----")
|
||||||
|
PROFILER._flog(f,"------------------------------------")
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER.showTable(t, f, runTimeGame)
|
||||||
|
|
||||||
|
-- Closing.
|
||||||
|
PROFILER._flog(f,"")
|
||||||
|
PROFILER._flog(f,"************************************************************************************************************************")
|
||||||
|
PROFILER._flog(f,"************************************************************************************************************************")
|
||||||
|
PROFILER._flog(f,"************************************************************************************************************************")
|
||||||
|
-- Close file.
|
||||||
|
f:close()
|
||||||
|
|
||||||
|
-- Print csv file.
|
||||||
|
PROFILER.printCSV(t, runTimeGame)
|
||||||
|
end
|
||||||
|
|
||||||
@ -191,21 +191,30 @@ end
|
|||||||
-- @param #table object The input table.
|
-- @param #table object The input table.
|
||||||
-- @return #table Copy of the input table.
|
-- @return #table Copy of the input table.
|
||||||
UTILS.DeepCopy = function(object)
|
UTILS.DeepCopy = function(object)
|
||||||
|
|
||||||
local lookup_table = {}
|
local lookup_table = {}
|
||||||
|
|
||||||
|
-- Copy function.
|
||||||
local function _copy(object)
|
local function _copy(object)
|
||||||
if type(object) ~= "table" then
|
if type(object) ~= "table" then
|
||||||
return object
|
return object
|
||||||
elseif lookup_table[object] then
|
elseif lookup_table[object] then
|
||||||
return lookup_table[object]
|
return lookup_table[object]
|
||||||
end
|
end
|
||||||
|
|
||||||
local new_table = {}
|
local new_table = {}
|
||||||
|
|
||||||
lookup_table[object] = new_table
|
lookup_table[object] = new_table
|
||||||
|
|
||||||
for index, value in pairs(object) do
|
for index, value in pairs(object) do
|
||||||
new_table[_copy(index)] = _copy(value)
|
new_table[_copy(index)] = _copy(value)
|
||||||
end
|
end
|
||||||
|
|
||||||
return setmetatable(new_table, getmetatable(object))
|
return setmetatable(new_table, getmetatable(object))
|
||||||
end
|
end
|
||||||
|
|
||||||
local objectreturn = _copy(object)
|
local objectreturn = _copy(object)
|
||||||
|
|
||||||
return objectreturn
|
return objectreturn
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -359,7 +368,7 @@ UTILS.MpsToMiph = function( mps )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Convert meters per second to knots.
|
--- Convert meters per second to knots.
|
||||||
-- @param #number knots Speed in m/s.
|
-- @param #number mps Speed in m/s.
|
||||||
-- @return #number Speed in knots.
|
-- @return #number Speed in knots.
|
||||||
UTILS.MpsToKnots = function( mps )
|
UTILS.MpsToKnots = function( mps )
|
||||||
return mps * 1.94384 --3600 / 1852
|
return mps * 1.94384 --3600 / 1852
|
||||||
@ -975,6 +984,22 @@ function UTILS.HdgDiff(h1, h2)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Translate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged.
|
||||||
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
|
-- @param #number distance The distance to translate.
|
||||||
|
-- @param #number angle Rotation angle in degrees.
|
||||||
|
-- @return DCS#Vec3 Vector rotated in the (x,z) plane.
|
||||||
|
function UTILS.VecTranslate(a, distance, angle)
|
||||||
|
|
||||||
|
local SX = a.x
|
||||||
|
local SY = a.z
|
||||||
|
local Radians=math.rad(angle or 0)
|
||||||
|
local TX=distance*math.cos(Radians)+SX
|
||||||
|
local TY=distance*math.sin(Radians)+SY
|
||||||
|
|
||||||
|
return {x=TX, y=a.y, z=TY}
|
||||||
|
end
|
||||||
|
|
||||||
--- Rotate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged.
|
--- Rotate 3D vector in the 2D (x,z) plane. y-component (usually altitude) unchanged.
|
||||||
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
-- @param DCS#Vec3 a Vector in 3D with x, y, z components.
|
||||||
-- @param #number angle Rotation angle in degrees.
|
-- @param #number angle Rotation angle in degrees.
|
||||||
@ -996,7 +1021,6 @@ function UTILS.Rotate2D(a, angle)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Converts a TACAN Channel/Mode couple into a frequency in Hz.
|
--- Converts a TACAN Channel/Mode couple into a frequency in Hz.
|
||||||
-- @param #number TACANChannel The TACAN channel, i.e. the 10 in "10X".
|
-- @param #number TACANChannel The TACAN channel, i.e. the 10 in "10X".
|
||||||
-- @param #string TACANMode The TACAN mode, i.e. the "X" in "10X".
|
-- @param #string TACANMode The TACAN mode, i.e. the "X" in "10X".
|
||||||
@ -1411,3 +1435,13 @@ function UTILS.GetSunset(Day, Month, Year, Latitude, Longitude, Tlocal)
|
|||||||
|
|
||||||
return UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tlocal)
|
return UTILS.GetSunRiseAndSet(DayOfYear, Latitude, Longitude, false, Tlocal)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get OS time. Needs os to be desanitized!
|
||||||
|
-- @return #number Os time in seconds.
|
||||||
|
function UTILS.GetOSTime()
|
||||||
|
if os then
|
||||||
|
return os.clock()
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
@ -15,6 +15,15 @@
|
|||||||
--- @type AIRBASE
|
--- @type AIRBASE
|
||||||
-- @field #string ClassName Name of the class, i.e. "AIRBASE".
|
-- @field #string ClassName Name of the class, i.e. "AIRBASE".
|
||||||
-- @field #table CategoryName Names of airbase categories.
|
-- @field #table CategoryName Names of airbase categories.
|
||||||
|
-- @field #string AirbaseName Name of the airbase.
|
||||||
|
-- @field #number AirbaseID Airbase ID.
|
||||||
|
-- @field #number category Airbase category.
|
||||||
|
-- @field #table descriptors DCS descriptors.
|
||||||
|
-- @field #boolean isAirdrome Airbase is an airdrome.
|
||||||
|
-- @field #boolean isHelipad Airbase is a helipad.
|
||||||
|
-- @field #boolean isShip Airbase is a ship.
|
||||||
|
-- @field #table parking Parking spot data.
|
||||||
|
-- @field #table parkingByID Parking spot data table with ID as key.
|
||||||
-- @field #number activerwyno Active runway number (forced).
|
-- @field #number activerwyno Active runway number (forced).
|
||||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||||
|
|
||||||
@ -440,20 +449,52 @@ AIRBASE.TerminalType = {
|
|||||||
-- @field Core.Point#COORDINATE position Position of runway start.
|
-- @field Core.Point#COORDINATE position Position of runway start.
|
||||||
-- @field Core.Point#COORDINATE endpoint End point of runway.
|
-- @field Core.Point#COORDINATE endpoint End point of runway.
|
||||||
|
|
||||||
-- Registration.
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Registration
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Create a new AIRBASE from DCSAirbase.
|
--- Create a new AIRBASE from DCSAirbase.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #string AirbaseName The name of the airbase.
|
-- @param #string AirbaseName The name of the airbase.
|
||||||
-- @return Wrapper.Airbase#AIRBASE
|
-- @return #AIRBASE self
|
||||||
function AIRBASE:Register( AirbaseName )
|
function AIRBASE:Register(AirbaseName)
|
||||||
|
|
||||||
|
-- Inherit everything from positionable.
|
||||||
|
local self=BASE:Inherit(self, POSITIONABLE:New(AirbaseName)) --#AIRBASE
|
||||||
|
|
||||||
|
-- Set airbase name.
|
||||||
|
self.AirbaseName=AirbaseName
|
||||||
|
|
||||||
|
-- Set airbase ID.
|
||||||
|
self.AirbaseID=self:GetID(true)
|
||||||
|
|
||||||
|
-- Get descriptors.
|
||||||
|
self.descriptors=self:GetDesc()
|
||||||
|
|
||||||
|
-- Category.
|
||||||
|
self.category=self.descriptors and self.descriptors.category or Airbase.Category.AIRDROME
|
||||||
|
|
||||||
|
-- Set category.
|
||||||
|
if self.category==Airbase.Category.AIRDROME then
|
||||||
|
self.isAirdrome=true
|
||||||
|
elseif self.category==Airbase.Category.HELIPAD then
|
||||||
|
self.isHelipad=true
|
||||||
|
elseif self.category==Airbase.Category.SHIP then
|
||||||
|
self.isShip=true
|
||||||
|
else
|
||||||
|
self:E("ERROR: Unknown airbase category!")
|
||||||
|
end
|
||||||
|
|
||||||
|
self:_InitParkingSpots()
|
||||||
|
|
||||||
local self = BASE:Inherit( self, POSITIONABLE:New( AirbaseName ) ) --#AIRBASE
|
|
||||||
self.AirbaseName = AirbaseName
|
|
||||||
self.AirbaseID = self:GetID(true)
|
|
||||||
local vec2=self:GetVec2()
|
local vec2=self:GetVec2()
|
||||||
|
|
||||||
|
-- Init coordinate.
|
||||||
|
self:GetCoordinate()
|
||||||
|
|
||||||
if vec2 then
|
if vec2 then
|
||||||
self.AirbaseZone = ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
|
-- TODO: For ships we need a moving zone.
|
||||||
|
self.AirbaseZone=ZONE_RADIUS:New( AirbaseName, vec2, 2500 )
|
||||||
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
|
||||||
@ -461,7 +502,9 @@ function AIRBASE:Register( AirbaseName )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reference methods.
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Reference methods
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Finds a AIRBASE from the _DATABASE using a DCSAirbase object.
|
--- Finds a AIRBASE from the _DATABASE using a DCSAirbase object.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
@ -508,7 +551,9 @@ end
|
|||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @return DCS#Airbase DCS airbase object.
|
-- @return DCS#Airbase DCS airbase object.
|
||||||
function AIRBASE:GetDCSObject()
|
function AIRBASE:GetDCSObject()
|
||||||
local DCSAirbase = Airbase.getByName( self.AirbaseName )
|
|
||||||
|
-- Get the DCS object.
|
||||||
|
local DCSAirbase = Airbase.getByName(self.AirbaseName)
|
||||||
|
|
||||||
if DCSAirbase then
|
if DCSAirbase then
|
||||||
return DCSAirbase
|
return DCSAirbase
|
||||||
@ -533,7 +578,7 @@ function AIRBASE.GetAllAirbases(coalition, category)
|
|||||||
local airbases={}
|
local airbases={}
|
||||||
for _,_airbase in pairs(_DATABASE.AIRBASES) do
|
for _,_airbase in pairs(_DATABASE.AIRBASES) do
|
||||||
local airbase=_airbase --#AIRBASE
|
local airbase=_airbase --#AIRBASE
|
||||||
if (coalition~=nil and airbase:GetCoalition()==coalition) or coalition==nil then
|
if coalition==nil or airbase:GetCoalition()==coalition then
|
||||||
if category==nil or category==airbase:GetAirbaseCategory() then
|
if category==nil or category==airbase:GetAirbaseCategory() then
|
||||||
table.insert(airbases, airbase)
|
table.insert(airbases, airbase)
|
||||||
end
|
end
|
||||||
@ -543,6 +588,25 @@ function AIRBASE.GetAllAirbases(coalition, category)
|
|||||||
return airbases
|
return airbases
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get all airbase names of the current map. This includes ships and FARPS.
|
||||||
|
-- @param DCS#Coalition coalition (Optional) Return only airbases belonging to the specified coalition. By default, all airbases of the map are returned.
|
||||||
|
-- @param #number category (Optional) Return only airbases of a certain category, e.g. Airbase.Category.FARP
|
||||||
|
-- @return #table Table containing all airbase names of the current map.
|
||||||
|
function AIRBASE.GetAllAirbaseNames(coalition, category)
|
||||||
|
|
||||||
|
local airbases={}
|
||||||
|
for airbasename,_airbase in pairs(_DATABASE.AIRBASES) do
|
||||||
|
local airbase=_airbase --#AIRBASE
|
||||||
|
if coalition==nil or airbase:GetCoalition()==coalition then
|
||||||
|
if category==nil or category==airbase:GetAirbaseCategory() then
|
||||||
|
table.insert(airbases, airbasename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return airbases
|
||||||
|
end
|
||||||
|
|
||||||
--- Get ID of the airbase.
|
--- Get ID of the airbase.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #boolean unique (Optional) If true, ships will get a negative sign as the unit ID might be the same as an airbase ID. Default off!
|
-- @param #boolean unique (Optional) If true, ships will get a negative sign as the unit ID might be the same as an airbase ID. Default off!
|
||||||
@ -565,24 +629,8 @@ function AIRBASE:GetID(unique)
|
|||||||
|
|
||||||
local airbaseCategory=self:GetAirbaseCategory()
|
local airbaseCategory=self:GetAirbaseCategory()
|
||||||
|
|
||||||
--env.info(string.format("FF airbase=%s id=%s category=%s", tostring(AirbaseName), tostring(airbaseID), tostring(airbaseCategory)))
|
|
||||||
|
|
||||||
-- No way AFIK to get the DCS version. So we check if the event exists. That should tell us if we are on DCS 2.5.6 or prior to that.
|
|
||||||
--[[
|
|
||||||
if world.event.S_EVENT_KILL and world.event.S_EVENT_KILL>0 and airbaseCategory==Airbase.Category.AIRDROME then
|
|
||||||
|
|
||||||
-- We have to take the key value of this loop!
|
|
||||||
airbaseID=DCSAirbaseId
|
|
||||||
|
|
||||||
-- Now another quirk: for Caucasus, we need to add 11 to the key value to get the correct ID. See https://forums.eagle.ru/showpost.php?p=4210774&postcount=11
|
|
||||||
if UTILS.GetDCSMap()==DCSMAP.Caucasus then
|
|
||||||
airbaseID=airbaseID+11
|
|
||||||
end
|
|
||||||
end
|
|
||||||
]]
|
|
||||||
|
|
||||||
if AirbaseName==self.AirbaseName then
|
if AirbaseName==self.AirbaseName then
|
||||||
if airbaseCategory==Airbase.Category.SHIP then
|
if airbaseCategory==Airbase.Category.SHIP or airbaseCategory==Airbase.Category.HELIPAD then
|
||||||
-- Ships get a negative sign as their unit number might be the same as the ID of another airbase.
|
-- Ships get a negative sign as their unit number might be the same as the ID of another airbase.
|
||||||
return unique and -airbaseID or airbaseID
|
return unique and -airbaseID or airbaseID
|
||||||
else
|
else
|
||||||
@ -598,6 +646,38 @@ function AIRBASE:GetID(unique)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get category of airbase.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #number Category of airbase from GetDesc().category.
|
||||||
|
function AIRBASE:GetAirbaseCategory()
|
||||||
|
return self.category
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if airbase is an airdrome.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #boolean If true, airbase is an airdrome.
|
||||||
|
function AIRBASE:IsAirdrome()
|
||||||
|
return self.isAirdrome
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if airbase is a helipad.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #boolean If true, airbase is a helipad.
|
||||||
|
function AIRBASE:IsHelipad()
|
||||||
|
return self.isHelipad
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if airbase is a ship.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return #boolean If true, airbase is a ship.
|
||||||
|
function AIRBASE:IsShip()
|
||||||
|
return self.isShip
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Parking
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Returns a table of parking data for a given airbase. If the optional parameter *available* is true only available parking will be returned, otherwise all parking at the base is returned. Term types have the following enumerated values:
|
--- Returns a table of parking data for a given airbase. If the optional parameter *available* is true only available parking will be returned, otherwise all parking at the base is returned. Term types have the following enumerated values:
|
||||||
--
|
--
|
||||||
-- * 16 : Valid spawn points on runway
|
-- * 16 : Valid spawn points on runway
|
||||||
@ -728,6 +808,58 @@ function AIRBASE:GetParkingSpotsCoordinates(termtype)
|
|||||||
return spots
|
return spots
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @return#AIRBASE self
|
||||||
|
function AIRBASE:_InitParkingSpots()
|
||||||
|
|
||||||
|
-- Get parking data of all spots (free or occupied)
|
||||||
|
local parkingdata=self:GetParkingData(false)
|
||||||
|
|
||||||
|
-- Init table.
|
||||||
|
self.parking={}
|
||||||
|
self.parkingByID={}
|
||||||
|
|
||||||
|
self.NparkingTotal=0
|
||||||
|
self.NparkingTerminal={}
|
||||||
|
for _,terminalType in pairs(AIRBASE.TerminalType) do
|
||||||
|
self.NparkingTerminal[terminalType]=0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Put coordinates of parking spots into table.
|
||||||
|
for _,spot in pairs(parkingdata) do
|
||||||
|
|
||||||
|
-- New parking spot.
|
||||||
|
local park={} --#AIRBASE.ParkingSpot
|
||||||
|
park.Vec3=spot.vTerminalPos
|
||||||
|
park.Coordinate=COORDINATE:NewFromVec3(spot.vTerminalPos)
|
||||||
|
park.DistToRwy=spot.fDistToRW
|
||||||
|
park.Free=nil
|
||||||
|
park.TerminalID=spot.Term_Index
|
||||||
|
park.TerminalID0=spot.Term_Index_0
|
||||||
|
park.TerminalType=spot.Term_Type
|
||||||
|
park.TOAC=spot.TO_AC
|
||||||
|
|
||||||
|
for _,terminalType in pairs(AIRBASE.TerminalType) do
|
||||||
|
if self._CheckTerminalType(terminalType, park.TerminalType) then
|
||||||
|
self.NparkingTerminal[terminalType]=self.NparkingTerminal[terminalType]+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.parkingByID[park.TerminalID]=park
|
||||||
|
table.insert(self.parking, park)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param #number TerminalID Terminal ID.
|
||||||
|
-- @return #AIRBASE.ParkingSpot Parking spot.
|
||||||
|
function AIRBASE:_GetParkingSpotByID(TerminalID)
|
||||||
|
return self.parkingByID[TerminalID]
|
||||||
|
end
|
||||||
|
|
||||||
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
|
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
@ -737,6 +869,7 @@ function AIRBASE:GetParkingSpotsTable(termtype)
|
|||||||
|
|
||||||
-- Get parking data of all spots (free or occupied)
|
-- Get parking data of all spots (free or occupied)
|
||||||
local parkingdata=self:GetParkingData(false)
|
local parkingdata=self:GetParkingData(false)
|
||||||
|
|
||||||
-- Get parking data of all free spots.
|
-- Get parking data of all free spots.
|
||||||
local parkingfree=self:GetParkingData(true)
|
local parkingfree=self:GetParkingData(true)
|
||||||
|
|
||||||
@ -753,15 +886,18 @@ function AIRBASE:GetParkingSpotsTable(termtype)
|
|||||||
-- Put coordinates of parking spots into table.
|
-- Put coordinates of parking spots into table.
|
||||||
local spots={}
|
local spots={}
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) then
|
|
||||||
self:T2({_spot=_spot})
|
|
||||||
local _free=_isfree(_spot)
|
|
||||||
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
|
||||||
table.insert(spots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=_free, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self:T2({ spots = spots } )
|
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) then
|
||||||
|
|
||||||
|
local spot=self:_GetParkingSpotByID(_spot.Term_Index)
|
||||||
|
|
||||||
|
spot.Free=_isfree(_spot) -- updated
|
||||||
|
spot.TOAC=_spot.TO_AC -- updated
|
||||||
|
|
||||||
|
table.insert(spots, spot)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
return spots
|
return spots
|
||||||
end
|
end
|
||||||
@ -781,8 +917,14 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
|
|||||||
for _,_spot in pairs(parkingfree) do
|
for _,_spot in pairs(parkingfree) do
|
||||||
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then
|
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then
|
||||||
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
|
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
|
||||||
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
|
||||||
table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
local spot=self:_GetParkingSpotByID(_spot.Term_Index)
|
||||||
|
|
||||||
|
spot.Free=true -- updated
|
||||||
|
spot.TOAC=_spot.TO_AC -- updated
|
||||||
|
|
||||||
|
table.insert(freespots, spot)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -795,14 +937,10 @@ end
|
|||||||
-- @param #number TerminalID The terminal ID of the parking spot.
|
-- @param #number TerminalID The terminal ID of the parking spot.
|
||||||
-- @return #AIRBASE.ParkingSpot Table free parking spots. Table has the elements ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
-- @return #AIRBASE.ParkingSpot Table free parking spots. Table has the elements ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
||||||
function AIRBASE:GetParkingSpotData(TerminalID)
|
function AIRBASE:GetParkingSpotData(TerminalID)
|
||||||
self:F({TerminalID=TerminalID})
|
|
||||||
|
|
||||||
-- Get parking data.
|
-- Get parking data.
|
||||||
local parkingdata=self:GetParkingSpotsTable()
|
local parkingdata=self:GetParkingSpotsTable()
|
||||||
|
|
||||||
-- Debug output.
|
|
||||||
self:T2({parkingdata=parkingdata})
|
|
||||||
|
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
local spot=_spot --#AIRBASE.ParkingSpot
|
local spot=_spot --#AIRBASE.ParkingSpot
|
||||||
self:T({TerminalID=spot.TerminalID,TerminalType=spot.TerminalType})
|
self:T({TerminalID=spot.TerminalID,TerminalType=spot.TerminalType})
|
||||||
@ -1041,99 +1179,6 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
|||||||
return validspots
|
return validspots
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Function that checks if at leat one unit of a group has been spawned close to a spawn point on the runway.
|
|
||||||
-- @param #AIRBASE self
|
|
||||||
-- @param Wrapper.Group#GROUP group Group to be checked.
|
|
||||||
-- @param #number radius Radius around the spawn point to be checked. Default is 50 m.
|
|
||||||
-- @param #boolean despawn If true, the group is destroyed.
|
|
||||||
-- @return #boolean True if group is within radius around spawn points on runway.
|
|
||||||
function AIRBASE:CheckOnRunWay(group, radius, despawn)
|
|
||||||
|
|
||||||
-- Default radius.
|
|
||||||
radius=radius or 50
|
|
||||||
|
|
||||||
-- We only check at real airbases (not FARPS or ships).
|
|
||||||
if self:GetAirbaseCategory()~=Airbase.Category.AIRDROME then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if group and group:IsAlive() then
|
|
||||||
|
|
||||||
-- Debug.
|
|
||||||
self:T(string.format("%s, checking if group %s is on runway?",self:GetName(), group:GetName()))
|
|
||||||
|
|
||||||
-- Get coordinates on runway.
|
|
||||||
local runwaypoints=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
|
|
||||||
|
|
||||||
-- Mark runway spawn points.
|
|
||||||
--[[
|
|
||||||
for _i,_coord in pairs(runwaypoints) do
|
|
||||||
_coord:MarkToAll(string.format("runway %d",_i))
|
|
||||||
end
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- Get units of group.
|
|
||||||
local units=group:GetUnits()
|
|
||||||
|
|
||||||
-- Loop over units.
|
|
||||||
for _,_unit in pairs(units) do
|
|
||||||
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- Check if unit is alive and not in air.
|
|
||||||
if unit and unit:IsAlive() and not unit:InAir() then
|
|
||||||
self:T(string.format("%s, checking if unit %s is on runway?",self:GetName(), unit:GetName()))
|
|
||||||
|
|
||||||
-- Loop over runway spawn points.
|
|
||||||
for _i,_coord in pairs(runwaypoints) do
|
|
||||||
|
|
||||||
-- Distance between unit and spawn pos.
|
|
||||||
local dist=unit:GetCoordinate():Get2DDistance(_coord)
|
|
||||||
|
|
||||||
-- Mark unit spawn points for debugging.
|
|
||||||
--unit:GetCoordinate():MarkToAll(string.format("unit %s distance to rwy %d = %d",unit:GetName(),_i, dist))
|
|
||||||
|
|
||||||
-- Check if unit is withing radius.
|
|
||||||
if dist<radius then
|
|
||||||
self:E(string.format("%s, unit %s of group %s was spawned on runway #%d. Distance %.1f < radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
|
||||||
--unit:FlareRed()
|
|
||||||
if despawn then
|
|
||||||
group:Destroy(true)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
self:T(string.format("%s, unit %s of group %s was NOT spawned on runway #%d. Distance %.1f > radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
|
||||||
--unit:FlareGreen()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self:T(string.format("%s, checking if unit %s of group %s is on runway. Unit is NOT alive.",self:GetName(), unit:GetName(), group:GetName()))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self:T(string.format("%s, checking if group %s is on runway. Group is NOT alive.",self:GetName(), group:GetName()))
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get category of airbase.
|
|
||||||
-- @param #AIRBASE self
|
|
||||||
-- @return #number Category of airbase from GetDesc().category.
|
|
||||||
function AIRBASE:GetAirbaseCategory()
|
|
||||||
local desc=self:GetDesc()
|
|
||||||
local category=Airbase.Category.AIRDROME
|
|
||||||
|
|
||||||
if desc and desc.category then
|
|
||||||
category=desc.category
|
|
||||||
else
|
|
||||||
self:E(string.format("ERROR: Cannot get category of airbase %s due to DCS 2.5.6 bug! Assuming it is an AIRDROME for now...", tostring(self.AirbaseName)))
|
|
||||||
end
|
|
||||||
return category
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Helper function to check for the correct terminal type including "artificial" ones.
|
--- Helper function to check for the correct terminal type including "artificial" ones.
|
||||||
-- @param #number Term_Type Termial type from getParking routine.
|
-- @param #number Term_Type Termial type from getParking routine.
|
||||||
-- @param #AIRBASE.TerminalType termtype Terminal type from AIRBASE.TerminalType enumerator.
|
-- @param #AIRBASE.TerminalType termtype Terminal type from AIRBASE.TerminalType enumerator.
|
||||||
@ -1180,6 +1225,10 @@ function AIRBASE._CheckTerminalType(Term_Type, termtype)
|
|||||||
return match
|
return match
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Runway
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
--- Get runways data. Only for airdromes!
|
--- Get runways data. Only for airdromes!
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #number magvar (Optional) Magnetic variation in degrees.
|
-- @param #number magvar (Optional) Magnetic variation in degrees.
|
||||||
@ -1194,41 +1243,124 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get spawn points on runway.
|
-- Get spawn points on runway. These can be used to determine the runway heading.
|
||||||
local runwaycoords=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
|
local runwaycoords=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
|
||||||
|
|
||||||
|
-- Debug: For finding the numbers of the spawn points belonging to each runway.
|
||||||
|
if false then
|
||||||
|
for i,_coord in pairs(runwaycoords) do
|
||||||
|
local coord=_coord --Core.Point#COORDINATE
|
||||||
|
coord:Translate(100, 0):MarkToAll("Runway i="..i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Magnetic declination.
|
-- Magnetic declination.
|
||||||
magvar=magvar or UTILS.GetMagneticDeclination()
|
magvar=magvar or UTILS.GetMagneticDeclination()
|
||||||
|
|
||||||
|
-- Number of runways.
|
||||||
local N=#runwaycoords
|
local N=#runwaycoords
|
||||||
local dN=2
|
local N2=N/2
|
||||||
local ex=false
|
local exception=false
|
||||||
|
|
||||||
|
-- Airbase name.
|
||||||
local name=self:GetName()
|
local name=self:GetName()
|
||||||
|
|
||||||
|
|
||||||
|
-- Exceptions
|
||||||
if name==AIRBASE.Nevada.Jean_Airport or
|
if name==AIRBASE.Nevada.Jean_Airport or
|
||||||
name==AIRBASE.Nevada.Creech_AFB or
|
name==AIRBASE.Nevada.Creech_AFB or
|
||||||
name==AIRBASE.PersianGulf.Abu_Dhabi_International_Airport or
|
name==AIRBASE.PersianGulf.Abu_Dhabi_International_Airport or
|
||||||
name==AIRBASE.PersianGulf.Dubai_Intl or
|
name==AIRBASE.PersianGulf.Dubai_Intl or
|
||||||
name==AIRBASE.PersianGulf.Shiraz_International_Airport or
|
name==AIRBASE.PersianGulf.Shiraz_International_Airport or
|
||||||
name==AIRBASE.PersianGulf.Kish_International_Airport then
|
name==AIRBASE.PersianGulf.Kish_International_Airport
|
||||||
|
then
|
||||||
|
|
||||||
N=#runwaycoords/2
|
-- 1-->4, 2-->3, 3-->2, 4-->1
|
||||||
dN=1
|
exception=1
|
||||||
ex=true
|
|
||||||
|
elseif UTILS.GetDCSMap()==DCSMAP.Syria and N>=2 and
|
||||||
|
name~=AIRBASE.Syria.Minakh and
|
||||||
|
name~=AIRBASE.Syria.Damascus and
|
||||||
|
name~=AIRBASE.Syria.Khalkhalah and
|
||||||
|
name~=AIRBASE.Syria.Marj_Ruhayyil and
|
||||||
|
name~=AIRBASE.Syria.Beirut_Rafic_Hariri then
|
||||||
|
|
||||||
|
-- 1-->3, 2-->4, 3-->1, 4-->2
|
||||||
|
exception=2
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local function f(i)
|
||||||
|
|
||||||
|
local j
|
||||||
|
|
||||||
|
if exception==1 then
|
||||||
|
|
||||||
|
j=N-(i+1) -- 1-->4, 2-->3
|
||||||
|
|
||||||
|
elseif exception==2 then
|
||||||
|
|
||||||
|
if i<=N2 then
|
||||||
|
j=i+N2 -- 1-->3, 2-->4
|
||||||
|
else
|
||||||
|
j=i-N2 -- 3-->1, 4-->3
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if i%2==0 then
|
||||||
|
j=i-1 -- even 2-->1, 4-->3
|
||||||
|
else
|
||||||
|
j=i+1 -- odd 1-->2, 3-->4
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Special case where there is no obvious order.
|
||||||
|
if name==AIRBASE.Syria.Beirut_Rafic_Hariri then
|
||||||
|
if i==1 then
|
||||||
|
j=3
|
||||||
|
elseif i==2 then
|
||||||
|
j=6
|
||||||
|
elseif i==3 then
|
||||||
|
j=1
|
||||||
|
elseif i==4 then
|
||||||
|
j=5
|
||||||
|
elseif i==5 then
|
||||||
|
j=4
|
||||||
|
elseif i==6 then
|
||||||
|
j=2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if name==AIRBASE.Syria.Ramat_David then
|
||||||
|
if i==1 then
|
||||||
|
j=4
|
||||||
|
elseif i==2 then
|
||||||
|
j=6
|
||||||
|
elseif i==3 then
|
||||||
|
j=5
|
||||||
|
elseif i==4 then
|
||||||
|
j=1
|
||||||
|
elseif i==5 then
|
||||||
|
j=3
|
||||||
|
elseif i==6 then
|
||||||
|
j=2
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return j
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
for i=1,N,dN do
|
for i=1,N do
|
||||||
|
|
||||||
local j=i+1
|
-- Get the other spawn point coordinate.
|
||||||
if ex then
|
local j=f(i)
|
||||||
--j=N+i
|
|
||||||
j=#runwaycoords-i+1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Coordinates of the two runway points.
|
-- Coordinates of the two runway points.
|
||||||
local c1=runwaycoords[i] --Core.Point#COORDINATES
|
local c1=runwaycoords[i] --Core.Point#COORDINATE
|
||||||
local c2=runwaycoords[j] --Core.Point#COORDINATES
|
local c2=runwaycoords[j] --Core.Point#COORDINATE
|
||||||
|
|
||||||
-- Heading of runway.
|
-- Heading of runway.
|
||||||
local hdg=c1:HeadingTo(c2)
|
local hdg=c1:HeadingTo(c2)
|
||||||
@ -1245,11 +1377,11 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
runway.endpoint=c2
|
runway.endpoint=c2
|
||||||
|
|
||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T(string.format("Airbase %s: Adding runway id=%s, heading=%03d, length=%d m", self:GetName(), runway.idx, runway.heading, runway.length))
|
self:I(string.format("Airbase %s: Adding runway id=%s, heading=%03d, length=%d m i=%d j=%d", self:GetName(), runway.idx, runway.heading, runway.length, i, j))
|
||||||
|
|
||||||
-- Debug mark
|
-- Debug mark
|
||||||
if mark then
|
if mark then
|
||||||
runway.position:MarkToAll(string.format("Runway %s: true heading=%03d (magvar=%d), length=%d m", runway.idx, runway.heading, magvar, runway.length))
|
runway.position:MarkToAll(string.format("Runway %s: true heading=%03d (magvar=%d), length=%d m, i=%d, j=%d", runway.idx, runway.heading, magvar, runway.length, i, j))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Add runway.
|
-- Add runway.
|
||||||
@ -1257,38 +1389,6 @@ function AIRBASE:GetRunwayData(magvar, mark)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get inverse runways
|
|
||||||
local inverse={}
|
|
||||||
for _,_runway in pairs(runways) do
|
|
||||||
local r=_runway --#AIRBASE.Runway
|
|
||||||
|
|
||||||
local runway={} --#AIRBASE.Runway
|
|
||||||
runway.heading=r.heading-180
|
|
||||||
if runway.heading<0 then
|
|
||||||
runway.heading=runway.heading+360
|
|
||||||
end
|
|
||||||
runway.idx=string.format("%02d", math.max(0, UTILS.Round((runway.heading-magvar)/10, 0)))
|
|
||||||
runway.length=r.length
|
|
||||||
runway.position=r.endpoint
|
|
||||||
runway.endpoint=r.position
|
|
||||||
|
|
||||||
-- Debug info.
|
|
||||||
self:T(string.format("Airbase %s: Adding runway id=%s, heading=%03d, length=%d m", self:GetName(), runway.idx, runway.heading, runway.length))
|
|
||||||
|
|
||||||
-- Debug mark
|
|
||||||
if mark then
|
|
||||||
runway.position:MarkToAll(string.format("Runway %s: true heading=%03d (magvar=%d), length=%d m", runway.idx, runway.heading, magvar, runway.length))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add runway.
|
|
||||||
table.insert(inverse, runway)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add inverse runway.
|
|
||||||
for _,runway in pairs(inverse) do
|
|
||||||
table.insert(runways, runway)
|
|
||||||
end
|
|
||||||
|
|
||||||
return runways
|
return runways
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1359,5 +1459,72 @@ function AIRBASE:GetActiveRunway(magvar)
|
|||||||
return runways[iact]
|
return runways[iact]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Function that checks if at leat one unit of a group has been spawned close to a spawn point on the runway.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param Wrapper.Group#GROUP group Group to be checked.
|
||||||
|
-- @param #number radius Radius around the spawn point to be checked. Default is 50 m.
|
||||||
|
-- @param #boolean despawn If true, the group is destroyed.
|
||||||
|
-- @return #boolean True if group is within radius around spawn points on runway.
|
||||||
|
function AIRBASE:CheckOnRunWay(group, radius, despawn)
|
||||||
|
|
||||||
|
-- Default radius.
|
||||||
|
radius=radius or 50
|
||||||
|
|
||||||
|
-- We only check at real airbases (not FARPS or ships).
|
||||||
|
if self:GetAirbaseCategory()~=Airbase.Category.AIRDROME then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if group and group:IsAlive() then
|
||||||
|
|
||||||
|
-- Debug.
|
||||||
|
self:T(string.format("%s, checking if group %s is on runway?",self:GetName(), group:GetName()))
|
||||||
|
|
||||||
|
-- Get coordinates on runway.
|
||||||
|
local runwaypoints=self:GetParkingSpotsCoordinates(AIRBASE.TerminalType.Runway)
|
||||||
|
|
||||||
|
-- Get units of group.
|
||||||
|
local units=group:GetUnits()
|
||||||
|
|
||||||
|
-- Loop over units.
|
||||||
|
for _,_unit in pairs(units) do
|
||||||
|
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
-- Check if unit is alive and not in air.
|
||||||
|
if unit and unit:IsAlive() and not unit:InAir() then
|
||||||
|
self:T(string.format("%s, checking if unit %s is on runway?",self:GetName(), unit:GetName()))
|
||||||
|
|
||||||
|
-- Loop over runway spawn points.
|
||||||
|
for _i,_coord in pairs(runwaypoints) do
|
||||||
|
|
||||||
|
-- Distance between unit and spawn pos.
|
||||||
|
local dist=unit:GetCoordinate():Get2DDistance(_coord)
|
||||||
|
|
||||||
|
-- Mark unit spawn points for debugging.
|
||||||
|
--unit:GetCoordinate():MarkToAll(string.format("unit %s distance to rwy %d = %d",unit:GetName(),_i, dist))
|
||||||
|
|
||||||
|
-- Check if unit is withing radius.
|
||||||
|
if dist<radius then
|
||||||
|
self:E(string.format("%s, unit %s of group %s was spawned on runway #%d. Distance %.1f < radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
||||||
|
--unit:FlareRed()
|
||||||
|
if despawn then
|
||||||
|
group:Destroy(true)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
self:T(string.format("%s, unit %s of group %s was NOT spawned on runway #%d. Distance %.1f > radius %.1f m. Despawn = %s.", self:GetName(), unit:GetName(), group:GetName(),_i, dist, radius, tostring(despawn)))
|
||||||
|
--unit:FlareGreen()
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:T(string.format("%s, checking if unit %s of group %s is on runway. Unit is NOT alive.",self:GetName(), unit:GetName(), group:GetName()))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
self:T(string.format("%s, checking if group %s is on runway. Group is NOT alive.",self:GetName(), group:GetName()))
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|||||||
@ -243,8 +243,7 @@ end
|
|||||||
|
|
||||||
--- Returns the initial health.
|
--- Returns the initial health.
|
||||||
-- @param #CONTROLLABLE self
|
-- @param #CONTROLLABLE self
|
||||||
-- @return #number The controllable health value (unit or group average).
|
-- @return #number The controllable health value (unit or group average) or `nil` if the controllable does not exist.
|
||||||
-- @return #nil The controllable is not existing or alive.
|
|
||||||
function CONTROLLABLE:GetLife0()
|
function CONTROLLABLE:GetLife0()
|
||||||
self:F2( self.ControllableName )
|
self:F2( self.ControllableName )
|
||||||
|
|
||||||
@ -296,7 +295,6 @@ end
|
|||||||
-- @return #nil The CONTROLLABLE is not existing or alive.
|
-- @return #nil The CONTROLLABLE is not existing or alive.
|
||||||
function CONTROLLABLE:GetFuel()
|
function CONTROLLABLE:GetFuel()
|
||||||
self:F( self.ControllableName )
|
self:F( self.ControllableName )
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -803,7 +801,7 @@ function CONTROLLABLE:CommandSetFrequency(Frequency, Modulation, Delay)
|
|||||||
local CommandSetFrequency = {
|
local CommandSetFrequency = {
|
||||||
id = 'SetFrequency',
|
id = 'SetFrequency',
|
||||||
params = {
|
params = {
|
||||||
frequency = Frequency,
|
frequency = Frequency*1000000,
|
||||||
modulation = Modulation or radio.modulation.AM,
|
modulation = Modulation or radio.modulation.AM,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1429,16 +1427,6 @@ end
|
|||||||
-- @return DCS#Task The DCS task structure.
|
-- @return DCS#Task The DCS task structure.
|
||||||
function CONTROLLABLE:TaskFireAtPoint( Vec2, Radius, AmmoCount, WeaponType )
|
function CONTROLLABLE:TaskFireAtPoint( Vec2, Radius, AmmoCount, WeaponType )
|
||||||
|
|
||||||
-- FireAtPoint = {
|
|
||||||
-- id = 'FireAtPoint',
|
|
||||||
-- params = {
|
|
||||||
-- point = Vec2,
|
|
||||||
-- radius = Distance,
|
|
||||||
-- expendQty = number,
|
|
||||||
-- expendQtyEnabled = boolean,
|
|
||||||
-- }
|
|
||||||
-- }
|
|
||||||
|
|
||||||
local DCSTask = {
|
local DCSTask = {
|
||||||
id = 'FireAtPoint',
|
id = 'FireAtPoint',
|
||||||
params = {
|
params = {
|
||||||
@ -1458,7 +1446,6 @@ function CONTROLLABLE:TaskFireAtPoint( Vec2, Radius, AmmoCount, WeaponType )
|
|||||||
DCSTask.params.weaponType=WeaponType
|
DCSTask.params.weaponType=WeaponType
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T3( { DCSTask } )
|
|
||||||
return DCSTask
|
return DCSTask
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1481,8 +1468,8 @@ end
|
|||||||
-- @param #number WeaponType Bitmask of weapon types, which are allowed to use.
|
-- @param #number WeaponType Bitmask of weapon types, which are allowed to use.
|
||||||
-- @param DCS#AI.Task.Designation Designation (Optional) Designation type.
|
-- @param DCS#AI.Task.Designation Designation (Optional) Designation type.
|
||||||
-- @param #boolean Datalink (Optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default.
|
-- @param #boolean Datalink (Optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default.
|
||||||
-- @param #number Frequency Frequency used to communicate with the FAC.
|
-- @param #number Frequency Frequency in MHz used to communicate with the FAC. Default 133 MHz.
|
||||||
-- @param #number Modulation Modulation of radio for communication.
|
-- @param #number Modulation Modulation of radio for communication. Default 0=AM.
|
||||||
-- @param #number CallsignName Callsign enumerator name of the FAC.
|
-- @param #number CallsignName Callsign enumerator name of the FAC.
|
||||||
-- @param #number CallsignNumber Callsign number, e.g. Axeman-**1**.
|
-- @param #number CallsignNumber Callsign number, e.g. Axeman-**1**.
|
||||||
-- @return DCS#Task The DCS task structure.
|
-- @return DCS#Task The DCS task structure.
|
||||||
@ -1492,11 +1479,11 @@ function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation,
|
|||||||
id = 'FAC_AttackGroup',
|
id = 'FAC_AttackGroup',
|
||||||
params = {
|
params = {
|
||||||
groupId = AttackGroup:GetID(),
|
groupId = AttackGroup:GetID(),
|
||||||
weaponType = WeaponType,
|
weaponType = WeaponType or ENUMS.WeaponFlag.AutoDCS,
|
||||||
designation = Designation,
|
designation = Designation or "Auto",
|
||||||
datalink = Datalink,
|
datalink = Datalink and Datalink or true,
|
||||||
frequency = Frequency,
|
frequency = (Frequency or 133)*1000000,
|
||||||
modulation = Modulation,
|
modulation = Modulation or radio.modulation.AM,
|
||||||
callname = CallsignName,
|
callname = CallsignName,
|
||||||
number = CallsignNumber,
|
number = CallsignNumber,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -261,7 +261,9 @@ end
|
|||||||
-- @param #string GroupName The Group name
|
-- @param #string GroupName The Group name
|
||||||
-- @return #GROUP self
|
-- @return #GROUP self
|
||||||
function GROUP:Register( GroupName )
|
function GROUP:Register( GroupName )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, CONTROLLABLE:New( GroupName ) ) -- #GROUP
|
local self = BASE:Inherit( self, CONTROLLABLE:New( GroupName ) ) -- #GROUP
|
||||||
|
|
||||||
self.GroupName = GroupName
|
self.GroupName = GroupName
|
||||||
|
|
||||||
self:SetEventPriority( 4 )
|
self:SetEventPriority( 4 )
|
||||||
@ -668,14 +670,15 @@ end
|
|||||||
-- @param #number UnitNumber The number of the UNIT wrapper class to be returned.
|
-- @param #number UnitNumber The number of the UNIT wrapper class to be returned.
|
||||||
-- @return Wrapper.Unit#UNIT The UNIT wrapper class.
|
-- @return Wrapper.Unit#UNIT The UNIT wrapper class.
|
||||||
function GROUP:GetUnit( UnitNumber )
|
function GROUP:GetUnit( UnitNumber )
|
||||||
self:F3( { self.GroupName, UnitNumber } )
|
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
|
|
||||||
local DCSUnit = DCSGroup:getUnit( UnitNumber )
|
local DCSUnit = DCSGroup:getUnit( UnitNumber )
|
||||||
local UnitFound = UNIT:Find( DCSGroup:getUnit( UnitNumber ) )
|
|
||||||
self:T2( UnitFound )
|
local UnitFound = UNIT:Find(DCSUnit)
|
||||||
|
|
||||||
return UnitFound
|
return UnitFound
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -688,13 +691,11 @@ end
|
|||||||
-- @param #number UnitNumber The number of the DCS Unit to be returned.
|
-- @param #number UnitNumber The number of the DCS Unit to be returned.
|
||||||
-- @return DCS#Unit The DCS Unit.
|
-- @return DCS#Unit The DCS Unit.
|
||||||
function GROUP:GetDCSUnit( UnitNumber )
|
function GROUP:GetDCSUnit( UnitNumber )
|
||||||
self:F3( { self.GroupName, UnitNumber } )
|
|
||||||
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup=self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
local DCSUnitFound = DCSGroup:getUnit( UnitNumber )
|
local DCSUnitFound=DCSGroup:getUnit( UnitNumber )
|
||||||
self:T3( DCSUnitFound )
|
|
||||||
return DCSUnitFound
|
return DCSUnitFound
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -706,14 +707,14 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return #number The DCS Group size.
|
-- @return #number The DCS Group size.
|
||||||
function GROUP:GetSize()
|
function GROUP:GetSize()
|
||||||
self:F3( { self.GroupName } )
|
|
||||||
local DCSGroup = self:GetDCSObject()
|
local DCSGroup = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSGroup then
|
if DCSGroup then
|
||||||
|
|
||||||
local GroupSize = DCSGroup:getSize()
|
local GroupSize = DCSGroup:getSize()
|
||||||
|
|
||||||
if GroupSize then
|
if GroupSize then
|
||||||
self:T3( GroupSize )
|
|
||||||
return GroupSize
|
return GroupSize
|
||||||
else
|
else
|
||||||
return 0
|
return 0
|
||||||
@ -946,24 +947,29 @@ end
|
|||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return DCS#Vec2 Current Vec2 point of the first DCS Unit of the DCS Group.
|
-- @return DCS#Vec2 Current Vec2 point of the first DCS Unit of the DCS Group.
|
||||||
function GROUP:GetVec2()
|
function GROUP:GetVec2()
|
||||||
self:F2( self.GroupName )
|
|
||||||
|
|
||||||
local UnitPoint = self:GetUnit(1)
|
local Unit=self:GetUnit(1)
|
||||||
UnitPoint:GetVec2()
|
|
||||||
local GroupPointVec2 = UnitPoint:GetVec2()
|
if Unit then
|
||||||
self:T3( GroupPointVec2 )
|
return Unit:GetVec2()
|
||||||
return GroupPointVec2
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the current Vec3 vector of the first DCS Unit in the GROUP.
|
--- Returns the current Vec3 vector of the first DCS Unit in the GROUP.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @return DCS#Vec3 Current Vec3 of the first DCS Unit of the GROUP.
|
-- @return DCS#Vec3 Current Vec3 of the first DCS Unit of the GROUP.
|
||||||
function GROUP:GetVec3()
|
function GROUP:GetVec3()
|
||||||
self:F2( self.GroupName )
|
|
||||||
|
|
||||||
local GroupVec3 = self:GetUnit(1):GetVec3()
|
-- Get first unit.
|
||||||
self:T3( GroupVec3 )
|
local unit=self:GetUnit(1)
|
||||||
return GroupVec3
|
|
||||||
|
if unit then
|
||||||
|
return unit:GetVec3()
|
||||||
|
end
|
||||||
|
|
||||||
|
self:E("ERROR: Cannot get Vec3 of group "..tostring(self.GroupName))
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns a POINT_VEC2 object indicating the point in 2D of the first UNIT of the GROUP within the mission.
|
--- Returns a POINT_VEC2 object indicating the point in 2D of the first UNIT of the GROUP within the mission.
|
||||||
@ -1039,11 +1045,16 @@ function GROUP:GetHeading()
|
|||||||
local GroupSize = self:GetSize()
|
local GroupSize = self:GetSize()
|
||||||
local HeadingAccumulator = 0
|
local HeadingAccumulator = 0
|
||||||
|
|
||||||
|
local n=0
|
||||||
if GroupSize then
|
if GroupSize then
|
||||||
for i = 1, GroupSize do
|
for i = 1, GroupSize do
|
||||||
HeadingAccumulator = HeadingAccumulator + self:GetUnit(i):GetHeading()
|
local unit=self:GetUnit(i)
|
||||||
|
if unit and unit:IsAlive() then
|
||||||
|
HeadingAccumulator = HeadingAccumulator + unit:GetHeading()
|
||||||
|
n=n+1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return math.floor(HeadingAccumulator / GroupSize)
|
return math.floor(HeadingAccumulator / n)
|
||||||
end
|
end
|
||||||
|
|
||||||
BASE:E( { "Cannot GetHeading", Group = self, Alive = self:IsAlive() } )
|
BASE:E( { "Cannot GetHeading", Group = self, Alive = self:IsAlive() } )
|
||||||
@ -1161,6 +1172,32 @@ end
|
|||||||
|
|
||||||
do -- Is Zone methods
|
do -- Is Zone methods
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if any unit of a group is inside a @{Zone}.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
|
-- @return #boolean Returns true if at least one unit is inside the zone or false if no unit is inside.
|
||||||
|
function GROUP:IsInZone( Zone )
|
||||||
|
|
||||||
|
if self:IsAlive() then
|
||||||
|
|
||||||
|
for UnitID, UnitData in pairs(self:GetUnits()) do
|
||||||
|
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
if Zone:IsVec3InZone(Unit:GetVec3()) then
|
||||||
|
return true -- At least one unit is in the zone. That is enough.
|
||||||
|
else
|
||||||
|
-- This one is not but another could be.
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns true if all units of the group are within a @{Zone}.
|
--- Returns true if all units of the group are within a @{Zone}.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
@ -2095,6 +2132,7 @@ end
|
|||||||
|
|
||||||
--- Calculate the maxium A2G threat level of the Group.
|
--- Calculate the maxium A2G threat level of the Group.
|
||||||
-- @param #GROUP self
|
-- @param #GROUP self
|
||||||
|
-- @return #number Number between 0 and 10.
|
||||||
function GROUP:CalculateThreatLevelA2G()
|
function GROUP:CalculateThreatLevelA2G()
|
||||||
|
|
||||||
local MaxThreatLevelA2G = 0
|
local MaxThreatLevelA2G = 0
|
||||||
@ -2110,6 +2148,25 @@ function GROUP:CalculateThreatLevelA2G()
|
|||||||
return MaxThreatLevelA2G
|
return MaxThreatLevelA2G
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get threat level of the group.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return #number Max threat level (a number between 0 and 10).
|
||||||
|
function GROUP:GetThreatLevel()
|
||||||
|
|
||||||
|
local threatlevelMax = 0
|
||||||
|
for UnitName, UnitData in pairs(self:GetUnits()) do
|
||||||
|
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
local threatlevel = ThreatUnit:GetThreatLevel()
|
||||||
|
if threatlevel > threatlevelMax then
|
||||||
|
threatlevelMax=threatlevel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return threatlevelMax
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns true if the first unit of the GROUP is in the air.
|
--- Returns true if the first unit of the GROUP is in the air.
|
||||||
-- @param Wrapper.Group#GROUP self
|
-- @param Wrapper.Group#GROUP self
|
||||||
-- @return #boolean true if in the first unit of the group is in the air or #nil if the GROUP is not existing or not alive.
|
-- @return #boolean true if in the first unit of the group is in the air or #nil if the GROUP is not existing or not alive.
|
||||||
|
|||||||
776
Moose Development/Moose/Wrapper/Marker.lua
Normal file
776
Moose Development/Moose/Wrapper/Marker.lua
Normal file
@ -0,0 +1,776 @@
|
|||||||
|
--- **Wrapper** - Markers On the F10 map.
|
||||||
|
--
|
||||||
|
-- **Main Features:**
|
||||||
|
--
|
||||||
|
-- * Convenient handling of markers via multiple user API functions.
|
||||||
|
-- * Update text and position of marker easily via scripting.
|
||||||
|
-- * Delay creation and removal of markers via (optional) parameters.
|
||||||
|
-- * Retrieve data such as text and coordinate.
|
||||||
|
-- * Marker specific FSM events when a marker is added, removed or changed.
|
||||||
|
-- * Additional FSM events when marker text or position is changed.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **funkyfranky**
|
||||||
|
-- @module Wrapper.Marker
|
||||||
|
-- @image Wrapper_Marker.png
|
||||||
|
|
||||||
|
|
||||||
|
--- Marker class.
|
||||||
|
-- @type MARKER
|
||||||
|
-- @field #string ClassName Name of the class.
|
||||||
|
-- @field #boolean Debug Debug mode. Messages to all about status.
|
||||||
|
-- @field #string lid Class id string for output to DCS log file.
|
||||||
|
-- @field #number mid Marker ID.
|
||||||
|
-- @field Core.Point#COORDINATE coordinate Coordinate of the mark.
|
||||||
|
-- @field #string text Text displayed in the mark panel.
|
||||||
|
-- @field #string message Message dispayed when the mark is added.
|
||||||
|
-- @field #boolean readonly Marker is read-only.
|
||||||
|
-- @field #number coalition Coalition to which the marker is displayed.
|
||||||
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
|
--- Just because...
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- 
|
||||||
|
--
|
||||||
|
-- # The MARKER Class Idea
|
||||||
|
--
|
||||||
|
-- The MARKER class simplifies creating, updating and removing of markers on the F10 map.
|
||||||
|
--
|
||||||
|
-- # Create a Marker
|
||||||
|
--
|
||||||
|
-- -- Create a MARKER object at Batumi with a trivial text.
|
||||||
|
-- local Coordinate=AIRBASE:FindByName("Batumi"):GetCoordinate()
|
||||||
|
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield")
|
||||||
|
--
|
||||||
|
-- Now this does **not** show the marker yet. We still need to specifiy to whom it is shown. There are several options, i.e.
|
||||||
|
-- show the marker to everyone, to a speficic coaliton only, or only to a specific group.
|
||||||
|
--
|
||||||
|
-- ## For Everyone
|
||||||
|
--
|
||||||
|
-- If the marker should be visible to everyone, you can use the :ToAll() function.
|
||||||
|
--
|
||||||
|
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToAll()
|
||||||
|
--
|
||||||
|
-- ## For a Coaliton
|
||||||
|
--
|
||||||
|
-- If the maker should be visible to a specific coalition, you can use the :ToCoalition() function.
|
||||||
|
--
|
||||||
|
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToCoaliton(coaliton.side.BLUE)
|
||||||
|
--
|
||||||
|
-- ### To Blue Coaliton
|
||||||
|
--
|
||||||
|
-- ### To Red Coalition
|
||||||
|
--
|
||||||
|
-- This would show the marker only to the Blue coaliton.
|
||||||
|
--
|
||||||
|
-- ## For a Group
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- # Removing a Marker
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- # Updating a Marker
|
||||||
|
--
|
||||||
|
-- The marker text and coordinate can be updated easily as shown below.
|
||||||
|
--
|
||||||
|
-- However, note that **updateing involves to remove and recreate the marker if either text or its coordinate is changed**.
|
||||||
|
-- *This is a DCS scripting engine limitation.*
|
||||||
|
--
|
||||||
|
-- ## Update Text
|
||||||
|
--
|
||||||
|
-- If you created a marker "mymarker" as shown above, you can update the dispayed test by
|
||||||
|
--
|
||||||
|
-- mymarker:UpdateText("I am the new text at Batumi")
|
||||||
|
--
|
||||||
|
-- The update can also be delayed by, e.g. 90 seconds, using
|
||||||
|
--
|
||||||
|
-- mymarker:UpdateText("I am the new text at Batumi", 90)
|
||||||
|
--
|
||||||
|
-- ## Update Coordinate
|
||||||
|
--
|
||||||
|
-- If you created a marker "mymarker" as shown above, you can update its coordinate on the F10 map by
|
||||||
|
--
|
||||||
|
-- mymarker:UpdateCoordinate(NewCoordinate)
|
||||||
|
--
|
||||||
|
-- The update can also be delayed by, e.g. 60 seconds, using
|
||||||
|
--
|
||||||
|
-- mymarker:UpdateCoordinate(NewCoordinate, 60)
|
||||||
|
--
|
||||||
|
-- # Retrieve Data
|
||||||
|
--
|
||||||
|
-- The important data as the displayed text and the coordinate of the marker can be retrieved easily.
|
||||||
|
--
|
||||||
|
-- ## Text
|
||||||
|
--
|
||||||
|
-- local text=mymarker:GetText()
|
||||||
|
-- env.info("Marker Text = " .. text)
|
||||||
|
--
|
||||||
|
-- ## Coordinate
|
||||||
|
--
|
||||||
|
-- local Coordinate=mymarker:GetCoordinate()
|
||||||
|
-- env.info("Marker Coordinate LL DSM = " .. Coordinate:ToStringLLDMS())
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- # FSM Events
|
||||||
|
--
|
||||||
|
-- Moose creates addditonal events, so called FSM event, when markers are added, changed, removed, and text or the coordianteis updated.
|
||||||
|
--
|
||||||
|
-- These events can be captured and used for processing via OnAfter functions as shown below.
|
||||||
|
--
|
||||||
|
-- ## Added
|
||||||
|
--
|
||||||
|
-- ## Changed
|
||||||
|
--
|
||||||
|
-- ## Removed
|
||||||
|
--
|
||||||
|
-- ## TextUpdate
|
||||||
|
--
|
||||||
|
-- ## CoordUpdate
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- # Examples
|
||||||
|
--
|
||||||
|
--
|
||||||
|
-- @field #MARKER
|
||||||
|
MARKER = {
|
||||||
|
ClassName = "MARKER",
|
||||||
|
Debug = false,
|
||||||
|
lid = nil,
|
||||||
|
mid = nil,
|
||||||
|
coordinate = nil,
|
||||||
|
text = nil,
|
||||||
|
message = nil,
|
||||||
|
readonly = nil,
|
||||||
|
coalition = nil,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Marker ID. Running number.
|
||||||
|
_MARKERID=0
|
||||||
|
|
||||||
|
--- Marker class version.
|
||||||
|
-- @field #string version
|
||||||
|
MARKER.version="0.1.0"
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- TODO list
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- TODO: User "Get" functions. E.g., :GetCoordinate()
|
||||||
|
-- DONE: Add delay to user functions.
|
||||||
|
-- DONE: Handle events.
|
||||||
|
-- DONE: Create FSM events.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Constructor
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create a new MARKER class object.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate Coordinate where to place the marker.
|
||||||
|
-- @param #string Text Text displayed on the mark panel.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:New(Coordinate, Text)
|
||||||
|
|
||||||
|
-- Inherit everything from FSM class.
|
||||||
|
local self=BASE:Inherit(self, FSM:New()) -- #MARKER
|
||||||
|
|
||||||
|
self.coordinate=Coordinate
|
||||||
|
|
||||||
|
self.text=Text
|
||||||
|
|
||||||
|
-- Defaults
|
||||||
|
self.readonly=false
|
||||||
|
self.message=""
|
||||||
|
|
||||||
|
-- New marker ID. This is not the one of the actual marker.
|
||||||
|
_MARKERID=_MARKERID+1
|
||||||
|
|
||||||
|
self.myid=_MARKERID
|
||||||
|
|
||||||
|
-- Log ID.
|
||||||
|
self.lid=string.format("Marker #%d | ", self.myid)
|
||||||
|
|
||||||
|
-- Start State.
|
||||||
|
self:SetStartState("Invisible")
|
||||||
|
|
||||||
|
-- Add FSM transitions.
|
||||||
|
-- From State --> Event --> To State
|
||||||
|
self:AddTransition("Invisible", "Added", "Visible") -- Marker was added.
|
||||||
|
self:AddTransition("Visible", "Removed", "Invisible") -- Marker was removed.
|
||||||
|
self:AddTransition("*", "Changed", "*") -- Marker was changed.
|
||||||
|
|
||||||
|
self:AddTransition("*", "TextUpdate", "*") -- Text updated.
|
||||||
|
self:AddTransition("*", "CoordUpdate", "*") -- Coordinates updated.
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Added".
|
||||||
|
-- @function [parent=#MARKER] Added
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
--- Triggers the delayed FSM event "Added".
|
||||||
|
-- @function [parent=#MARKER] __Added
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
--- On after "Added" event user function.
|
||||||
|
-- @function [parent=#MARKER] OnAfterAdded
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Removed".
|
||||||
|
-- @function [parent=#MARKER] Removed
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
--- Triggers the delayed FSM event "Removed".
|
||||||
|
-- @function [parent=#MARKER] __Removed
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
--- On after "Removed" event user function.
|
||||||
|
-- @function [parent=#MARKER] OnAfterRemoved
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Changed".
|
||||||
|
-- @function [parent=#MARKER] Changed
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
--- Triggers the delayed FSM event "Changed".
|
||||||
|
-- @function [parent=#MARKER] __Changed
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
--- On after "Changed" event user function.
|
||||||
|
-- @function [parent=#MARKER] OnAfterChanged
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
|
||||||
|
|
||||||
|
--- Triggers the FSM event "TextUpdate".
|
||||||
|
-- @function [parent=#MARKER] TextUpdate
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string Text The new text.
|
||||||
|
|
||||||
|
--- Triggers the delayed FSM event "TextUpdate".
|
||||||
|
-- @function [parent=#MARKER] __TextUpdate
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string Text The new text.
|
||||||
|
|
||||||
|
--- On after "TextUpdate" event user function.
|
||||||
|
-- @function [parent=#MARKER] OnAfterTextUpdate
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #string Text The new text.
|
||||||
|
|
||||||
|
|
||||||
|
--- Triggers the FSM event "CoordUpdate".
|
||||||
|
-- @function [parent=#MARKER] CoordUpdate
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate The new Coordinate.
|
||||||
|
|
||||||
|
--- Triggers the delayed FSM event "CoordUpdate".
|
||||||
|
-- @function [parent=#MARKER] __CoordUpdate
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate The updated Coordinate.
|
||||||
|
|
||||||
|
--- On after "CoordUpdate" event user function.
|
||||||
|
-- @function [parent=#MARKER] OnAfterCoordUpdate
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate The updated Coordinate.
|
||||||
|
|
||||||
|
|
||||||
|
-- Handle events.
|
||||||
|
self:HandleEvent(EVENTS.MarkAdded)
|
||||||
|
self:HandleEvent(EVENTS.MarkRemoved)
|
||||||
|
self:HandleEvent(EVENTS.MarkChange)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- User API Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Marker is readonly. Text cannot be changed and marker cannot be removed.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:ReadOnly()
|
||||||
|
|
||||||
|
self.readonly=true
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set message that is displayed on screen if the marker is added.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string Text Message displayed when the marker is added.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:Message(Text)
|
||||||
|
|
||||||
|
self.message=Text or ""
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Place marker visible for everyone.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:ToAll(Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, MARKER.ToAll, self)
|
||||||
|
else
|
||||||
|
|
||||||
|
self.toall=true
|
||||||
|
self.tocoaliton=nil
|
||||||
|
self.coalition=nil
|
||||||
|
self.togroup=nil
|
||||||
|
self.groupname=nil
|
||||||
|
self.groupid=nil
|
||||||
|
|
||||||
|
-- First remove an existing mark.
|
||||||
|
if self.shown then
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.mid=UTILS.GetMarkID()
|
||||||
|
|
||||||
|
-- Call DCS function.
|
||||||
|
trigger.action.markToAll(self.mid, self.text, self.coordinate:GetVec3(), self.readonly, self.message)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Place marker visible for a specific coalition only.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #number Coalition Coalition 1=Red, 2=Blue, 0=Neutral. See `coaliton.side.RED`.
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:ToCoalition(Coalition, Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, MARKER.ToCoalition, self, Coalition)
|
||||||
|
else
|
||||||
|
|
||||||
|
self.coalition=Coalition
|
||||||
|
|
||||||
|
self.tocoaliton=true
|
||||||
|
self.toall=false
|
||||||
|
self.togroup=false
|
||||||
|
self.groupname=nil
|
||||||
|
self.groupid=nil
|
||||||
|
|
||||||
|
-- First remove an existing mark.
|
||||||
|
if self.shown then
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.mid=UTILS.GetMarkID()
|
||||||
|
|
||||||
|
-- Call DCS function.
|
||||||
|
trigger.action.markToCoalition(self.mid, self.text, self.coordinate:GetVec3(), self.coalition, self.readonly, self.message)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Place marker visible for the blue coalition only.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:ToBlue(Delay)
|
||||||
|
self:ToCoalition(coalition.side.BLUE, Delay)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Place marker visible for the blue coalition only.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:ToRed(Delay)
|
||||||
|
self:ToCoalition(coalition.side.RED, Delay)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Place marker visible for the neutral coalition only.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:ToNeutral(Delay)
|
||||||
|
self:ToCoalition(coalition.side.NEUTRAL, Delay)
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Place marker visible for a specific group only.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Wrapper.Group#GROUP Group The group to which the marker is displayed.
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:ToGroup(Group, Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, MARKER.ToGroup, self, Group)
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Check if group exists.
|
||||||
|
if Group and Group:IsAlive()~=nil then
|
||||||
|
|
||||||
|
self.groupid=Group:GetID()
|
||||||
|
|
||||||
|
if self.groupid then
|
||||||
|
|
||||||
|
self.groupname=Group:GetName()
|
||||||
|
|
||||||
|
self.togroup=true
|
||||||
|
self.tocoaliton=nil
|
||||||
|
self.coalition=nil
|
||||||
|
self.toall=nil
|
||||||
|
|
||||||
|
-- First remove an existing mark.
|
||||||
|
if self.shown then
|
||||||
|
self:Remove()
|
||||||
|
end
|
||||||
|
|
||||||
|
self.mid=UTILS.GetMarkID()
|
||||||
|
|
||||||
|
-- Call DCS function.
|
||||||
|
trigger.action.markToGroup(self.mid, self.text, self.coordinate:GetVec3(), self.groupid, self.readonly, self.message)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
--TODO: Warning!
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Update the text displayed on the mark panel.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string Text Updated text.
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:UpdateText(Text, Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, MARKER.UpdateText, self, Text)
|
||||||
|
else
|
||||||
|
|
||||||
|
self.text=tostring(Text)
|
||||||
|
|
||||||
|
self:Refresh()
|
||||||
|
|
||||||
|
self:TextUpdate(tostring(Text))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Update the coordinate where the marker is displayed.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate The new coordinate.
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:UpdateCoordinate(Coordinate, Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, MARKER.UpdateCoordinate, self, Coordinate)
|
||||||
|
else
|
||||||
|
|
||||||
|
self.coordinate=Coordinate
|
||||||
|
|
||||||
|
self:Refresh()
|
||||||
|
|
||||||
|
self:CoordUpdate(Coordinate)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Refresh the marker.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is created.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:Refresh(Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, MARKER.Refresh, self)
|
||||||
|
else
|
||||||
|
|
||||||
|
if self.toall then
|
||||||
|
|
||||||
|
self:ToAll()
|
||||||
|
|
||||||
|
elseif self.tocoaliton then
|
||||||
|
|
||||||
|
self:ToCoalition(self.coalition)
|
||||||
|
|
||||||
|
elseif self.togroup then
|
||||||
|
|
||||||
|
local group=GROUP:FindByName(self.groupname)
|
||||||
|
|
||||||
|
self:ToGroup(group)
|
||||||
|
|
||||||
|
else
|
||||||
|
self:E(self.lid.."ERROR: unknown To in :Refresh()!")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove a marker.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #number Delay (Optional) Delay in seconds, before the marker is removed.
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:Remove(Delay)
|
||||||
|
|
||||||
|
if Delay and Delay>0 then
|
||||||
|
self:ScheduleOnce(Delay, MARKER.Remove, self)
|
||||||
|
else
|
||||||
|
|
||||||
|
if self.shown then
|
||||||
|
|
||||||
|
-- Call DCS function.
|
||||||
|
trigger.action.removeMark(self.mid)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get position of the marker.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @return Core.Point#COORDINATE The coordinate of the marker.
|
||||||
|
function MARKER:GetCoordinate()
|
||||||
|
return self.coordinate
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get text that is displayed in the marker panel.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @return #string Marker text.
|
||||||
|
function MARKER:GetText()
|
||||||
|
return self.text
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Set text that is displayed in the marker panel. Note this does not show the marker.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string Text Marker text. Default is an empty sting "".
|
||||||
|
-- @return #MARKER self
|
||||||
|
function MARKER:SetText(Text)
|
||||||
|
self.text=Text and tostring(Text) or ""
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Check if marker is currently visible on the F10 map.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @return #boolean True if the marker is currently visible.
|
||||||
|
function MARKER:IsVisible()
|
||||||
|
return self:Is("Visible")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Check if marker is currently invisible on the F10 map.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @return
|
||||||
|
function MARKER:IsInvisible()
|
||||||
|
return self:Is("Invisible")
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Event Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Event function when a MARKER is added.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function MARKER:OnEventMarkAdded(EventData)
|
||||||
|
|
||||||
|
if EventData and EventData.MarkID then
|
||||||
|
|
||||||
|
local MarkID=EventData.MarkID
|
||||||
|
|
||||||
|
self:T3(self.lid..string.format("Captured event MarkAdded for Mark ID=%s", tostring(MarkID)))
|
||||||
|
|
||||||
|
if MarkID==self.mid then
|
||||||
|
|
||||||
|
self.shown=true
|
||||||
|
|
||||||
|
self:Added(EventData)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Event function when a MARKER is removed.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function MARKER:OnEventMarkRemoved(EventData)
|
||||||
|
|
||||||
|
if EventData and EventData.MarkID then
|
||||||
|
|
||||||
|
local MarkID=EventData.MarkID
|
||||||
|
|
||||||
|
self:T3(self.lid..string.format("Captured event MarkAdded for Mark ID=%s", tostring(MarkID)))
|
||||||
|
|
||||||
|
if MarkID==self.mid then
|
||||||
|
|
||||||
|
self.shown=false
|
||||||
|
|
||||||
|
self:Removed(EventData)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Event function when a MARKER changed.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData
|
||||||
|
function MARKER:OnEventMarkChange(EventData)
|
||||||
|
|
||||||
|
if EventData and EventData.MarkID then
|
||||||
|
|
||||||
|
local MarkID=EventData.MarkID
|
||||||
|
|
||||||
|
self:T3(self.lid..string.format("Captured event MarkChange for Mark ID=%s", tostring(MarkID)))
|
||||||
|
|
||||||
|
if MarkID==self.mid then
|
||||||
|
|
||||||
|
self:Changed(EventData)
|
||||||
|
|
||||||
|
self:TextChanged(tostring(EventData.MarkText))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- FSM Event Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- On after "Added" event.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
function MARKER:onafterAdded(From, Event, To, EventData)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("Captured event MarkAdded for myself:\n")
|
||||||
|
text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID))
|
||||||
|
text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition))
|
||||||
|
text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID))
|
||||||
|
text=text..string.format("Initiator = %s\n", EventData.IniUnit and EventData.IniUnit:GetName() or "Nobody")
|
||||||
|
text=text..string.format("Coordinate = %s\n", EventData.MarkCoordinate and EventData.MarkCoordinate:ToStringLLDMS() or "Nowhere")
|
||||||
|
text=text..string.format("Text: \n%s", tostring(EventData.MarkText))
|
||||||
|
self:T2(self.lid..text)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "Removed" event.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
function MARKER:onafterRemoved(From, Event, To, EventData)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("Captured event MarkRemoved for myself:\n")
|
||||||
|
text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID))
|
||||||
|
text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition))
|
||||||
|
text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID))
|
||||||
|
text=text..string.format("Initiator = %s\n", EventData.IniUnit and EventData.IniUnit:GetName() or "Nobody")
|
||||||
|
text=text..string.format("Coordinate = %s\n", EventData.MarkCoordinate and EventData.MarkCoordinate:ToStringLLDMS() or "Nowhere")
|
||||||
|
text=text..string.format("Text: \n%s", tostring(EventData.MarkText))
|
||||||
|
self:T2(self.lid..text)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "Changed" event.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data table.
|
||||||
|
function MARKER:onafterChanged(From, Event, To, EventData)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("Captured event MarkChange for myself:\n")
|
||||||
|
text=text..string.format("Marker ID = %s\n", tostring(EventData.MarkID))
|
||||||
|
text=text..string.format("Coalition = %s\n", tostring(EventData.MarkCoalition))
|
||||||
|
text=text..string.format("Group ID = %s\n", tostring(EventData.MarkGroupID))
|
||||||
|
text=text..string.format("Initiator = %s\n", EventData.IniUnit and EventData.IniUnit:GetName() or "Nobody")
|
||||||
|
text=text..string.format("Coordinate = %s\n", EventData.MarkCoordinate and EventData.MarkCoordinate:ToStringLLDMS() or "Nowhere")
|
||||||
|
text=text..string.format("Text: \n%s", tostring(EventData.MarkText))
|
||||||
|
self:T2(self.lid..text)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "TextUpdate" event.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param #string Text The updated text, displayed in the mark panel.
|
||||||
|
function MARKER:onafterTextUpdate(From, Event, To, Text)
|
||||||
|
|
||||||
|
self:T(self.lid..string.format("New Marker Text:\n%s", Text))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- On after "CoordUpdate" event.
|
||||||
|
-- @param #MARKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Core.Point#COORDINATE Coordinate The updated coordinates.
|
||||||
|
function MARKER:onafterCoordUpdate(From, Event, To, Coordinate)
|
||||||
|
|
||||||
|
self:T(self.lid..string.format("New Marker Coordinate in LL DMS: %s", Coordinate:ToStringLLDMS()))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -15,6 +15,8 @@
|
|||||||
-- @extends Wrapper.Identifiable#IDENTIFIABLE
|
-- @extends Wrapper.Identifiable#IDENTIFIABLE
|
||||||
|
|
||||||
--- @type POSITIONABLE
|
--- @type POSITIONABLE
|
||||||
|
-- @field Core.Point#COORDINATE coordinate Coordinate object.
|
||||||
|
-- @field Core.Point#POINT_VEC3 pointvec3 Point Vec3 object.
|
||||||
-- @extends Wrapper.Identifiable#IDENTIFIABLE
|
-- @extends Wrapper.Identifiable#IDENTIFIABLE
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +47,8 @@
|
|||||||
POSITIONABLE = {
|
POSITIONABLE = {
|
||||||
ClassName = "POSITIONABLE",
|
ClassName = "POSITIONABLE",
|
||||||
PositionableName = "",
|
PositionableName = "",
|
||||||
|
coordinate = nil,
|
||||||
|
pointvec3 = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- @field #POSITIONABLE.__
|
--- @field #POSITIONABLE.__
|
||||||
@ -121,10 +125,17 @@ function POSITIONABLE:Destroy( GenerateEvent )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns the DCS object. Polymorphic for other classes like UNIT, STATIC, GROUP, AIRBASE.
|
||||||
|
-- @param #POSITIONABLE self
|
||||||
|
-- @return DCS#Object The DCS object.
|
||||||
|
function POSITIONABLE:GetDCSObject()
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns a pos3 table of the objects current position and orientation in 3D space. X, Y, Z values are unit vectors defining the objects orientation.
|
--- Returns a pos3 table of the objects current position and orientation in 3D space. X, Y, Z values are unit vectors defining the objects orientation.
|
||||||
-- Coordinates are dependent on the position of the maps origin.
|
-- Coordinates are dependent on the position of the maps origin.
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
-- @return DCS#Position Table consisting of the point and orientation tables.
|
-- @return DCS#Position3 Table consisting of the point and orientation tables.
|
||||||
function POSITIONABLE:GetPosition()
|
function POSITIONABLE:GetPosition()
|
||||||
self:F2( self.PositionableName )
|
self:F2( self.PositionableName )
|
||||||
|
|
||||||
@ -215,27 +226,44 @@ function POSITIONABLE:GetPositionVec3()
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the @{DCS#Vec2} vector indicating the point in 2D of the POSITIONABLE within the mission.
|
--- Returns the @{DCS#Vec3} vector indicating the 3D vector of the POSITIONABLE within the mission.
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
-- @return DCS#Vec2 The 2D point vector of the POSITIONABLE.
|
-- @return DCS#Vec3 The 3D point vector of the POSITIONABLE or `nil` if it is not existing or alive.
|
||||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
function POSITIONABLE:GetVec3()
|
||||||
function POSITIONABLE:GetVec2()
|
|
||||||
self:F2( self.PositionableName )
|
|
||||||
|
|
||||||
local DCSPositionable = self:GetDCSObject()
|
local DCSPositionable = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSPositionable then
|
if DCSPositionable then
|
||||||
local PositionableVec3 = DCSPositionable:getPosition().p
|
|
||||||
|
|
||||||
local PositionableVec2 = {}
|
local vec3=DCSPositionable:getPoint()
|
||||||
PositionableVec2.x = PositionableVec3.x
|
|
||||||
PositionableVec2.y = PositionableVec3.z
|
|
||||||
|
|
||||||
self:T2( PositionableVec2 )
|
if vec3 then
|
||||||
return PositionableVec2
|
return vec3
|
||||||
|
else
|
||||||
|
self:E("ERROR: Cannot get vec3!")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
BASE:E( { "Cannot GetVec2", Positionable = self, Alive = self:IsAlive() } )
|
-- ERROR!
|
||||||
|
self:E( { "Cannot GetVec3", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the @{DCS#Vec2} vector indicating the point in 2D of the POSITIONABLE within the mission.
|
||||||
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
|
-- @return DCS#Vec2 The 2D point vector of the POSITIONABLE or #nil if it is not existing or alive.
|
||||||
|
function POSITIONABLE:GetVec2()
|
||||||
|
|
||||||
|
local DCSPositionable = self:GetDCSObject()
|
||||||
|
|
||||||
|
if DCSPositionable then
|
||||||
|
|
||||||
|
local Vec3=DCSPositionable:getPoint() --DCS#Vec3
|
||||||
|
|
||||||
|
return {x=Vec3.x, y=Vec3.z}
|
||||||
|
end
|
||||||
|
|
||||||
|
self:E( { "Cannot GetVec2", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -258,7 +286,7 @@ function POSITIONABLE:GetPointVec2()
|
|||||||
return PositionablePointVec2
|
return PositionablePointVec2
|
||||||
end
|
end
|
||||||
|
|
||||||
BASE:E( { "Cannot GetPointVec2", Positionable = self, Alive = self:IsAlive() } )
|
self:E( { "Cannot GetPointVec2", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
@ -268,17 +296,29 @@ end
|
|||||||
-- @return Core.Point#POINT_VEC3 The 3D point vector of the POSITIONABLE.
|
-- @return Core.Point#POINT_VEC3 The 3D point vector of the POSITIONABLE.
|
||||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
-- @return #nil The POSITIONABLE is not existing or alive.
|
||||||
function POSITIONABLE:GetPointVec3()
|
function POSITIONABLE:GetPointVec3()
|
||||||
self:F2( self.PositionableName )
|
|
||||||
|
|
||||||
local DCSPositionable = self:GetDCSObject()
|
local DCSPositionable = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSPositionable then
|
if DCSPositionable then
|
||||||
|
|
||||||
|
-- Get 3D vector.
|
||||||
local PositionableVec3 = self:GetPositionVec3()
|
local PositionableVec3 = self:GetPositionVec3()
|
||||||
|
|
||||||
local PositionablePointVec3 = POINT_VEC3:NewFromVec3( PositionableVec3 )
|
if false and self.pointvec3 then
|
||||||
|
|
||||||
self:T2( PositionablePointVec3 )
|
-- Update vector.
|
||||||
return PositionablePointVec3
|
self.pointvec3.x=PositionableVec3.x
|
||||||
|
self.pointvec3.y=PositionableVec3.y
|
||||||
|
self.pointvec3.z=PositionableVec3.z
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Create a new POINT_VEC3 object.
|
||||||
|
self.pointvec3=POINT_VEC3:NewFromVec3(PositionableVec3)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.pointvec3
|
||||||
end
|
end
|
||||||
|
|
||||||
BASE:E( { "Cannot GetPointVec3", Positionable = self, Alive = self:IsAlive() } )
|
BASE:E( { "Cannot GetPointVec3", Positionable = self, Alive = self:IsAlive() } )
|
||||||
@ -289,27 +329,62 @@ end
|
|||||||
--- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.
|
--- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
-- @return Core.Point#COORDINATE The COORDINATE of the POSITIONABLE.
|
-- @return Core.Point#COORDINATE The COORDINATE of the POSITIONABLE.
|
||||||
function POSITIONABLE:GetCoordinate()
|
function POSITIONABLE:GetCoord()
|
||||||
self:F2( self.PositionableName )
|
|
||||||
|
|
||||||
|
-- Get DCS object.
|
||||||
local DCSPositionable = self:GetDCSObject()
|
local DCSPositionable = self:GetDCSObject()
|
||||||
|
|
||||||
if DCSPositionable then
|
if DCSPositionable then
|
||||||
local PositionableVec3 = self:GetPositionVec3()
|
|
||||||
|
|
||||||
local PositionableCoordinate = COORDINATE:NewFromVec3( PositionableVec3 )
|
-- Get the current position.
|
||||||
PositionableCoordinate:SetHeading( self:GetHeading() )
|
local Vec3 = self:GetVec3()
|
||||||
PositionableCoordinate:SetVelocity( self:GetVelocityMPS() )
|
|
||||||
|
|
||||||
self:T2( PositionableCoordinate )
|
if self.coordinate then
|
||||||
return PositionableCoordinate
|
|
||||||
|
-- Update vector.
|
||||||
|
self.coordinate.x=Vec3.x
|
||||||
|
self.coordinate.y=Vec3.y
|
||||||
|
self.coordinate.z=Vec3.z
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- New COORDINATE.
|
||||||
|
self.coordinate=COORDINATE:NewFromVec3(Vec3)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.coordinate
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Error message.
|
||||||
BASE:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } )
|
BASE:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns a COORDINATE object indicating the point in 3D of the POSITIONABLE within the mission.
|
||||||
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
|
-- @return Core.Point#COORDINATE The COORDINATE of the POSITIONABLE.
|
||||||
|
function POSITIONABLE:GetCoordinate()
|
||||||
|
|
||||||
|
-- Get DCS object.
|
||||||
|
local DCSPositionable = self:GetDCSObject()
|
||||||
|
|
||||||
|
if DCSPositionable then
|
||||||
|
|
||||||
|
-- Get the current position.
|
||||||
|
local PositionableVec3 = self:GetVec3()
|
||||||
|
|
||||||
|
-- Return a new coordiante object.
|
||||||
|
return COORDINATE:NewFromVec3(PositionableVec3)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Error message.
|
||||||
|
self:E( { "Cannot GetCoordinate", Positionable = self, Alive = self:IsAlive() } )
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns a COORDINATE object, which is offset with respect to the orientation of the POSITIONABLE.
|
--- Returns a COORDINATE object, which is offset with respect to the orientation of the POSITIONABLE.
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||||
-- @param #number x Offset in the direction "the nose" of the unit is pointing in meters. Default 0 m.
|
-- @param #number x Offset in the direction "the nose" of the unit is pointing in meters. Default 0 m.
|
||||||
@ -384,26 +459,6 @@ function POSITIONABLE:GetRandomVec3( Radius )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns the @{DCS#Vec3} vector indicating the 3D vector of the POSITIONABLE within the mission.
|
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
|
||||||
-- @return DCS#Vec3 The 3D point vector of the POSITIONABLE.
|
|
||||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
|
||||||
function POSITIONABLE:GetVec3()
|
|
||||||
self:F2( self.PositionableName )
|
|
||||||
|
|
||||||
local DCSPositionable = self:GetDCSObject()
|
|
||||||
|
|
||||||
if DCSPositionable then
|
|
||||||
local PositionableVec3 = DCSPositionable:getPosition().p
|
|
||||||
self:T3( PositionableVec3 )
|
|
||||||
return PositionableVec3
|
|
||||||
end
|
|
||||||
|
|
||||||
BASE:E( { "Cannot GetVec3", Positionable = self, Alive = self:IsAlive() } )
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Get the bounding box of the underlying POSITIONABLE DCS Object.
|
--- Get the bounding box of the underlying POSITIONABLE DCS Object.
|
||||||
-- @param #POSITIONABLE self
|
-- @param #POSITIONABLE self
|
||||||
@ -1533,7 +1588,7 @@ end
|
|||||||
|
|
||||||
|
|
||||||
--- Returns true if the unit is within a @{Zone}.
|
--- Returns true if the unit is within a @{Zone}.
|
||||||
-- @param #STPOSITIONABLEATIC self
|
-- @param #POSITIONABLE self
|
||||||
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
-- @param Core.Zone#ZONE_BASE Zone The zone to test.
|
||||||
-- @return #boolean Returns true if the unit is within the @{Core.Zone#ZONE_BASE}
|
-- @return #boolean Returns true if the unit is within the @{Core.Zone#ZONE_BASE}
|
||||||
function POSITIONABLE:IsInZone( Zone )
|
function POSITIONABLE:IsInZone( Zone )
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user