diff --git a/Dcs/DCSGroup.lua b/Dcs/DCSGroup.lua index a3d0edf5d..46e212f2f 100644 --- a/Dcs/DCSGroup.lua +++ b/Dcs/DCSGroup.lua @@ -37,10 +37,11 @@ -- @return #Group.Category --TODO check coalition.side ---- Returns coalition of the group. + +--- Returns the coalition of the group. -- @function [parent=#Group] getCoalition -- @param #Group self --- @return #coalition.side +-- @return DCSCoalitionObject#coalition.side --- Returns the group's name. This is the same name assigned to the group in Mission Editor. -- @function [parent=#Group] getName diff --git a/Dcs/DCSTime.lua b/Dcs/DCSTime.lua index 95b1efcc1..d70d337ec 100644 --- a/Dcs/DCSTime.lua +++ b/Dcs/DCSTime.lua @@ -1,2 +1,8 @@ --- @type ModelTime +------------------------------------------------------------------------------- +-- @module DCSTime + +--- @type ModelTime -- @extends #number + +--- @type Time +-- @extends #number \ No newline at end of file diff --git a/Dcs/DCScountry.lua b/Dcs/DCScountry.lua new file mode 100644 index 000000000..5a277d1fb --- /dev/null +++ b/Dcs/DCScountry.lua @@ -0,0 +1,26 @@ +------------------------------------------------------------------------------- +-- @module DCScountry + +--- @type country +-- @field #country.id id + +--- @type country.id +-- @field RUSSIA +-- @field UKRAINE +-- @field USA +-- @field TURKEY +-- @field UK +-- @field FRANCE +-- @field GERMANY +-- @field CANADA +-- @field SPAIN +-- @field THE_NETHERLANDS +-- @field BELGIUM +-- @field NORWAY +-- @field DENMARK +-- @field ISRAEL +-- @field GEORGIA +-- @field INSURGENTS +-- @field ABKHAZIA +-- @field SOUTH_OSETIA +-- @field ITALY \ No newline at end of file diff --git a/Dcs/Moose_Test_WRAPPER.lua b/Dcs/Moose_Test_WRAPPER.lua new file mode 100644 index 000000000..bed5f303a --- /dev/null +++ b/Dcs/Moose_Test_WRAPPER.lua @@ -0,0 +1,8 @@ + +Include.File( "Group" ) +Include.File( "Unit" ) + +local UnitAirPlaneAI = _DATABASE:FindUnit( "Airplane AI" ) + +UnitAirPlaneAI:FlareRed() + diff --git a/Documentation/Base.html b/Documentation/Base.html index c691d7457..f7177aa41 100644 --- a/Documentation/Base.html +++ b/Documentation/Base.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/CARGO.html b/Documentation/CARGO.html index dbce3e8d9..fdacc75e3 100644 --- a/Documentation/CARGO.html +++ b/Documentation/CARGO.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/CLEANUP.html b/Documentation/CLEANUP.html index 6946d1aa9..1b0702bb3 100644 --- a/Documentation/CLEANUP.html +++ b/Documentation/CLEANUP.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Client.html b/Documentation/Client.html index f19da4d0b..67e324e6f 100644 --- a/Documentation/Client.html +++ b/Documentation/Client.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -59,18 +74,41 @@

    #CLIENT class

    Clients are those Units defined within the Mission Editor that have the skillset defined as Client or Player. -Note that clients are NOT the same as Units, they are NOT necessarily alive.

    +Note that clients are NOT the same as Units, they are NOT necessarily alive. +The CLIENT class is a wrapper class to handle the DCS Unit objects that have the skillset defined as Client or Player:

    + +

    Clients are being used by the MISSION class to follow players and register their successes.

    -

    CLIENT construction methods:

    -

    Create a new CLIENT object with the CLIENT.New method:

    +

    CLIENT reference methods

    +

    For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _DATABASE object. +This is done at the beginning of the mission (when the mission starts).

    + +

    The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference +using the DCS Unit or the DCS UnitName.

    + +

    Another thing to know is that CLIENT objects do not "contain" the DCS Unit object. +The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution. +If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file.

    + +

    The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance:

    +

    IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).

    + +

    Global(s)

    @@ -92,12 +130,6 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

    - - - - @@ -164,12 +196,6 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

    - - - - @@ -179,9 +205,15 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

    - + + + + + @@ -212,48 +244,6 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -299,13 +289,13 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

    - + - + @@ -314,6 +304,12 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

    + + + + @@ -398,8 +394,8 @@ is the text defining the Mission briefing.

    Return value

    -

    #CLIENT:

    - +

    #CLIENT: +self

    @@ -433,20 +429,6 @@ Function.

    #CLIENT:

    - - -
    -
    - - - -CLIENT.AliveCheckScheduler - -
    -
    - - -
    @@ -599,24 +581,6 @@ Function.

    - -
    -
    -
    - - -CLIENT:ClientPosition() - -
    -
    - -

    Returns the position of the CLIENT in DCSTypes#Vec3 format.

    - -

    Return value

    - -

    DCSTypes#Vec3:

    - -
    @@ -636,19 +600,95 @@ Function.

    - -CLIENT:GetAltitude() + +CLIENT:Find(ClientName, ClientBriefing, DCSUnit)
    -

    Returns the altitude of the CLIENT.

    +

    Finds a CLIENT from the _DATABASE using the relevant DCS Unit.

    +

    Parameters

    +
      +
    • + +

      #string ClientName : +Name of the DCS Unit as defined within the Mission Editor.

      + +
    • +
    • + +

      #string ClientBriefing : +Text that describes the briefing of the mission when a Player logs into the Client.

      + +
    • +
    • + +

      DCSUnit :

      + +
    • +

    Return value

    -

    DCSTypes#Distance:

    +

    #CLIENT:

    +

    Usage:

    +
    -- Create new Clients.
    + local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
    + Mission:AddGoal( DeploySA6TroopsGoal )
    +
    + Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
    + Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
    + Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
    + Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
    + +
    +
    +
    +
    + + +CLIENT:FindByName(ClientName, ClientBriefing) + +
    +
    + +

    Finds a CLIENT from the _DATABASE using the relevant Client Unit Name.

    + + +

    As an optional parameter, a briefing text can be given also.

    + +

    Parameters

    +
      +
    • + +

      #string ClientName : +Name of the DCS Unit as defined within the Mission Editor.

      + +
    • +
    • + +

      #string ClientBriefing : +Text that describes the briefing of the mission when a Player logs into the Client.

      + +
    • +
    +

    Return value

    + +

    #CLIENT:

    + + +

    Usage:

    +
    -- Create new Clients.
    +	local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
    +	Mission:AddGoal( DeploySA6TroopsGoal )
    +
    +	Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
    +	Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
    +	Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
    +	Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
    +
    @@ -743,105 +783,6 @@ Function.

    DCSGroup#Group:

    - -
    -
    -
    - - -CLIENT:GetID() - -
    -
    - - - -
    -
    -
    -
    - - -CLIENT:GetName() - -
    -
    - - - -
    -
    -
    -
    - - -CLIENT:GetPointVec2() - -
    -
    - -

    Returns the position of the CLIENT in DCSTypes#Vec2 format..

    - -

    Return value

    - -

    DCSTypes#Vec2:

    - - -
    -
    -
    -
    - - -CLIENT:GetPositionVec3() - -
    -
    - - - -
    -
    -
    -
    - - -CLIENT:GetTypeName() - -
    -
    - - - -
    -
    -
    -
    - - -CLIENT:GetUnit() - -
    -
    - - - - -

    TODO what is this??? check. possible double function.

    - -
    -
    -
    -
    - - -CLIENT:IsAlive() - -
    -
    - -

    Checks if client is alive and returns true or false.

    -
    @@ -983,49 +924,6 @@ is the interval in seconds between the display of the -
    - - -CLIENT:New(ClientName, ClientBriefing) - -
    -
    - -

    Use this method to register new Clients within a mission.

    - -

    Parameters

    -
      -
    • - -

      #string ClientName : -Name of the DCS Unit as defined within the Mission Editor.

      - -
    • -
    • - -

      #string ClientBriefing : -Text that describes the briefing of the mission when a Player logs into the Client.

      - -
    • -
    -

    Return value

    - -

    #CLIENT:

    - - -

    Usage:

    -
    -- Create new Clients.
    -	local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
    -	Mission:AddGoal( DeploySA6TroopsGoal )
    -
    -	Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
    -	Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
    -	Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
    -	Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
    -
    @@ -1040,6 +938,27 @@ Text that describes the briefing of the mission when a Player logs into the Clie + +
    +
    +
    + + +CLIENT:Register(ClientName) + +
    +
    + + + +

    Parameter

    +
      +
    • + +

      ClientName :

      + +
    • +
    @@ -1067,6 +986,24 @@ Name of the Group as defined within the Mission Editor. The Group must have a Un
    + +CLIENT:ShowBriefing() + +
    +
    + +

    Show the briefing of the MISSION to the CLIENT.

    + +

    Return value

    + +

    #CLIENT: +self

    + +
    +
    +
    +
    + CLIENT:ShowCargo() diff --git a/Documentation/DCSAirbase.html b/Documentation/DCSAirbase.html index 5ba906d1e..907c576e5 100644 --- a/Documentation/DCSAirbase.html +++ b/Documentation/DCSAirbase.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSCoalitionObject.html b/Documentation/DCSCoalitionObject.html index 8f4146e80..ee0e7b8dc 100644 --- a/Documentation/DCSCoalitionObject.html +++ b/Documentation/DCSCoalitionObject.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSCommand.html b/Documentation/DCSCommand.html index e5cb77601..4c9762082 100644 --- a/Documentation/DCSCommand.html +++ b/Documentation/DCSCommand.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSController.html b/Documentation/DCSController.html index 05bd95b0e..c4e7c7428 100644 --- a/Documentation/DCSController.html +++ b/Documentation/DCSController.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSGroup.html b/Documentation/DCSGroup.html index 9f2258624..a7a84c8d1 100644 --- a/Documentation/DCSGroup.html +++ b/Documentation/DCSGroup.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • @@ -106,6 +109,12 @@
    + + + + @@ -291,6 +300,24 @@

    #Group.Category:

    + + +
    +
    + + +Group:getCoalition() + +
    +
    + +

    Returns the coalition of the group.

    + +

    Return value

    + +

    DCSCoalitionObject#coalition.side:

    + +
    diff --git a/Documentation/DCSObject.html b/Documentation/DCSObject.html index 017a27b88..44157433f 100644 --- a/Documentation/DCSObject.html +++ b/Documentation/DCSObject.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSTask.html b/Documentation/DCSTask.html index 4f42d8760..93585f188 100644 --- a/Documentation/DCSTask.html +++ b/Documentation/DCSTask.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSTypes.html b/Documentation/DCSTypes.html index 7eb5381e2..2cf9f22b0 100644 --- a/Documentation/DCSTypes.html +++ b/Documentation/DCSTypes.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSUnit.html b/Documentation/DCSUnit.html index 7b78a1fd6..e09265c44 100644 --- a/Documentation/DCSUnit.html +++ b/Documentation/DCSUnit.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCSWorld.html b/Documentation/DCSWorld.html index e1dc25088..e91ba3f3f 100644 --- a/Documentation/DCSWorld.html +++ b/Documentation/DCSWorld.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DCStimer.html b/Documentation/DCStimer.html index 1ee0f7a2c..b4af45ac2 100644 --- a/Documentation/DCStimer.html +++ b/Documentation/DCStimer.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/DEPLOYTASK.html b/Documentation/DEPLOYTASK.html index 2d68b6cfa..b57bf41c4 100644 --- a/Documentation/DEPLOYTASK.html +++ b/Documentation/DEPLOYTASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYBASETASK.html b/Documentation/DESTROYBASETASK.html index 32d486ea6..263a03453 100644 --- a/Documentation/DESTROYBASETASK.html +++ b/Documentation/DESTROYBASETASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYGROUPSTASK.html b/Documentation/DESTROYGROUPSTASK.html index 01411a4f9..2235e0590 100644 --- a/Documentation/DESTROYGROUPSTASK.html +++ b/Documentation/DESTROYGROUPSTASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYRADARSTASK.html b/Documentation/DESTROYRADARSTASK.html index 6cb878888..f246dfc10 100644 --- a/Documentation/DESTROYRADARSTASK.html +++ b/Documentation/DESTROYRADARSTASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYUNITTYPESTASK.html b/Documentation/DESTROYUNITTYPESTASK.html index 9890c4507..62898b2ee 100644 --- a/Documentation/DESTROYUNITTYPESTASK.html +++ b/Documentation/DESTROYUNITTYPESTASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Database.html b/Documentation/Database.html index 8192f0de6..baef7069e 100644 --- a/Documentation/Database.html +++ b/Documentation/Database.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -139,13 +154,31 @@ The following iterator methods are currently available within the DATABASE:

    Type DATABASE

    CLIENT:Alive(CallBack, ...)

    Checks for a client alive event and calls a function on a continuous basis.

    -
    CLIENT.AliveCheckScheduler -
    CLIENT.ClientParameters -
    CLIENT:ClientPosition() -

    Returns the position of the CLIENT in DCSTypes#Vec3 format.

    CLIENT:GetAltitude()CLIENT:Find(ClientName, ClientBriefing, DCSUnit) -

    Returns the altitude of the CLIENT.

    +

    Finds a CLIENT from the _DATABASE using the relevant DCS Unit.

    +
    CLIENT:FindByName(ClientName, ClientBriefing) +

    Finds a CLIENT from the _DATABASE using the relevant Client Unit Name.

    CLIENT:GetDCSGroup()

    Return the DCSGroup of a Client.

    -
    CLIENT:GetID() - -
    CLIENT:GetName() - -
    CLIENT:GetPointVec2() -

    Returns the position of the CLIENT in DCSTypes#Vec2 format..

    -
    CLIENT:GetPositionVec3() - -
    CLIENT:GetTypeName() - -
    CLIENT:GetUnit() - -
    CLIENT:IsAlive() -

    Checks if client is alive and returns true or false.

    CLIENT:New(ClientName, ClientBriefing)CLIENT.ONBOARDSIDE -

    Use this method to register new Clients within a mission.

    +
    CLIENT.ONBOARDSIDECLIENT:Register(ClientName) CLIENT:Reset(ClientName)

    Resets a CLIENT.

    +
    CLIENT:ShowBriefing() +

    Show the briefing of the MISSION to the CLIENT.

    Group:getCategory()

    Returns category of the group.

    +
    Group:getCoalition() +

    Returns the coalition of the group.

    - + + + + + + + + + + + + + - + @@ -160,12 +193,6 @@ The following iterator methods are currently available within the DATABASE:

    - - - - @@ -175,39 +202,15 @@ The following iterator methods are currently available within the DATABASE:

    - + - - - - - - - - - - - - - - - - @@ -217,21 +220,21 @@ The following iterator methods are currently available within the DATABASE:

    - + - + - + @@ -247,7 +250,7 @@ The following iterator methods are currently available within the DATABASE:

    - + @@ -256,24 +259,18 @@ The following iterator methods are currently available within the DATABASE:

    + + + + - - - - - - - - @@ -337,13 +334,7 @@ The following iterator methods are currently available within the DATABASE:

    - - - - - + @@ -435,9 +426,82 @@ The following iterator methods are currently available within the DATABASE:

    - #string - -DATABASE.ClassName + +DATABASE:AddClient(ClientName) + +
    +
    + +

    Adds a CLIENT based on the ClientName in the DATABASE.

    + +

    Parameter

    + +
    +
    +
    +
    + + +DATABASE:AddGroup(DCSGroup, GroupName) + +
    +
    + +

    Adds a GROUP based on the GroupName in the DATABASE.

    + +

    Parameters

    + +
    +
    +
    +
    + + +DATABASE:AddUnit(DCSUnit, DCSUnitName) + +
    +
    + +

    Adds a Unit based on the Unit Name in the DATABASE.

    + +

    Parameters

    + +
    +
    +
    +
    + + + +DATABASE.CLIENTS
    @@ -449,9 +513,9 @@ The following iterator methods are currently available within the DATABASE:

    - - -DATABASE.Clients + #string + +DATABASE.ClassName
    @@ -486,20 +550,6 @@ The following iterator methods are currently available within the DATABASE:

    -
    -
    -
    -
    - - - -DATABASE.DCSGroupsAlive - -
    -
    - - -
    @@ -519,15 +569,22 @@ The following iterator methods are currently available within the DATABASE:

    - - -DATABASE.DCSUnitsAlive + +DATABASE:DeleteUnit(DCSUnitName)
    +

    Deletes a Unit from the DATABASE based on the Unit Name.

    +

    Parameter

    +
      +
    • + +

      DCSUnitName :

      +
    • +
    @@ -542,126 +599,6 @@ The following iterator methods are currently available within the DATABASE:

    -
    -
    -
    -
    - - -DATABASE:FilterCategories(Categories) - -
    -
    - -

    Builds a set of units out of categories.

    - - -

    Possible current categories are plane, helicopter, ground, ship.

    - -

    Parameter

    - -

    Return value

    - -

    #DATABASE: -self

    - -
    -
    -
    -
    - - -DATABASE:FilterCoalitions(Coalitions) - -
    -
    - -

    Builds a set of units of coalitons.

    - - -

    Possible current coalitions are red, blue and neutral.

    - -

    Parameter

    - -

    Return value

    - -

    #DATABASE: -self

    - -
    -
    -
    -
    - - -DATABASE:FilterCountries(Countries) - -
    -
    - -

    Builds a set of units of defined countries.

    - - -

    Possible current countries are those known within DCS world.

    - -

    Parameter

    - -

    Return value

    - -

    #DATABASE: -self

    - -
    -
    -
    -
    - - -DATABASE:FilterGroupPrefixes(Prefixes) - -
    -
    - -

    Builds a set of units of defined group prefixes.

    - - -

    All the units starting with the given group prefixes will be included within the set.

    - -

    Parameter

    - -

    Return value

    - -

    #DATABASE: -self

    -
    @@ -681,78 +618,78 @@ self

    - -DATABASE:FilterStart() + +DATABASE:FindClient(ClientName)
    -

    Starts the filtering.

    +

    Finds a CLIENT based on the ClientName.

    +

    Parameter

    +
      +
    • + +

      #string ClientName :

      + +
    • +

    Return value

    -

    #DATABASE: -self

    +

    Client#CLIENT: +The found CLIENT.

    - -DATABASE:FilterTypes(Types) + +DATABASE:FindGroup(GroupName)
    -

    Builds a set of units of defined unit types.

    - - -

    Possible current types are those types known within DCS world.

    +

    Finds a GROUP based on the GroupName.

    Parameter

    • -

      #string Types : -Can take those type strings known within DCS world.

      +

      #string GroupName :

    Return value

    -

    #DATABASE: -self

    +

    Group#GROUP: +The found GROUP.

    - -DATABASE:FilterUnitPrefixes(Prefixes) + +DATABASE:FindUnit(UnitName)
    -

    Builds a set of units of defined unit prefixes.

    - - -

    All the units starting with the given prefixes will be included within the set.

    +

    Finds a Unit based on the Unit Name.

    Parameter

    • -

      #string Prefixes : -The prefix of which the unit name starts with.

      +

      #string UnitName :

    Return value

    -

    #DATABASE: -self

    +

    Unit#UNIT: +The found Unit.

    @@ -828,8 +765,8 @@ self

    - -DATABASE:ForEachDCSUnitAlive(IteratorFunction, ...) + +DATABASE:ForEachDCSUnit(IteratorFunction, ...)
    @@ -887,6 +824,20 @@ The function that will be called when there is an alive player in the database.

    #DATABASE: self

    +
    +
    +
    +
    + + + +DATABASE.GROUPS + +
    +
    + + +
    @@ -908,34 +859,6 @@ self

    - -
    -
    -
    - - - -DATABASE.Groups - -
    -
    - - - -
    -
    -
    -
    - - - -DATABASE.GroupsAlive - -
    -
    - - -
    @@ -1125,22 +1048,8 @@ self

    - -DATABASE.Units - -
    -
    - - - -
    -
    -
    -
    - - - -DATABASE.UnitsAlive + +DATABASE.UNITS
    diff --git a/Documentation/Escort.html b/Documentation/Escort.html index 9101be061..6da80cd1e 100644 --- a/Documentation/Escort.html +++ b/Documentation/Escort.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -1835,6 +1850,7 @@ self

    + ESCORT.ReportTargetsScheduler diff --git a/Documentation/Event.html b/Documentation/Event.html index b05cb6788..153c8cb07 100644 --- a/Documentation/Event.html +++ b/Documentation/Event.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/GOHOMETASK.html b/Documentation/GOHOMETASK.html index 4b63dc32e..3a3adccd4 100644 --- a/Documentation/GOHOMETASK.html +++ b/Documentation/GOHOMETASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Group.html b/Documentation/Group.html index be3012b46..cfbc60f20 100644 --- a/Documentation/Group.html +++ b/Documentation/Group.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,20 +54,54 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • Module Group

    -

    A GROUP class abstraction of a DCSGroup class.

    +

    GROUP class.

    -

    The GROUP class will take an abstraction of the DCSGroup class, providing more methods that can be done with a GROUP.

    + +

    GROUP class

    +

    The GROUP class is a wrapper class to handle the DCS Group objects:

    + +
      +
    • Support all DCS Group APIs.
    • +
    • Enhance with Group specific APIs not in the DCS Group API set.
    • +
    • Handle local Group Controller.
    • +
    • Manage the "state" of the DCS Group.
    • +
    + + +

    GROUP reference methods

    +

    For each DCS Group object alive within a running mission, a GROUP wrapper object (instance) will be created within the _DATABASE object. +This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Group objects are spawned (using the SPAWN class).

    + +

    The GROUP class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference +using the DCS Group or the DCS GroupName.

    + +

    Another thing to know is that GROUP objects do not "contain" the DCS Group object. +The GROUP methods will reference the DCS Group object by name when it is needed during API execution. +If the DCS Group object does not exist or is nil, the GROUP methods will return nil and log an exception in the DCS.log file.

    + +

    The GROUP class provides the following functions to retrieve quickly the relevant GROUP instance:

    + +
      +
    • GROUP.Find(): Find a GROUP instance from the _DATABASE object using a DCS Group object.
    • +
    • GROUP.FindByName(): Find a GROUP instance from the _DATABASE object using a DCS Group name.
    • +
    + +

    IMPORTANT: ONE SHOULD NEVER SANATIZE these GROUP OBJECT REFERENCES! (make the GROUP object references nil).

    Global(s)

    DATABASE.ClassNameDATABASE:AddClient(ClientName) +

    Adds a CLIENT based on the ClientName in the DATABASE.

    +
    DATABASE:AddGroup(DCSGroup, GroupName) +

    Adds a GROUP based on the GroupName in the DATABASE.

    +
    DATABASE:AddUnit(DCSUnit, DCSUnitName) +

    Adds a Unit based on the Unit Name in the DATABASE.

    +
    DATABASE.CLIENTS
    DATABASE.ClientsDATABASE.ClassName DATABASE.DCSGroups -
    DATABASE.DCSGroupsAlive -
    DATABASE.DCSUnitsAliveDATABASE:DeleteUnit(DCSUnitName) - +

    Deletes a Unit from the DATABASE based on the Unit Name.

    DATABASE.Filter -
    DATABASE:FilterCategories(Categories) -

    Builds a set of units out of categories.

    -
    DATABASE:FilterCoalitions(Coalitions) -

    Builds a set of units of coalitons.

    -
    DATABASE:FilterCountries(Countries) -

    Builds a set of units of defined countries.

    -
    DATABASE:FilterGroupPrefixes(Prefixes) -

    Builds a set of units of defined group prefixes.

    DATABASE:FilterStart()DATABASE:FindClient(ClientName) -

    Starts the filtering.

    +

    Finds a CLIENT based on the ClientName.

    DATABASE:FilterTypes(Types)DATABASE:FindGroup(GroupName) -

    Builds a set of units of defined unit types.

    +

    Finds a GROUP based on the GroupName.

    DATABASE:FilterUnitPrefixes(Prefixes)DATABASE:FindUnit(UnitName) -

    Builds a set of units of defined unit prefixes.

    +

    Finds a Unit based on the Unit Name.

    DATABASE:ForEachDCSUnitAlive(IteratorFunction, ...)DATABASE:ForEachDCSUnit(IteratorFunction, ...)

    Interate the DATABASE and call an interator function for each alive unit, providing the Unit and optional parameters.

    DATABASE:ForEachPlayer(IteratorFunction, ...)

    Interate the DATABASE and call an interator function for each alive player, providing the Unit of the player and optional parameters.

    +
    DATABASE.GROUPS +
    DATABASE:GetStatusGroup(GroupName)

    Get a status to a Group within the Database, this to check crossing events for example.

    -
    DATABASE.Groups - -
    DATABASE.GroupsAlive -
    DATABASE.Units - -
    DATABASE.UnitsAliveDATABASE.UNITS
    @@ -112,7 +157,7 @@ @@ -130,44 +175,61 @@ - + + + + + + + + + + + + + @@ -179,7 +241,15 @@ Note that this destroy method also raises a destroy event at run-time.

    + + + + @@ -203,19 +273,25 @@ Note that this destroy method also raises a destroy event at run-time.

    - + + + + + @@ -239,13 +315,19 @@ Note that this destroy method also raises a destroy event at run-time.

    + + + + @@ -263,31 +345,31 @@ Note that this destroy method also raises a destroy event at run-time.

    @@ -324,24 +406,6 @@ Note that this destroy method also raises a destroy event at run-time.

    - - - - - - - - - - - - @@ -450,6 +514,12 @@ Note that this destroy method also raises a destroy event at run-time.

    + + + + @@ -564,12 +634,18 @@ Note that this destroy method also raises a destroy event at run-time.

    + + + + @@ -603,7 +679,7 @@ Note that this destroy method also raises a destroy event at run-time.

    - + @@ -618,22 +694,6 @@ Note that this destroy method also raises a destroy event at run-time.

    - -
    GROUP.Controller -

    The controller of the group.

    +
    GROUP:Destroy() -

    Destroy a GROUP -Note that this destroy method also raises a destroy event at run-time.

    +

    Destroys the DCS Group and all of its DCS Units.

    GROUP.FindGroup(Group, DCSGroup)GROUP:Find(DCSGroup) -

    Find the created GROUP using the DCSGroup ID.

    +

    Find the GROUP wrapper class instance using the DCS Group.

    +
    GROUP:FindByName(GroupName) +

    Find the created GROUP using the DCS Group Name.

    GROUP:GetCallsign() -

    Gets the callsign of the fist unit of the group.

    +

    Gets the CallSign of the first DCS Unit of the DCS Group.

    +
    GROUP:GetCategory() +

    Returns category of the DCS Group.

    GROUP:GetCategoryName() -

    Returns the category name of the group.

    +

    Returns the category name of the DCS Group.

    +
    GROUP:GetCoalition() +

    Returns the coalition of the DCS Group.

    GROUP:GetDCSGroup() -

    Gets the DCSGroup of the GROUP.

    +

    Returns the DCS Group.

    GROUP:GetDCSUnit(UnitNumber) -

    Gets the DCS Unit of the GROUP.

    +

    Returns the DCS Unit with number UnitNumber.

    GROUP:GetDCSUnits() -

    Gets the DCSUnits of the GROUP.

    +

    Returns the DCS Units of the DCS Group.

    GROUP:GetID() -

    Gets the ID of the GROUP.

    +

    Returns the DCS Group identifier.

    +
    GROUP:GetInitialSize() +
      +
    • Returns the initial size of the DCS Group.
    • +
    GROUP:GetName() -

    Returns the name of the Group.

    +

    Returns the name of the DCS Group.

    GROUP:GetPointVec2() -

    Gets the current Point of the GROUP in VEC3 format.

    +

    Returns the current point (Vec2 vector) of the first DCS Unit in the DCS Group.

    GROUP:GetPositionVec3()GROUP:GetPointVec3() -

    Gets the current Point of the GROUP in VEC3 format.

    +

    Returns the current point (Vec3 vector) of the first DCS Unit in the DCS Group.

    +
    GROUP:GetSize() +

    Returns current size of the DCS Group.

    GROUP:GetUnit(UnitNumber) -

    Gets the DCS Unit.

    +

    Returns the UNIT wrapper class with number UnitNumber.

    +
    GROUP:GetUnits() +

    Returns the UNITs wrappers of the DCS Units of the DCS Group.

    GROUP.GroupID -

    the ID of the group.

    +
    GROUP:IsAirPlane() -

    Returns if the GROUP are AirPlanes.

    +

    Returns if the DCS Group contains AirPlanes.

    GROUP:IsAlive() -

    Returns if the group is alive.

    +

    Returns if the DCS Group is alive.

    GROUP:IsGround() -

    Returns if the GROUP are Ground troops.

    +

    Returns if the DCS Group contains Ground troops.

    GROUP:IsHelicopter() -

    Returns if the GROUP is a Helicopter.

    +

    Returns if the DCS Group contains Helicopters.

    GROUP:IsShip() -

    Returns if the GROUP are Ships.

    +

    Returns if the DCS Group contains Ships.

    GROUP:MessageToRed(Message, Duration)

    Send a message to the red coalition.

    -
    GROUP:New(DCSGroup) -

    Create a new GROUP from a DCSGroup

    -
    GROUP:NewFromDCSUnit(DCSUnit) -

    Create a new GROUP from an existing DCSUnit in the mission.

    -
    GROUP:NewFromName(GroupName) -

    Create a new GROUP from an existing group name.

    GROUP:PushTask(DCSTask, WaitTime)

    Pushing Task on the queue from the group.

    +
    GROUP:Register(GroupName) +

    Create a new GROUP from a DCSGroup

    GROUP:TaskRoute(Points)

    Return a Misson task to follow a given route defined by Points.

    +
    GROUP:TaskRouteToVec2(Point, Speed) +

    Make the DCS Group to fly to a given point and hover.

    GROUP:TaskRouteToVec3(Point, Speed) -

    Make the group to fly to a given point and hover.

    +

    Make the DCS Group to fly to a given point and hover.

    GROUP:WayPointInitialize(WayPoint)GROUP:WayPointInitialize()

    Retrieve the group mission and allow to place function hooks within the mission waypoint plan.

    GROUP:_GetController()

    Get the controller for the GROUP.

    -
    - -

    Type Vec3

    - - - - - - - -
    Vec3.x - -
    Vec3.y -
    @@ -798,14 +858,13 @@ All units on the ground result.

    - #table GROUP.Controller
    -

    The controller of the group.

    +
    @@ -872,46 +931,65 @@ When randomization is on, the randomization is within the radius.

    -

    Destroy a GROUP -Note that this destroy method also raises a destroy event at run-time.

    +

    Destroys the DCS Group and all of its DCS Units.

    -

    So all event listeners will catch the destroy event of this GROUP.

    +

    Note that this destroy method also raises a destroy event at run-time. +So all event listeners will catch the destroy event of this DCS Group.

    - -GROUP.FindGroup(Group, DCSGroup) + +GROUP:Find(DCSGroup)
    -

    Find the created GROUP using the DCSGroup ID.

    +

    Find the GROUP wrapper class instance using the DCS Group.

    - -

    If a GROUP was created with the DCSGroupID, the the GROUP instance will be returned. -Otherwise nil will be returned.

    - -

    Parameters

    +

    Parameter

    Return value

    -

    #GROUP:

    +

    #GROUP: +The GROUP.

    +
    +
    +
    +
    + + +GROUP:FindByName(GroupName) + +
    +
    + +

    Find the created GROUP using the DCS Group Name.

    + +

    Parameter

    + +

    Return value

    + +

    #GROUP: +The GROUP.

    @@ -924,12 +1002,30 @@ Otherwise nil will be returned.

    -

    Gets the callsign of the fist unit of the group.

    +

    Gets the CallSign of the first DCS Unit of the DCS Group.

    Return value

    #string: -The callsign of the first unit of the group.

    +The CallSign of the first DCS Unit of the DCS Group.

    + +
    + +
    +
    + + +GROUP:GetCategory() + +
    +
    + +

    Returns category of the DCS Group.

    + +

    Return value

    + +

    DCSGroup#Group.Category: +The category ID

    @@ -942,7 +1038,7 @@ The callsign of the first unit of the group.

    -

    Returns the category name of the group.

    +

    Returns the category name of the DCS Group.

    Return value

    @@ -954,18 +1050,36 @@ Category name = Helicopter, Airplane, Ground Unit, Ship

    + +GROUP:GetCoalition() + +
    +
    + +

    Returns the coalition of the DCS Group.

    + +

    Return value

    + +

    DCSCoalitionObject#coalition.side: +The coalition side of the DCS Group.

    + +
    +
    +
    +
    + GROUP:GetDCSGroup()
    -

    Gets the DCSGroup of the GROUP.

    +

    Returns the DCS Group.

    Return value

    DCSGroup#Group: -The DCSGroup.

    +The DCS Group.

    @@ -978,20 +1092,23 @@ The DCSGroup.

    -

    Gets the DCS Unit of the GROUP.

    +

    Returns the DCS Unit with number UnitNumber.

    + + +

    If the underlying DCS Unit does not exist, the method will return nil. .

    Parameter

    Return value

    -

    #Unit: +

    DCSUnit#Unit: The DCS Unit.

    @@ -1005,12 +1122,12 @@ The DCS Unit.

    -

    Gets the DCSUnits of the GROUP.

    +

    Returns the DCS Units of the DCS Group.

    Return value

    #table: -The DCSUnits.

    +The DCS Units.

    @@ -1036,12 +1153,35 @@ The DCSUnits.

    -

    Gets the ID of the GROUP.

    +

    Returns the DCS Group identifier.

    Return value

    #number: -The ID of the GROUP.

    +The identifier of the DCS Group.

    + +
    + +
    +
    + + +GROUP:GetInitialSize() + +
    +
    + + + + +

    If some of the DCS Units of the DCS Group are destroyed, the initial size of the DCS Group is unchanged.

    + +

    Return value

    + +

    #number: +The DCS Group initial size.

    @@ -1117,12 +1257,12 @@ Minimum height found.

    -

    Returns the name of the Group.

    +

    Returns the name of the DCS Group.

    Return value

    #string: -GroupName

    +The DCS Group name.

    @@ -1135,30 +1275,51 @@ GroupName

    -

    Gets the current Point of the GROUP in VEC3 format.

    +

    Returns the current point (Vec2 vector) of the first DCS Unit in the DCS Group.

    Return value

    -

    #Vec3: -Current x,y and z position of the group.

    +

    DCSTypes#Vec2: +Current Vec2 point of the first DCS Unit of the DCS Group.

    - -GROUP:GetPositionVec3() + +GROUP:GetPointVec3()
    -

    Gets the current Point of the GROUP in VEC3 format.

    +

    Returns the current point (Vec3 vector) of the first DCS Unit in the DCS Group.

    Return value

    -

    #Vec3: -Current Vec3 position of the group.

    +

    DCSTypes#Vec3: +Current Vec3 point of the first DCS Unit of the DCS Group.

    + +
    +
    +
    +
    + + +GROUP:GetSize() + +
    +
    + +

    Returns current size of the DCS Group.

    + + +

    If some of the DCS Units of the DCS Group are destroyed the size of the DCS Group is changed.

    + +

    Return value

    + +

    #number: +The DCS Group size.

    @@ -1225,21 +1386,42 @@ The type name of the group.

    -

    Gets the DCS Unit.

    +

    Returns the UNIT wrapper class with number UnitNumber.

    + + +

    If the underlying DCS Unit does not exist, the method will return nil. .

    Parameter

    Return value

    Unit#UNIT: -The DCS Unit.

    +The UNIT wrapper class.

    + +
    + +
    +
    + + +GROUP:GetUnits() + +
    +
    + +

    Returns the UNITs wrappers of the DCS Units of the DCS Group.

    + +

    Return value

    + +

    #table: +The UNITs wrappers.

    @@ -1253,7 +1435,7 @@ The DCS Unit.

    -

    the ID of the group.

    +
    @@ -1301,12 +1483,12 @@ Air category evaluation result.

    -

    Returns if the GROUP are AirPlanes.

    +

    Returns if the DCS Group contains AirPlanes.

    Return value

    #boolean: -true if GROUP are AirPlanes.

    +true if DCS Group contains AirPlanes.

    @@ -1319,7 +1501,7 @@ true if GROUP are AirPlanes.

    -

    Returns if the group is alive.

    +

    Returns if the DCS Group is alive.

    When the group exists at run-time, this method will return true, otherwise false.

    @@ -1327,7 +1509,7 @@ true if GROUP are AirPlanes.

    Return value

    #boolean: -Alive result.

    +true if the DCS Group is alive.

    @@ -1340,12 +1522,12 @@ Alive result.

    -

    Returns if the GROUP are Ground troops.

    +

    Returns if the DCS Group contains Ground troops.

    Return value

    #boolean: -true if GROUP are Ground troops.

    +true if DCS Group contains Ground troops.

    @@ -1358,12 +1540,12 @@ true if GROUP are Ground troops.

    -

    Returns if the GROUP is a Helicopter.

    +

    Returns if the DCS Group contains Helicopters.

    Return value

    #boolean: -true if GROUP are Helicopters.

    +true if DCS Group contains Helicopters.

    @@ -1376,12 +1558,12 @@ true if GROUP are Helicopters.

    -

    Returns if the GROUP are Ships.

    +

    Returns if the DCS Group contains Ships.

    Return value

    #boolean: -true if GROUP are Ships.

    +true if DCS Group contains Ships.

    @@ -1572,87 +1754,6 @@ The duration of the message.

    - -GROUP:New(DCSGroup) - -
    -
    - -

    Create a new GROUP from a DCSGroup

    - -

    Parameter

    - -

    Return value

    - -

    #GROUP: -self

    - -
    -
    -
    -
    - - -GROUP:NewFromDCSUnit(DCSUnit) - -
    -
    - -

    Create a new GROUP from an existing DCSUnit in the mission.

    - -

    Parameter

    - -

    Return value

    - -

    #GROUP: -self

    - -
    -
    -
    -
    - - -GROUP:NewFromName(GroupName) - -
    -
    - -

    Create a new GROUP from an existing group name.

    - -

    Parameter

    - -

    Return value

    - -

    #GROUP: -self

    - -
    -
    -
    -
    - GROUP:OptionROEHoldFire() @@ -1990,6 +2091,33 @@ self

    + +GROUP:Register(GroupName) + +
    +
    + +

    Create a new GROUP from a DCSGroup

    + +

    Parameter

    + +

    Return value

    + +

    #GROUP: +self

    + +
    +
    +
    +
    + GROUP:Route(GoPoints) @@ -2177,7 +2305,7 @@ CSTask#Task> DCSTasks

    • -

      #Time time :

      +

      DCSTime#Time time :

    • @@ -2197,7 +2325,7 @@ CSTask#Task> DCSTasks

    • -

      #Time duration :

      +

      DCSTime#Time duration :

    • @@ -2256,7 +2384,7 @@ CSTask#Task> DCSTasks

      • -

        #Vec2 Point : +

        DCSTypes#Vec2 Point : The point where to wait.

      • @@ -2289,7 +2417,7 @@ The DCS task structure.

    +
    +
    + + +GROUP:TaskRouteToVec2(Point, Speed) + +
    +
    + +

    Make the DCS Group to fly to a given point and hover.

    + +

    Parameters

    +
      +
    • + +

      DCSTypes#Vec3 Point : +The destination point in Vec3 format.

      + +
    • +
    • + +

      #number Speed : +The speed to travel.

      + +
    • +
    +

    Return value

    + +

    #GROUP: +self

    +
    @@ -2620,14 +2781,14 @@ A table of route points.

    -

    Make the group to fly to a given point and hover.

    +

    Make the DCS Group to fly to a given point and hover.

    Parameters

    - -

    Type Time

    - -

    Type Unit

    - -

    Type Vec2

    - -

    Type Vec3

    -

    Field(s)

    -
    -
    - - - -Vec3.x - -
    -
    - - - -
    -
    -
    -
    - - - -Vec3.y - -
    -
    - +

    DCSController#Controller:

    diff --git a/Documentation/MISSION.html b/Documentation/MISSION.html index 9de091e4d..0e909bbc5 100644 --- a/Documentation/MISSION.html +++ b/Documentation/MISSION.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -272,12 +287,6 @@ A CLIENT needs to be registered within the MISSION.SUCCESS - - - - MISSION.ShowBriefing(CLIENT, self, Client) - -

    Show the briefing of the MISSION to the CLIENT.

    @@ -1156,43 +1165,6 @@ local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical', - -
    -
    -
    - - -MISSION.ShowBriefing(CLIENT, self, Client) - -
    -
    - -

    Show the briefing of the MISSION to the CLIENT.

    - -

    Parameters

    - -

    Return value

    - - -

    CLIENT

    -
    diff --git a/Documentation/MOVEMENT.html b/Documentation/MOVEMENT.html index 98df22b0c..5d35d954c 100644 --- a/Documentation/MOVEMENT.html +++ b/Documentation/MOVEMENT.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Menu.html b/Documentation/Menu.html index 58ccee4f5..286cd3f1f 100644 --- a/Documentation/Menu.html +++ b/Documentation/Menu.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Message.html b/Documentation/Message.html index dd4087bf7..e7fb13b06 100644 --- a/Documentation/Message.html +++ b/Documentation/Message.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/MissileTrainer.html b/Documentation/MissileTrainer.html index 2eebd576b..8e21f7b5b 100644 --- a/Documentation/MissileTrainer.html +++ b/Documentation/MissileTrainer.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -90,9 +105,9 @@ It suports the following functionality:

  • Alerts: Menu to configure alert messages.
  • diff --git a/Documentation/NOTASK.html b/Documentation/NOTASK.html index d49ebedf5..8aeb474b4 100644 --- a/Documentation/NOTASK.html +++ b/Documentation/NOTASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/PICKUPTASK.html b/Documentation/PICKUPTASK.html index d888999c0..079600693 100644 --- a/Documentation/PICKUPTASK.html +++ b/Documentation/PICKUPTASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/ROUTETASK.html b/Documentation/ROUTETASK.html index c95432e3e..b53f143b3 100644 --- a/Documentation/ROUTETASK.html +++ b/Documentation/ROUTETASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/STAGE.html b/Documentation/STAGE.html index fd2ceedc0..c45a68326 100644 --- a/Documentation/STAGE.html +++ b/Documentation/STAGE.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Scheduler.html b/Documentation/Scheduler.html index 10a410720..41d757d5d 100644 --- a/Documentation/Scheduler.html +++ b/Documentation/Scheduler.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Scoring.html b/Documentation/Scoring.html index 34d058056..bcecc4626 100644 --- a/Documentation/Scoring.html +++ b/Documentation/Scoring.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Sead.html b/Documentation/Sead.html index d4631a922..e8bf12d86 100644 --- a/Documentation/Sead.html +++ b/Documentation/Sead.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Set.html b/Documentation/Set.html new file mode 100644 index 000000000..e43329a31 --- /dev/null +++ b/Documentation/Set.html @@ -0,0 +1,1332 @@ + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +

    Module Set

    + +

    Manage sets of units and groups.

    + + + +

    #Set class

    +

    Mission designers can use the SET class to build sets of units belonging to certain:

    + +
      +
    • Coalitions
    • +
    • Categories
    • +
    • Countries
    • +
    • Unit types
    • +
    • Starting with certain prefix strings.
    • +
    + +

    This list will grow over time. Planned developments are to include filters and iterators. +Additional filters will be added around Zone#ZONEs, Radiuses, Active players, ... +More iterators will be implemented in the near future ...

    + +

    Administers the Initial Sets of the Mission Templates as defined within the Mission Editor.

    + +

    SET construction methods:

    +

    Create a new SET object with the SET.New method:

    + +
      +
    • SET.New: Creates a new SET object.
    • +
    + + +

    SET filter criteria:

    +

    You can set filter criteria to define the set of units within the SET. +Filter criteria are defined by:

    + + + +

    Once the filter criteria have been set for the SET, you can start filtering using:

    + + + +

    Planned filter criteria within development are (so these are not yet available):

    + + + + +

    SET iterators:

    +

    Once the filters have been defined and the SET has been built, you can iterate the SET with the available iterator methods. +The iterator methods will walk the SET set, and call for each element within the set a function that you provide. +The following iterator methods are currently available within the SET:

    + + + +

    Planned iterators methods in development are (so these are not yet available):

    + +
      +
    • SET.ForEachUnit: Calls a function for each unit contained within the SET.
    • +
    • SET.ForEachGroup: Calls a function for each group contained within the SET.
    • +
    • SET.ForEachUnitInZone: Calls a function for each unit within a certain zone contained within the SET.
    • +
    + +
    + +

    Global(s)

    + + + + + +
    SET + +
    +

    Type SET

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SET:AddUnit(UnitToAdd) +

    Finds a Unit based on the Unit Name.

    +
    SET.ClassName + +
    SET.Clients + +
    SET.ClientsAlive + +
    SET.DCSGroups + +
    SET.DCSGroupsAlive + +
    SET.DCSUnits + +
    SET.DCSUnitsAlive + +
    SET.Filter + +
    SET:FilterCategories(Categories) +

    Builds a set of units out of categories.

    +
    SET:FilterCoalitions(Coalitions) +

    Builds a set of units of coalitons.

    +
    SET:FilterCountries(Countries) +

    Builds a set of units of defined countries.

    +
    SET:FilterGroupPrefixes(Prefixes) +

    Builds a set of units of defined group prefixes.

    +
    SET.FilterMeta + +
    SET:FilterStart() +

    Starts the filtering.

    +
    SET:FilterTypes(Types) +

    Builds a set of units of defined unit types.

    +
    SET:FilterUnitPrefixes(Prefixes) +

    Builds a set of units of defined unit prefixes.

    +
    SET:FindUnit(UnitName) +

    Finds a Unit based on the Unit Name.

    +
    SET:ForEach(IteratorFunction, arg, Set) +

    Interate the SET and call an interator function for the given set, providing the Object for each element within the set and optional parameters.

    +
    SET:ForEachClient(IteratorFunction, ...) +

    Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters.

    +
    SET:ForEachDCSUnitAlive(IteratorFunction, ...) +

    Interate the SET and call an interator function for each alive unit, providing the Unit and optional parameters.

    +
    SET:ForEachPlayer(IteratorFunction, ...) +

    Interate the SET and call an interator function for each alive player, providing the Unit of the player and optional parameters.

    +
    SET.Groups + +
    SET.GroupsAlive + +
    SET.NavPoints + +
    SET:New() +

    Creates a new SET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.

    +
    SET.Players + +
    SET.PlayersAlive + +
    SET:ScanEnvironment() + +
    SET.Statics + +
    SET.Templates + +
    SET:TraceDatabase() +

    Traces the current SET contents in the log ...

    +
    SET.Units + +
    SET.UnitsAlive + +
    SET:_EventOnBirth(Event) +

    Handles the OnBirth event for the alive units set.

    +
    SET:_EventOnDeadOrCrash(Event) +

    Handles the OnDead or OnCrash event for alive units set.

    +
    SET:_EventOnPlayerEnterUnit(Event) +

    Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).

    +
    SET:_EventOnPlayerLeaveUnit(Event) +

    Handles the OnPlayerLeaveUnit event to clean the active players table.

    +
    SET:_IsAliveDCSGroup(DCSGroup) + +
    SET:_IsAliveDCSUnit(DCSUnit) + +
    SET:_IsIncludeDCSUnit(DCSUnit) + +
    SET:_RegisterDatabase() +

    Private method that registers all datapoints within in the mission.

    +
    SET:_RegisterPlayers() +

    Private method that registers all alive players in the mission.

    +
    + +

    Global(s)

    +
    +
    + + #SET + +SET + +
    +
    + + + +
    +
    +

    Type Set

    + +

    Type SET

    + +

    SET class

    + +

    Field(s)

    +
    +
    + + +SET:AddUnit(UnitToAdd) + +
    +
    + +

    Finds a Unit based on the Unit Name.

    + +

    Parameter

    + +

    Return value

    + +

    Unit#UNIT: +The added Unit.

    + +
    +
    +
    +
    + + #string + +SET.ClassName + +
    +
    + + + +
    +
    +
    +
    + + + +SET.Clients + +
    +
    + + + +
    +
    +
    +
    + + + +SET.ClientsAlive + +
    +
    + + + +
    +
    +
    +
    + + + +SET.DCSGroups + +
    +
    + + + +
    +
    +
    +
    + + + +SET.DCSGroupsAlive + +
    +
    + + + +
    +
    +
    +
    + + + +SET.DCSUnits + +
    +
    + + + +
    +
    +
    +
    + + + +SET.DCSUnitsAlive + +
    +
    + + + +
    +
    +
    +
    + + + +SET.Filter + +
    +
    + + + +
    +
    +
    +
    + + +SET:FilterCategories(Categories) + +
    +
    + +

    Builds a set of units out of categories.

    + + +

    Possible current categories are plane, helicopter, ground, ship.

    + +

    Parameter

    +
      +
    • + +

      #string Categories : +Can take the following values: "plane", "helicopter", "ground", "ship".

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:FilterCoalitions(Coalitions) + +
    +
    + +

    Builds a set of units of coalitons.

    + + +

    Possible current coalitions are red, blue and neutral.

    + +

    Parameter

    +
      +
    • + +

      #string Coalitions : +Can take the following values: "red", "blue", "neutral".

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:FilterCountries(Countries) + +
    +
    + +

    Builds a set of units of defined countries.

    + + +

    Possible current countries are those known within DCS world.

    + +

    Parameter

    +
      +
    • + +

      #string Countries : +Can take those country strings known within DCS world.

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:FilterGroupPrefixes(Prefixes) + +
    +
    + +

    Builds a set of units of defined group prefixes.

    + + +

    All the units starting with the given group prefixes will be included within the set.

    + +

    Parameter

    +
      +
    • + +

      #string Prefixes : +The prefix of which the group name where the unit belongs to starts with.

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + + +SET.FilterMeta + +
    +
    + + + +
    +
    +
    +
    + + +SET:FilterStart() + +
    +
    + +

    Starts the filtering.

    + +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:FilterTypes(Types) + +
    +
    + +

    Builds a set of units of defined unit types.

    + + +

    Possible current types are those types known within DCS world.

    + +

    Parameter

    +
      +
    • + +

      #string Types : +Can take those type strings known within DCS world.

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:FilterUnitPrefixes(Prefixes) + +
    +
    + +

    Builds a set of units of defined unit prefixes.

    + + +

    All the units starting with the given prefixes will be included within the set.

    + +

    Parameter

    +
      +
    • + +

      #string Prefixes : +The prefix of which the unit name starts with.

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:FindUnit(UnitName) + +
    +
    + +

    Finds a Unit based on the Unit Name.

    + +

    Parameter

    +
      +
    • + +

      #string UnitName :

      + +
    • +
    +

    Return value

    + +

    Unit#UNIT: +The found Unit.

    + +
    +
    +
    +
    + + +SET:ForEach(IteratorFunction, arg, Set) + +
    +
    + +

    Interate the SET and call an interator function for the given set, providing the Object for each element within the set and optional parameters.

    + +

    Parameters

    +
      +
    • + +

      #function IteratorFunction : +The function that will be called when there is an alive player in the SET.

      + +
    • +
    • + +

      arg :

      + +
    • +
    • + +

      Set :

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:ForEachClient(IteratorFunction, ...) + +
    +
    + +

    Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters.

    + +

    Parameters

    +
      +
    • + +

      #function IteratorFunction : +The function that will be called when there is an alive player in the SET. The function needs to accept a CLIENT parameter.

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:ForEachDCSUnitAlive(IteratorFunction, ...) + +
    +
    + +

    Interate the SET and call an interator function for each alive unit, providing the Unit and optional parameters.

    + +

    Parameters

    +
      +
    • + +

      #function IteratorFunction : +The function that will be called when there is an alive unit in the SET. The function needs to accept a UNIT parameter.

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:ForEachPlayer(IteratorFunction, ...) + +
    +
    + +

    Interate the SET and call an interator function for each alive player, providing the Unit of the player and optional parameters.

    + +

    Parameters

    +
      +
    • + +

      #function IteratorFunction : +The function that will be called when there is an alive player in the SET. The function needs to accept a UNIT parameter.

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + + +SET.Groups + +
    +
    + + + +
    +
    +
    +
    + + + +SET.GroupsAlive + +
    +
    + + + +
    +
    +
    +
    + + + +SET.NavPoints + +
    +
    + + + +
    +
    +
    +
    + + +SET:New() + +
    +
    + +

    Creates a new SET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.

    + +

    Return value

    + +

    #SET:

    + + +

    Usage:

    +
    -- Define a new SET Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE.
    +DBObject = SET:New()
    + +
    +
    +
    +
    + + + +SET.Players + +
    +
    + + + +
    +
    +
    +
    + + + +SET.PlayersAlive + +
    +
    + + + +
    +
    +
    +
    + + +SET:ScanEnvironment() + +
    +
    + + + +
    +
    +
    +
    + + + +SET.Statics + +
    +
    + + + +
    +
    +
    +
    + + + +SET.Templates + +
    +
    + + + +
    +
    +
    +
    + + +SET:TraceDatabase() + +
    +
    + +

    Traces the current SET contents in the log ...

    + + +

    (for debug reasons).

    + +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + + +SET.Units + +
    +
    + + + +
    +
    +
    +
    + + + +SET.UnitsAlive + +
    +
    + + + +
    +
    +
    +
    + + +SET:_EventOnBirth(Event) + +
    +
    + +

    Handles the OnBirth event for the alive units set.

    + +

    Parameter

    + +
    +
    +
    +
    + + +SET:_EventOnDeadOrCrash(Event) + +
    +
    + +

    Handles the OnDead or OnCrash event for alive units set.

    + +

    Parameter

    + +
    +
    +
    +
    + + +SET:_EventOnPlayerEnterUnit(Event) + +
    +
    + +

    Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).

    + +

    Parameter

    + +
    +
    +
    +
    + + +SET:_EventOnPlayerLeaveUnit(Event) + +
    +
    + +

    Handles the OnPlayerLeaveUnit event to clean the active players table.

    + +

    Parameter

    + +
    +
    +
    +
    + + +SET:_IsAliveDCSGroup(DCSGroup) + +
    +
    + + + +

    Parameter

    + +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:_IsAliveDCSUnit(DCSUnit) + +
    +
    + + + +

    Parameter

    + +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:_IsIncludeDCSUnit(DCSUnit) + +
    +
    + + + +

    Parameter

    + +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:_RegisterDatabase() + +
    +
    + +

    Private method that registers all datapoints within in the mission.

    + +

    Return value

    + +

    #SET: +self

    + +
    +
    +
    +
    + + +SET:_RegisterPlayers() + +
    +
    + +

    Private method that registers all alive players in the mission.

    + +

    Return value

    + +

    #SET: +self

    + +
    +
    + +
    + +
    + + diff --git a/Documentation/Spawn.html b/Documentation/Spawn.html index 2f5ba12ef..9d0eb5271 100644 --- a/Documentation/Spawn.html +++ b/Documentation/Spawn.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/StaticObject.html b/Documentation/StaticObject.html index 9f6847026..a49ce3be6 100644 --- a/Documentation/StaticObject.html +++ b/Documentation/StaticObject.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/TASK.html b/Documentation/TASK.html index d18c673ff..301d33c96 100644 --- a/Documentation/TASK.html +++ b/Documentation/TASK.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Unit.html b/Documentation/Unit.html index ec8a45111..b1d81bcd6 100644 --- a/Documentation/Unit.html +++ b/Documentation/Unit.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,17 +54,91 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • Module Unit

    -

    UNIT Classes

    +

    UNIT Class

    + +

    UNIT class

    +

    The UNIT class is a wrapper class to handle the DCS Unit objects:

    + + + + + + + +

    UNIT reference methods

    +

    For each DCS Unit object alive within a running mission, a UNIT wrapper object (instance) will be created within the _DATABASE object. +This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Unit objects are spawned (using the SPAWN class).

    + +

    The UNIT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference +using the DCS Unit or the DCS UnitName.

    + +

    Another thing to know is that UNIT objects do not "contain" the DCS Unit object. +The UNIT methods will reference the DCS Unit object by name when it is needed during API execution. +If the DCS Unit object does not exist or is nil, the UNIT methods will return nil and log an exception in the DCS.log file.

    + +

    The UNIT class provides the following functions to retrieve quickly the relevant UNIT instance:

    + + + +

    IMPORTANT: ONE SHOULD NEVER SANATIZE these UNIT OBJECT REFERENCES! (make the UNIT object references nil).

    + +

    DCS UNIT APIs

    +

    The DCS Unit APIs are used extensively within MOOSE. The UNIT class has for each DCS Unit API a corresponding method. +To be able to distinguish easily in your code the difference between a UNIT API call and a DCS Unit API call, +the first letter of the method is also capitalized. So, by example, the DCS Unit method DCSUnit#Unit.getName() +is implemented in the UNIT class as UNIT.GetName().

    + +

    Additional UNIT APIs

    +

    The UNIT class comes with additional methods. Find below a summary.

    + +

    Smoke, Flare Units

    +

    The UNIT class provides methods to smoke or flare units easily. +The UNIT.SmokeBlue(), UNIT.SmokeGreen(),UNIT.SmokeOrange(), UNIT.SmokeRed(), UNIT.SmokeRed() methods +will smoke the unit in the corresponding color. Note that smoking a unit is done at the current position of the DCS Unit. +When the DCS Unit moves for whatever reason, the smoking will still continue! +The UNIT.FlareGreen(), UNIT.FlareRed(), UNIT.FlareWhite(), UNIT.FlareYellow() +methods will fire off a flare in the air with the corresponding color. Note that a flare is a one-off shot and its effect is of very short duration.

    + +

    Position, Point

    +

    The UNIT class provides methods to obtain the current point or position of the DCS Unit. +The UNIT.GetPointVec2(), UNIT.GetPointVec3() will obtain the current location of the DCS Unit in a Vec2 (2D) or a Vec3 (3D) vector respectively. +If you want to obtain the complete 3D position including oriëntation and direction vectors, consult the UNIT.GetPositionVec3() method respectively.

    + +

    Alive

    +

    The UNIT.IsAlive(), UNIT.IsActive() methods determines if the DCS Unit is alive, meaning, it is existing and active.

    + +

    Test for other units in radius

    +

    One can test if another DCS Unit is within a given radius of the current DCS Unit, by using the UNIT.OtherUnitInRadius() method.

    + +

    More functions will be added

    +

    During the MOOSE development, more functions will be added. A complete list of the current functions is below.

    + + + +

    Global(s)

    @@ -76,6 +161,18 @@ + + + + + + + + @@ -112,66 +209,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -183,19 +380,19 @@ - - - - + + + + @@ -352,6 +549,60 @@ + + +
    +
    + + +UNIT:Find(DCSUnit) + +
    +
    + +

    Finds a UNIT from the _DATABASE using a DCSUnit object.

    + +

    Parameter

    +
      +
    • + +

      DCSUnit#Unit DCSUnit : +An existing DCS Unit object reference.

      + +
    • +
    +

    Return value

    + +

    Unit#UNIT: +self

    + +
    +
    +
    +
    + + +UNIT:FindByName(UnitName) + +
    +
    + +

    Find a UNIT in the _DATABASE using the name of an existing DCS Unit.

    + +

    Parameter

    +
      +
    • + +

      #string UnitName : +The Unit Name.

      + +
    • +
    +

    Return value

    + +

    Unit#UNIT: +self

    +
    @@ -444,14 +695,85 @@
    + +UNIT:GetAltitude() + +
    +
    + +

    Returns the altitude of the DCS Unit.

    + +

    Return values

    +
      +
    1. + +

      DCSTypes#Distance: +The altitude of the DCS Unit.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetAmmo() + +
    +
    + +

    Returns the Unit's ammunition.

    + +

    Return values

    +
      +
    1. + +

      DCSUnit#Unit.Ammo:

      + + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + UNIT:GetCallSign()
    +

    Returns the unit's callsign - the localized string.

    +

    Return values

    +
      +
    1. + +

      #string: +The Callsign of the Unit.

      +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -463,13 +785,74 @@
    +

    Returns the DCS Unit category name as defined within the DCS Unit Descriptor.

    +

    Return value

    + +

    #string: +The DCS Unit Category Name

    + +UNIT:GetCoalition() + +
    +
    + +

    Returns coalition of the Unit.

    + +

    Return values

    +
      +
    1. + +

      DCSCoalitionObject#coalition.side: +The side of the coalition.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetCountry() + +
    +
    + +

    Returns country of the Unit.

    + +

    Return values

    +
      +
    1. + +

      DCScountry#country.id: +The country identifier.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + UNIT:GetDCSUnit() @@ -478,6 +861,96 @@ + +
    +
    +
    + + +UNIT:GetDesc() + +
    +
    + +

    Returns unit descriptor.

    + + +

    Descriptor type depends on unit category.

    + +

    Return values

    +
      +
    1. + +

      DCSUnit#Unit.Desc: +The Unit descriptor.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetFuel() + +
    +
    + +

    Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks.

    + + +

    If there are additional fuel tanks the value may be greater than 1.0.

    + +

    Return values

    +
      +
    1. + +

      #number: +The relative amount of fuel (from 0.0 to 1.0).

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetGroup() + +
    +
    + +

    Returns the unit's group if it exist and nil otherwise.

    + +

    Return values

    +
      +
    1. + +

      Group#GROUP: +The Group of the Unit.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -489,8 +962,82 @@
    +

    Returns the unit's unique identifier.

    +

    Return values

    +
      +
    1. + +

      DCSUnit#Unit.ID: +Unit ID

      +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetLife() + +
    +
    + +

    Returns the unit's health.

    + + +

    Dead units has health <= 1.0.

    + +

    Return values

    +
      +
    1. + +

      #number: +The Unit's health value.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetLife0() + +
    +
    + +

    Returns the Unit's initial health.

    + +

    Return values

    +
      +
    1. + +

      #number: +The Unit's initial health value.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -502,8 +1049,59 @@
    +

    Returns DCS Unit object name.

    + +

    The function provides access to non-activated units too.

    +

    Return values

    +
      +
    1. + +

      #string: +The name of the DCS Unit.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetNumber() + +
    +
    + +

    Returns the unit's number in the group.

    + + +

    The number is the same number the unit has in ME. +It may not be changed during the mission. +If any unit in the group is destroyed, the numbers of another units will not be changed.

    + +

    Return values

    +
      +
    1. + +

      #number: +The Unit number.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -515,8 +1113,23 @@
    +

    Returns name of the player that control the unit or nil if the unit is controlled by A.I.

    +

    Return values

    +
      +
    1. + +

      #string: +Player Name

      +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -528,8 +1141,51 @@
    +

    Returns the DCSTypes#Vec2 vector indicating the point in 2D of the DCS Unit within the mission.

    +

    Return values

    +
      +
    1. + +

      DCSTypes#Vec2: +The 2D point vector of the DCS Unit.

      +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetPointVec3() + +
    +
    + +

    Returns the DCSTypes#Vec3 vector indicating the point in 3D of the DCS Unit within the mission.

    + +

    Return values

    +
      +
    1. + +

      DCSTypes#Vec3: +The 3D point vector of the DCS Unit.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -541,8 +1197,23 @@
    +

    Returns the DCSTypes#Position3 position vectors indicating the point and direction vectors in 3D of the DCS Unit within the mission.

    +

    Return values

    +
      +
    1. + +

      DCSTypes#Position: +The 3D position vectors of the DCS Unit.

      +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -554,8 +1225,99 @@
    +

    Returns the prefix name of the DCS Unit.

    + + +

    A prefix name is a part of the name before a '#'-sign. +DCS Units spawned with the SPAWN class contain a '#'-sign to indicate the end of the (base) DCS Unit name. +The spawn sequence number and unit number are contained within the name after the '#' sign.

    + +

    Return values

    +
      +
    1. + +

      #string: +The name of the DCS Unit.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetRadar() + +
    +
    + +

    Returns two values:

    + +
      +
    • First value indicates if at least one of the unit's radar(s) is on.
    • +
    + + +
      +
    • Second value is the object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target.
    • +
    + +

    Return values

    +
      +
    1. + +

      #boolean: + Indicates if at least one of the unit's radar(s) is on.

      + +
    2. +
    3. + +

      DCSObject#Object: +The object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target.

      + +
    4. +
    5. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    6. +
    +
    +
    +
    +
    + + +UNIT:GetSensors() + +
    +
    + +

    Returns the unit sensors.

    + +

    Return values

    +
      +
    1. + +

      DCSUnit#Unit.Sensors:

      +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -567,8 +1329,107 @@
    +

    Returns the type name of the DCS Unit.

    +

    Return values

    +
      +
    1. + +

      #string: +The type name of the DCS Unit.

      +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:GetVelocity() + +
    +
    + +

    Returns the DCS Unit velocity vector.

    + +

    Return values

    +
      +
    1. + +

      DCSTypes#Vec3: +The velocity vector

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:InAir() + +
    +
    + +

    Returns true if the DCS Unit is in the air.

    + +

    Return values

    +
      +
    1. + +

      #boolean: +true if in the air.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:IsActive() + +
    +
    + +

    Returns if the unit is activated.

    + +

    Return values

    +
      +
    1. + +

      #boolean: +true if Unit is activated.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    @@ -601,34 +1462,23 @@ Air category evaluation result.

    +

    Returns if the unit is alive.

    - -
    -
    -
    -
    - - -UNIT:New(DCSUnit) - -
    -
    - -

    Create a new UNIT from DCSUnit.

    - -

    Parameter

    -
      +

      Return values

      +
      1. -

        DCSUnit#Unit DCSUnit :

        +

        #boolean: +true if Unit is alive.

      2. -
    -

    Return value

    +
  • -

    Unit#UNIT:

    - +

    #nil: +The DCS Unit is not existing or alive.

    +
  • +
    @@ -640,21 +1490,74 @@ Air category evaluation result.

    - +

    Returns true if there is an other DCS Unit within a radius of the current 2D point of the DCS Unit.

    Parameters

    • -

      AwaitUnit :

      +

      Unit#UNIT AwaitUnit : +The other UNIT wrapper object.

    • -

      Radius :

      +

      Radius : +The radius in meters with the DCS Unit in the centre.

    +

    Return values

    +
      +
    1. + + +

      true If the other DCS Unit is within the radius of the 2D point of the DCS Unit.

      + +
    2. +
    3. + +

      #nil: +The DCS Unit is not existing or alive.

      + +
    4. +
    +
    +
    +
    +
    + + +UNIT:Register(DCSUnit, Database, UnitName) + +
    +
    + +

    Create a new UNIT from DCSUnit.

    + +

    Parameters

    + +

    Return value

    + +

    Unit#UNIT:

    + +
    diff --git a/Documentation/Zone.html b/Documentation/Zone.html index ca4efd886..447c617e5 100644 --- a/Documentation/Zone.html +++ b/Documentation/Zone.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/env.html b/Documentation/env.html index 959ef7350..5a02f5de9 100644 --- a/Documentation/env.html +++ b/Documentation/env.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/index.html b/Documentation/index.html index 6900f9112..e260bcbe9 100644 --- a/Documentation/index.html +++ b/Documentation/index.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -75,6 +90,72 @@
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -134,7 +215,7 @@ @@ -207,12 +288,24 @@ + + + + + + + + @@ -224,13 +317,32 @@ + + + + + + + + diff --git a/Documentation/land.html b/Documentation/land.html index 5399503ee..82d512824 100644 --- a/Documentation/land.html +++ b/Documentation/land.html @@ -46,12 +46,15 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • StaticObject
  • TASK
  • diff --git a/Documentation/routines.html b/Documentation/routines.html index 806bd57e3..198b37402 100644 --- a/Documentation/routines.html +++ b/Documentation/routines.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -43,10 +54,14 @@
  • Scheduler
  • Scoring
  • Sead
  • +
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Embedded/Moose_Embedded.lua b/Embedded/Moose_Embedded.lua index 7d283599e..05b36b49a 100644 --- a/Embedded/Moose_Embedded.lua +++ b/Embedded/Moose_Embedded.lua @@ -3998,9 +3998,38 @@ function MENU_COALITION_COMMAND:Remove() self.ParentMenu.Menus[self.MenuPath] = nil return nil end ---- A GROUP class abstraction of a DCSGroup class. --- The GROUP class will take an abstraction of the DCSGroup class, providing more methods that can be done with a GROUP. +--- GROUP class. +-- +-- @{GROUP} class +-- ============== +-- The @{GROUP} class is a wrapper class to handle the DCS Group objects: +-- +-- * Support all DCS Group APIs. +-- * Enhance with Group specific APIs not in the DCS Group API set. +-- * Handle local Group Controller. +-- * Manage the "state" of the DCS Group. +-- +-- +-- GROUP reference methods +-- ======================= +-- For each DCS Group object alive within a running mission, a GROUP wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Group objects are spawned (using the @{SPAWN} class). +-- +-- The GROUP class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference +-- using the DCS Group or the DCS GroupName. +-- +-- Another thing to know is that GROUP objects do not "contain" the DCS Group object. +-- The GROUP methods will reference the DCS Group object by name when it is needed during API execution. +-- If the DCS Group object does not exist or is nil, the GROUP methods will return nil and log an exception in the DCS.log file. +-- +-- The GROUP class provides the following functions to retrieve quickly the relevant GROUP instance: +-- +-- * @{#GROUP.Find}(): Find a GROUP instance from the _DATABASE object using a DCS Group object. +-- * @{#GROUP.FindByName}(): Find a GROUP instance from the _DATABASE object using a DCS Group name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these GROUP OBJECT REFERENCES! (make the GROUP object references nil). -- @module Group +-- @author FlightControl Include.File( "Routines" ) Include.File( "Base" ) @@ -4012,8 +4041,6 @@ Include.File( "Unit" ) -- @extends Base#BASE -- @field DCSGroup#Group DCSGroup The DCS group class. -- @field #string GroupName The name of the group. --- @field #number GroupID the ID of the group. --- @field #table Controller The controller of the group. GROUP = { ClassName = "GROUP", GroupName = "", @@ -4027,81 +4054,310 @@ GROUP = { -- @type DCSGroup -- @field id_ The ID of the group in DCS ---- The GROUPS structure contains references to all the created GROUP instances. -local GROUPS = {} - --- Create a new GROUP from a DCSGroup -- @param #GROUP self --- @param DCSGroup#Group DCSGroup The DCS Group +-- @param DCSGroup#Group GroupName The DCS Group name -- @return #GROUP self -function GROUP:New( DCSGroup ) +function GROUP:Register( GroupName ) local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSGroup ) + self:F2( GroupName ) + self.GroupName = GroupName + return self +end - self.DCSGroup = DCSGroup - if self.DCSGroup and self.DCSGroup:isExist() then - self.GroupName = DCSGroup:getName() - self.GroupID = DCSGroup:getID() - self.Controller = DCSGroup:getController() - else - self:E( { "DCSGroup is nil or does not exist, cannot initialize GROUP!", self.DCSGroup } ) +-- Reference methods. + +--- Find the GROUP wrapper class instance using the DCS Group. +-- @param #GROUP self +-- @param DCSGroup#Group DCSGroup The DCS Group. +-- @return #GROUP The GROUP. +function GROUP:Find( DCSGroup ) + + local GroupName = DCSGroup:getName() -- Group#GROUP + local GroupFound = _DATABASE:FindGroup( GroupName ) + return GroupFound +end + +--- Find the created GROUP using the DCS Group Name. +-- @param #GROUP self +-- @param #string GroupName The DCS Group Name. +-- @return #GROUP The GROUP. +function GROUP:FindByName( GroupName ) + + local GroupFound = _DATABASE:FindGroup( GroupName ) + return GroupFound +end + +-- DCS Group methods support. + +--- Returns the DCS Group. +-- @param #GROUP self +-- @return DCSGroup#Group The DCS Group. +function GROUP:GetDCSGroup() + local DCSGroup = Group.getByName( self.GroupName ) + + if DCSGroup then + return DCSGroup + end + + return nil +end + + +--- Returns if the DCS Group is alive. +-- When the group exists at run-time, this method will return true, otherwise false. +-- @param #GROUP self +-- @return #boolean true if the DCS Group is alive. +function GROUP:IsAlive() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupIsAlive = DCSGroup:isExist() + self:T3( GroupIsAlive ) + return GroupIsAlive end - GROUPS[self.GroupID] = self - - return self + return nil end ---- Create a new GROUP from an existing group name. +--- Destroys the DCS Group and all of its DCS Units. +-- Note that this destroy method also raises a destroy event at run-time. +-- So all event listeners will catch the destroy event of this DCS Group. -- @param #GROUP self --- @param GroupName The name of the DCS Group. --- @return #GROUP self -function GROUP:NewFromName( GroupName ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( GroupName ) - - self.DCSGroup = Group.getByName( GroupName ) - if self.DCSGroup then - self.GroupName = self.DCSGroup:getName() - self.GroupID = self.DCSGroup:getID() - self.Controller = self.DCSGroup:getController() - end - - GROUPS[self.GroupID] = self - - return self +function GROUP:Destroy() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + self:CreateEventCrash( timer.getTime(), UnitData ) + end + DCSGroup:destroy() + DCSGroup = nil + end + + return nil end ---- Create a new GROUP from an existing DCSUnit in the mission. +--- Returns category of the DCS Group. -- @param #GROUP self --- @param DCSUnit The DCSUnit. --- @return #GROUP self -function GROUP:NewFromDCSUnit( DCSUnit ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSUnit ) +-- @return DCSGroup#Group.Category The category ID +function GROUP:GetCategory() + self:F2( self.GroupName ) - self.DCSGroup = DCSUnit:getGroup() - if self.DCSGroup then - self.GroupName = self.DCSGroup:getName() - self.GroupID = self.DCSGroup:getID() - self.Controller = self.DCSGroup:getController() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T3( GroupCategory ) + return GroupCategory + end + + return nil +end + +--- Returns the category name of the DCS Group. +-- @param #GROUP self +-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship +function GROUP:GetCategoryName() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local CategoryNames = { + [Group.Category.AIRPLANE] = "Airplane", + [Group.Category.HELICOPTER] = "Helicopter", + [Group.Category.GROUND] = "Ground Unit", + [Group.Category.SHIP] = "Ship", + } + local GroupCategory = DCSGroup:getCategory() + self:T3( GroupCategory ) + + return CategoryNames[GroupCategory] + end + + return nil +end + + +--- Returns the coalition of the DCS Group. +-- @param #GROUP self +-- @return DCSCoalitionObject#coalition.side The coalition side of the DCS Group. +function GROUP:GetCoalition() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local GroupCoalition = DCSGroup:getCoalition() + self:T3( GroupCoalition ) + return GroupCoalition + end + + return nil +end + +--- Returns the name of the DCS Group. +-- @param #GROUP self +-- @return #string The DCS Group name. +function GROUP:GetName() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupName = DCSGroup:getName() + self:T3( GroupName ) + return GroupName + end + + return nil +end + +--- Returns the DCS Group identifier. +-- @param #GROUP self +-- @return #number The identifier of the DCS Group. +function GROUP:GetID() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupID = DCSGroup:getID() + self:T3( GroupID ) + return GroupID + end + + return nil +end + +--- Returns the UNIT wrapper class with number UnitNumber. +-- If the underlying DCS Unit does not exist, the method will return nil. . +-- @param #GROUP self +-- @param #number UnitNumber The number of the UNIT wrapper class to be returned. +-- @return Unit#UNIT The UNIT wrapper class. +function GROUP:GetUnit( UnitNumber ) + self:F2( { self.GroupName, UnitNumber } ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local UnitFound = UNIT:Find( DCSGroup:getUnit( UnitNumber ) ) + self:T3( UnitFound.UnitName ) + self:T2( UnitFound ) + return UnitFound end - GROUPS[self.GroupID] = self - - return self + return nil end ---- Returns the name of the Group. +--- Returns the DCS Unit with number UnitNumber. +-- If the underlying DCS Unit does not exist, the method will return nil. . -- @param #GROUP self --- @return #string GroupName -function GROUP:GetName() +-- @param #number UnitNumber The number of the DCS Unit to be returned. +-- @return DCSUnit#Unit The DCS Unit. +function GROUP:GetDCSUnit( UnitNumber ) + self:F2( { self.GroupName, UnitNumber } ) - local GroupName = self.DCSGroup:getName() + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local DCSUnitFound = DCSGroup:getUnit( UnitNumber ) + self:T3( DCSUnitFound ) + return DCSUnitFound + end - return GroupName + return nil end +--- Returns current size of the DCS Group. +-- If some of the DCS Units of the DCS Group are destroyed the size of the DCS Group is changed. +-- @param #GROUP self +-- @return #number The DCS Group size. +function GROUP:GetSize() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupSize = DCSGroup:getSize() + self:T3( GroupSize ) + return GroupSize + end + + return nil +end + +--- +--- Returns the initial size of the DCS Group. +-- If some of the DCS Units of the DCS Group are destroyed, the initial size of the DCS Group is unchanged. +-- @param #GROUP self +-- @return #number The DCS Group initial size. +function GROUP:GetInitialSize() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupInitialSize = DCSGroup:getInitialSize() + self:T3( GroupInitialSize ) + return GroupInitialSize + end + + return nil +end + +--- Returns the UNITs wrappers of the DCS Units of the DCS Group. +-- @param #GROUP self +-- @return #table The UNITs wrappers. +function GROUP:GetUnits() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local DCSUnits = DCSGroup:getUnits() + local Units = {} + for Index, UnitData in pairs( DCSUnits ) do + Units[#Units+1] = UNIT:Find( UnitData ) + end + self:T3( Units ) + return Units + end + + return nil +end + + +--- Returns the DCS Units of the DCS Group. +-- @param #GROUP self +-- @return #table The DCS Units. +function GROUP:GetDCSUnits() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local DCSUnits = DCSGroup:getUnits() + self:T3( DCSUnits ) + return DCSUnits + end + + return nil +end + +--- Get the controller for the GROUP. +-- @param #GROUP self +-- @return DCSController#Controller +function GROUP:_GetController() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupController = DCSGroup:getController() + self:T3( GroupController ) + return GroupController + end + + return nil +end --- Retrieve the group mission and allow to place function hooks within the mission waypoint plan. @@ -4109,7 +4365,6 @@ end -- Use the method @{Group@GROUP:WayPointExecute) to start the execution of the new mission plan. -- Note that when WayPointInitialize is called, the Mission of the group is RESTARTED! -- @param #GROUP self --- @param #number WayPoint -- @return #GROUP function GROUP:WayPointInitialize() @@ -4126,7 +4381,7 @@ end -- @param #function WayPointFunction The waypoint function to be called when the group moves over the waypoint. The waypoint function takes variable parameters. -- @return #GROUP function GROUP:WayPointFunction( WayPoint, WayPointIndex, WayPointFunction, ... ) - self:F( { WayPoint, WayPointIndex, WayPointFunction } ) + self:F2( { WayPoint, WayPointIndex, WayPointFunction } ) table.insert( self.WayPoints[WayPoint].task.params.tasks, WayPointIndex ) self.WayPoints[WayPoint].task.params.tasks[WayPointIndex] = self:TaskFunction( WayPoint, WayPointIndex, WayPointFunction, arg ) @@ -4139,7 +4394,7 @@ function GROUP:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionAr local DCSTask local DCSScript = {} - DCSScript[#DCSScript+1] = "local MissionGroup = GROUP.FindGroup( ... ) " + DCSScript[#DCSScript+1] = "local MissionGroup = GROUP:Find( ... ) " if FunctionArguments.n > 0 then DCSScript[#DCSScript+1] = FunctionString .. "( MissionGroup, " .. table.concat( FunctionArguments, "," ) .. ")" @@ -4153,7 +4408,7 @@ function GROUP:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionAr ), WayPointIndex ) - self:T( DCSTask ) + self:T3( DCSTask ) return DCSTask @@ -4179,7 +4434,7 @@ function GROUP:WayPointExecute( WayPoint, WaitTime ) table.remove( self.WayPoints, 1 ) end - self:T( self.WayPoints ) + self:T3( self.WayPoints ) self:SetTask( self:TaskRoute( self.WayPoints ), WaitTime ) @@ -4187,148 +4442,70 @@ function GROUP:WayPointExecute( WayPoint, WaitTime ) end - ---- Gets the DCSGroup of the GROUP. --- @param #GROUP self --- @return DCSGroup#Group The DCSGroup. -function GROUP:GetDCSGroup() - self:F( { self.GroupName } ) - self.DCSGroup = Group.getByName( self.GroupName ) - return self.DCSGroup -end - ---- Gets the DCS Unit of the GROUP. --- @param #GROUP self --- @param #number UnitNumber The unit index to be returned from the GROUP. --- @return #Unit The DCS Unit. -function GROUP:GetDCSUnit( UnitNumber ) - self:F( { self.GroupName, UnitNumber } ) - return self.DCSGroup:getUnit( UnitNumber ) - -end - ---- Gets the DCSUnits of the GROUP. --- @param #GROUP self --- @return #table The DCSUnits. -function GROUP:GetDCSUnits() - self:F( { self.GroupName } ) - return self.DCSGroup:getUnits() - -end - --- Activates a GROUP. -- @param #GROUP self function GROUP:Activate() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) trigger.action.activateGroup( self:GetDCSGroup() ) return self:GetDCSGroup() end ---- Gets the ID of the GROUP. --- @param #GROUP self --- @return #number The ID of the GROUP. -function GROUP:GetID() - self:F( self.GroupName ) - - return self.GroupID -end - ---- Gets the name of the GROUP. --- @param #GROUP self --- @return #string The name of the GROUP. -function GROUP:GetName() - self:F( self.GroupName ) - - return self.GroupName -end --- Gets the type name of the group. -- @param #GROUP self -- @return #string The type name of the group. function GROUP:GetTypeName() - self:F( self.GroupName ) + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() - return self.DCSGroup:getUnit(1):getTypeName() + if DCSGroup then + local GroupTypeName = DCSGroup:getUnit(1):getTypeName() + self:T3( GroupTypeName ) + return( GroupTypeName ) + end + + return nil end ---- Gets the callsign of the fist unit of the group. +--- Gets the CallSign of the first DCS Unit of the DCS Group. -- @param #GROUP self --- @return #string The callsign of the first unit of the group. +-- @return #string The CallSign of the first DCS Unit of the DCS Group. function GROUP:GetCallsign() - self:F( self.GroupName ) + self:F2( self.GroupName ) - return self.DCSGroup:getUnit(1):getCallsign() + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupCallSign = DCSGroup:getUnit(1):getCallsign() + self:T3( GroupCallSign ) + return GroupCallSign + end + + return nil end ---- Gets the current Point of the GROUP in VEC3 format. --- @return #Vec3 Current x,y and z position of the group. +--- Returns the current point (Vec2 vector) of the first DCS Unit in the DCS Group. +-- @return DCSTypes#Vec2 Current Vec2 point of the first DCS Unit of the DCS Group. function GROUP:GetPointVec2() - self:F( self.GroupName ) + self:F2( self.GroupName ) - local GroupPoint = self:GetUnit(1):GetPointVec2() - self:T( GroupPoint ) - return GroupPoint + local GroupPointVec2 = self:GetUnit(1):GetPointVec2() + self:T3( GroupPointVec2 ) + return GroupPointVec2 end ---- Gets the current Point of the GROUP in VEC2 format. --- @return #Vec2 Current x and y position of the group in the 2D plane. -function GROUP:GetPointVec2() - self:F( self.GroupName ) +--- Returns the current point (Vec3 vector) of the first DCS Unit in the DCS Group. +-- @return DCSTypes#Vec3 Current Vec3 point of the first DCS Unit of the DCS Group. +function GROUP:GetPointVec3() + self:F2( self.GroupName ) - local GroupPoint = self:GetUnit(1):GetPointVec2() - self:T( GroupPoint ) - return GroupPoint + local GroupPointVec3 = self:GetUnit(1):GetPointVec3() + self:T3( GroupPointVec3 ) + return GroupPointVec3 end ---- Gets the current Point of the GROUP in VEC3 format. --- @return #Vec3 Current Vec3 position of the group. -function GROUP:GetPositionVec3() - self:F( self.GroupName ) - - local GroupPoint = self:GetUnit(1):GetPositionVec3() - self:T( GroupPoint ) - return GroupPoint -end ---- Destroy a GROUP --- Note that this destroy method also raises a destroy event at run-time. --- So all event listeners will catch the destroy event of this GROUP. --- @param #GROUP self -function GROUP:Destroy() - self:F( self.GroupName ) - - for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - self:CreateEventCrash( timer.getTime(), UnitData ) - end - - self.DCSGroup:destroy() - self.DCSGroup = nil -end - ---- Gets the DCS Unit. --- @param #GROUP self --- @param #number UnitNumber The number of the Unit to be returned. --- @return Unit#UNIT The DCS Unit. -function GROUP:GetUnit( UnitNumber ) - self:F( { self.GroupName, UnitNumber } ) - return UNIT:New( self.DCSGroup:getUnit( UnitNumber ) ) -end - ---- Returns the category name of the group. --- @param #GROUP self --- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship -function GROUP:GetCategoryName() - self:F( self.GroupName ) - - local CategoryNames = { - [Group.Category.AIRPLANE] = "Airplane", - [Group.Category.HELICOPTER] = "Helicopter", - [Group.Category.GROUND] = "Ground Unit", - [Group.Category.SHIP] = "Ship", - } - - return CategoryNames[self.DCSGroup:getCategory()] -end -- Is Functions @@ -4337,73 +4514,85 @@ end -- @param #GROUP self -- @return #boolean Air category evaluation result. function GROUP:IsAir() - self:F() - - local IsAirResult = self.DCSGroup:getCategory() == Group.Category.AIRPLANE or self.DCSGroup:getCategory() == Group.Category.HELICOPTER + self:F2( self.GroupName ) - self:T( IsAirResult ) - return IsAirResult + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local IsAirResult = DCSGroup:getCategory() == Group.Category.AIRPLANE or DCSGroup:getCategory() == Group.Category.HELICOPTER + self:T3( IsAirResult ) + return IsAirResult + end + + return nil end ---- Returns if the group is alive. --- When the group exists at run-time, this method will return true, otherwise false. +--- Returns if the DCS Group contains Helicopters. -- @param #GROUP self --- @return #boolean Alive result. -function GROUP:IsAlive() - self:F() - - local IsAliveResult = self.DCSGroup and self.DCSGroup:isExist() - - self:T( IsAliveResult ) - return IsAliveResult -end - ---- Returns if the GROUP is a Helicopter. --- @param #GROUP self --- @return #boolean true if GROUP are Helicopters. +-- @return #boolean true if DCS Group contains Helicopters. function GROUP:IsHelicopter() - self:F2() + self:F2( self.GroupName ) - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.HELICOPTER + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.HELICOPTER + end + + return nil end ---- Returns if the GROUP are AirPlanes. +--- Returns if the DCS Group contains AirPlanes. -- @param #GROUP self --- @return #boolean true if GROUP are AirPlanes. +-- @return #boolean true if DCS Group contains AirPlanes. function GROUP:IsAirPlane() self:F2() - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.AIRPLANE + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.AIRPLANE + end + + return nil end ---- Returns if the GROUP are Ground troops. +--- Returns if the DCS Group contains Ground troops. -- @param #GROUP self --- @return #boolean true if GROUP are Ground troops. +-- @return #boolean true if DCS Group contains Ground troops. function GROUP:IsGround() self:F2() - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.GROUND + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.GROUND + end + + return nil end ---- Returns if the GROUP are Ships. +--- Returns if the DCS Group contains Ships. -- @param #GROUP self --- @return #boolean true if GROUP are Ships. +-- @return #boolean true if DCS Group contains Ships. function GROUP:IsShip() self:F2() - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.SHIP + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.SHIP + end + + return nil end --- Returns if all units of the group are on the ground or landed. @@ -4411,18 +4600,24 @@ end -- @param #GROUP self -- @return #boolean All units on the ground result. function GROUP:AllOnGround() - self:F() + self:F2() - local AllOnGroundResult = true - - for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - if UnitData:inAir() then - AllOnGroundResult = false - end - end - - self:T( AllOnGroundResult ) - return AllOnGroundResult + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local AllOnGroundResult = true + + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + if UnitData:inAir() then + AllOnGroundResult = false + end + end + + self:T3( AllOnGroundResult ) + return AllOnGroundResult + end + + return nil end --- Returns the current maximum velocity of the group. @@ -4430,21 +4625,27 @@ end -- @param #GROUP self -- @return #number Maximum velocity found. function GROUP:GetMaxVelocity() - self:F() + self:F2() - local MaxVelocity = 0 - - for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - - local Velocity = UnitData:getVelocity() - local VelocityTotal = math.abs( Velocity.x ) + math.abs( Velocity.y ) + math.abs( Velocity.z ) - - if VelocityTotal < MaxVelocity then - MaxVelocity = VelocityTotal - end - end - - return MaxVelocity + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local MaxVelocity = 0 + + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + + local Velocity = UnitData:getVelocity() + local VelocityTotal = math.abs( Velocity.x ) + math.abs( Velocity.y ) + math.abs( Velocity.z ) + + if VelocityTotal < MaxVelocity then + MaxVelocity = VelocityTotal + end + end + + return MaxVelocity + end + + return nil end --- Returns the current minimum height of the group. @@ -4452,7 +4653,7 @@ end -- @param #GROUP self -- @return #number Minimum height found. function GROUP:GetMinHeight() - self:F() + self:F2() end @@ -4461,7 +4662,7 @@ end -- @param #GROUP self -- @return #number Maximum height found. function GROUP:GetMaxHeight() - self:F() + self:F2() end @@ -4471,68 +4672,85 @@ end -- @param #GROUP self -- @return Group#GROUP self function GROUP:PopCurrentTask() - self:F() + self:F2() - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - Controller:popTask() - - return self + if DCSGroup then + local Controller = self:_GetController() + Controller:popTask() + return self + end + + return nil end --- Pushing Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self function GROUP:PushTask( DCSTask, WaitTime ) - self:F() + self:F2() - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. - -- Therefore we schedule the functions to set the mission and options for the Group. - -- Controller:pushTask( DCSTask ) - - if not WaitTime then - Controller:pushTask( DCSTask ) - else - routines.scheduleFunction( Controller.pushTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + if DCSGroup then + local Controller = self:_GetController() + + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller:pushTask( DCSTask ) + + if WaitTime then + routines.scheduleFunction( Controller.pushTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + else + Controller:pushTask( DCSTask ) + end + + return self end - - return self + + return nil end --- Clearing the Task Queue and Setting the Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self function GROUP:SetTask( DCSTask, WaitTime ) - self:F( { DCSTask } ) + self:F2( { DCSTask } ) - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. - -- Therefore we schedule the functions to set the mission and options for the Group. - -- Controller.setTask( Controller, DCSTask ) - - if not WaitTime then - WaitTime = 1 + if DCSGroup then + + local Controller = self:_GetController() + + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller.setTask( Controller, DCSTask ) + + if not WaitTime then + WaitTime = 1 + end + routines.scheduleFunction( Controller.setTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + + return self end - routines.scheduleFunction( Controller.setTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) - return self + return nil end --- Return a condition section for a controlled task -- @param #GROUP self --- @param #Time time +-- @param DCSTime#Time time -- @param #string userFlag -- @param #boolean userFlagValue -- @param #string condition --- @param #Time duration +-- @param DCSTime#Time duration -- @param #number lastWayPoint -- return DCSTask#Task function GROUP:TaskCondition( time, userFlag, userFlagValue, condition, duration, lastWayPoint ) - self:F( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } ) + self:F2( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } ) local DCSStopCondition = {} DCSStopCondition.time = time @@ -4542,7 +4760,7 @@ function GROUP:TaskCondition( time, userFlag, userFlagValue, condition, duration DCSStopCondition.duration = duration DCSStopCondition.lastWayPoint = lastWayPoint - self:T( { DCSStopCondition } ) + self:T3( { DCSStopCondition } ) return DCSStopCondition end @@ -4552,7 +4770,7 @@ end -- @param #DCSStopCondition DCSStopCondition -- @return DCSTask#Task function GROUP:TaskControlled( DCSTask, DCSStopCondition ) - self:F( { DCSTask, DCSStopCondition } ) + self:F2( { DCSTask, DCSStopCondition } ) local DCSTaskControlled @@ -4564,7 +4782,7 @@ function GROUP:TaskControlled( DCSTask, DCSStopCondition ) } } - self:T( { DCSTaskControlled } ) + self:T3( { DCSTaskControlled } ) return DCSTaskControlled end @@ -4573,7 +4791,7 @@ end -- @param #list DCSTasks -- @return DCSTask#Task function GROUP:TaskCombo( DCSTasks ) - self:F( { DCSTasks } ) + self:F2( { DCSTasks } ) local DCSTaskCombo @@ -4584,7 +4802,7 @@ function GROUP:TaskCombo( DCSTasks ) } } - self:T( { DCSTaskCombo } ) + self:T3( { DCSTaskCombo } ) return DCSTaskCombo end @@ -4593,7 +4811,7 @@ end -- @param DCSCommand#Command DCSCommand -- @return DCSTask#Task function GROUP:TaskWrappedAction( DCSCommand, Index ) - self:F( { DCSCommand } ) + self:F2( { DCSCommand } ) local DCSTaskWrappedAction @@ -4607,7 +4825,7 @@ function GROUP:TaskWrappedAction( DCSCommand, Index ) }, } - self:T( { DCSTaskWrappedAction } ) + self:T3( { DCSTaskWrappedAction } ) return DCSTaskWrappedAction end @@ -4616,13 +4834,17 @@ end -- @param DCSCommand#Command DCSCommand -- @return #GROUP self function GROUP:SetCommand( DCSCommand ) - self:F( DCSCommand ) + self:F2( DCSCommand ) - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - Controller:setCommand( DCSCommand ) - - return self + if DCSGroup then + local Controller = self:_GetController() + Controller:setCommand( DCSCommand ) + return self + end + + return nil end --- Perform a switch waypoint command @@ -4631,7 +4853,7 @@ end -- @param #number ToWayPoint -- @return DCSTask#Task function GROUP:CommandSwitchWayPoint( FromWayPoint, ToWayPoint, Index ) - self:F( { FromWayPoint, ToWayPoint, Index } ) + self:F2( { FromWayPoint, ToWayPoint, Index } ) local CommandSwitchWayPoint = { id = 'SwitchWaypoint', @@ -4641,19 +4863,19 @@ function GROUP:CommandSwitchWayPoint( FromWayPoint, ToWayPoint, Index ) }, } - self:T( { CommandSwitchWayPoint } ) + self:T3( { CommandSwitchWayPoint } ) return CommandSwitchWayPoint end --- Orbit at a specified position at a specified alititude during a specified duration with a specified speed. -- @param #GROUP self --- @param #Vec2 Point The point to hold the position. +-- @param DCSTypes#Vec2 Point The point to hold the position. -- @param #number Altitude The altitude to hold the position. -- @param #number Speed The speed flying when holding the position. -- @return #GROUP self function GROUP:TaskOrbitCircleAtVec2( Point, Altitude, Speed ) - self:F( { self.GroupName, Point, Altitude, Speed } ) + self:F2( { self.GroupName, Point, Altitude, Speed } ) -- pattern = enum AI.Task.OribtPattern, -- point = Vec2, @@ -4663,7 +4885,7 @@ function GROUP:TaskOrbitCircleAtVec2( Point, Altitude, Speed ) local LandHeight = land.getHeight( Point ) - self:T( { LandHeight } ) + self:T3( { LandHeight } ) local DCSTask = { id = 'Orbit', params = { pattern = AI.Task.OrbitPattern.CIRCLE, @@ -4697,11 +4919,16 @@ end -- @param #number Speed The speed flying when holding the position. -- @return #GROUP self function GROUP:TaskOrbitCircle( Altitude, Speed ) - self:F( { self.GroupName, Altitude, Speed } ) + self:F2( { self.GroupName, Altitude, Speed } ) - local GroupPoint = self:GetPointVec2() + local DCSGroup = self:GetDCSGroup() - return self:TaskOrbitCircleAtVec2( GroupPoint, Altitude, Speed ) + if DCSGroup then + local GroupPoint = self:GetPointVec2() + return self:TaskOrbitCircleAtVec2( GroupPoint, Altitude, Speed ) + end + + return nil end @@ -4711,7 +4938,7 @@ end -- @param #number Duration The maximum duration in seconds to hold the position. -- @return #GROUP self function GROUP:TaskHoldPosition() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) return self:TaskOrbitCircle( 30, 10 ) end @@ -4719,11 +4946,11 @@ end --- Land the group at a Vec2Point. -- @param #GROUP self --- @param #Vec2 Point The point where to land. +-- @param DCSTypes#Vec2 Point The point where to land. -- @param #number Duration The duration in seconds to stay on the ground. -- @return #GROUP self function GROUP:TaskLandAtVec2( Point, Duration ) - self:F( { self.GroupName, Point, Duration } ) + self:F2( { self.GroupName, Point, Duration } ) local DCSTask @@ -4733,7 +4960,7 @@ function GROUP:TaskLandAtVec2( Point, Duration ) DCSTask = { id = 'Land', params = { point = Point, durationFlag = false } } end - self:T( DCSTask ) + self:T3( DCSTask ) return DCSTask end @@ -4743,7 +4970,7 @@ end -- @param #number Duration The duration in seconds to stay on the ground. -- @return #GROUP self function GROUP:TaskLandAtZone( Zone, Duration, RandomPoint ) - self:F( { self.GroupName, Zone, Duration, RandomPoint } ) + self:F2( { self.GroupName, Zone, Duration, RandomPoint } ) local Point if RandomPoint then @@ -4754,7 +4981,7 @@ function GROUP:TaskLandAtZone( Zone, Duration, RandomPoint ) local DCSTask = self:TaskLandAtVec2( Point, Duration ) - self:T( DCSTask ) + self:T3( DCSTask ) return DCSTask end @@ -4764,7 +4991,7 @@ end -- @param Unit#UNIT The unit. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskAttackUnit( AttackUnit ) - self:F( { self.GroupName, AttackUnit } ) + self:F2( { self.GroupName, AttackUnit } ) -- AttackUnit = { -- id = 'AttackUnit', @@ -4787,7 +5014,7 @@ function GROUP:TaskAttackUnit( AttackUnit ) }, }, - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -4796,7 +5023,7 @@ end -- @param Group#GROUP AttackGroup The Group to be attacked. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskAttackGroup( AttackGroup ) - self:F( { self.GroupName, AttackGroup } ) + self:F2( { self.GroupName, AttackGroup } ) -- AttackGroup = { -- id = 'AttackGroup', @@ -4820,7 +5047,7 @@ function GROUP:TaskAttackGroup( AttackGroup ) }, }, - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -4830,7 +5057,7 @@ end -- @param DCSTypes#Distance Radius The radius of the zone to deploy the fire at. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskFireAtPoint( PointVec2, Radius ) - self:F( { self.GroupName, PointVec2, Radius } ) + self:F2( { self.GroupName, PointVec2, Radius } ) -- FireAtPoint = { -- id = 'FireAtPoint', @@ -4847,7 +5074,7 @@ function GROUP:TaskFireAtPoint( PointVec2, Radius ) } } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -4855,12 +5082,12 @@ end --- Move the group to a Vec2 Point, wait for a defined duration and embark a group. -- @param #GROUP self --- @param #Vec2 Point The point where to wait. +-- @param DCSTypes#Vec2 Point The point where to wait. -- @param #number Duration The duration in seconds to wait. -- @param #GROUP EmbarkingGroup The group to be embarked. -- @return DCSTask#Task The DCS task structure function GROUP:TaskEmbarkingAtVec2( Point, Duration, EmbarkingGroup ) - self:F( { self.GroupName, Point, Duration, EmbarkingGroup.DCSGroup } ) + self:F2( { self.GroupName, Point, Duration, EmbarkingGroup.DCSGroup } ) local DCSTask DCSTask = { id = 'Embarking', @@ -4874,17 +5101,17 @@ function GROUP:TaskEmbarkingAtVec2( Point, Duration, EmbarkingGroup ) } } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end --- Move to a defined Vec2 Point, and embark to a group when arrived within a defined Radius. -- @param #GROUP self --- @param #Vec2 Point The point where to wait. +-- @param DCSTypes#Vec2 Point The point where to wait. -- @param #number Radius The radius of the embarking zone around the Point. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskEmbarkToTransportAtVec2( Point, Radius ) - self:F( { self.GroupName, Point, Radius } ) + self:F2( { self.GroupName, Point, Radius } ) local DCSTask --DCSTask#Task DCSTask = { id = 'EmbarkToTransport', @@ -4894,7 +5121,7 @@ function GROUP:TaskEmbarkToTransportAtVec2( Point, Radius ) } } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -4903,12 +5130,12 @@ end -- @param #table TaskMission A table containing the mission task. -- @return DCSTask#Task function GROUP:TaskMission( TaskMission ) - self:F( Points ) + self:F2( Points ) local DCSTask DCSTask = { id = 'Mission', params = { TaskMission, }, } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -4917,24 +5144,75 @@ end -- @param #table Points A table of route points. -- @return DCSTask#Task function GROUP:TaskRoute( Points ) - self:F( Points ) + self:F2( Points ) local DCSTask DCSTask = { id = 'Mission', params = { route = { points = Points, }, }, } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end ---- Make the group to fly to a given point and hover. +--- Make the DCS Group to fly to a given point and hover. -- @param #GROUP self --- @param #Vec3 Point The destination point. +-- @param DCSTypes#Vec3 Point The destination point in Vec3 format. +-- @param #number Speed The speed to travel. +-- @return #GROUP self +function GROUP:TaskRouteToVec2( Point, Speed ) + self:F2( { Point, Speed } ) + + local GroupPoint = self:GetUnit( 1 ):GetPointVec2() + + local PointFrom = {} + PointFrom.x = GroupPoint.x + PointFrom.y = GroupPoint.y + PointFrom.type = "Turning Point" + PointFrom.action = "Turning Point" + PointFrom.speed = Speed + PointFrom.speed_locked = true + PointFrom.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + + local PointTo = {} + PointTo.x = Point.x + PointTo.y = Point.y + PointTo.type = "Turning Point" + PointTo.action = "Fly Over Point" + PointTo.speed = Speed + PointTo.speed_locked = true + PointTo.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + self:Route( Points ) + + return self +end + +--- Make the DCS Group to fly to a given point and hover. +-- @param #GROUP self +-- @param DCSTypes#Vec3 Point The destination point in Vec3 format. -- @param #number Speed The speed to travel. -- @return #GROUP self function GROUP:TaskRouteToVec3( Point, Speed ) - self:F( { Point, Speed } ) + self:F2( { Point, Speed } ) - local GroupPoint = self:GetUnit( 1 ):GetPositionVec3() + local GroupPoint = self:GetUnit( 1 ):GetPointVec3() local PointFrom = {} PointFrom.x = GroupPoint.x @@ -4974,7 +5252,7 @@ function GROUP:TaskRouteToVec3( Point, Speed ) local Points = { PointFrom, PointTo } - self:T( Points ) + self:T3( Points ) self:Route( Points ) @@ -4988,16 +5266,20 @@ end -- @param #table GoPoints A table of Route Points. -- @return #GROUP self function GROUP:Route( GoPoints ) - self:F( GoPoints ) + self:F2( GoPoints ) - local Points = routines.utils.deepCopy( GoPoints ) - local MissionTask = { id = 'Mission', params = { route = { points = Points, }, }, } - - --self.Controller.setTask( self.Controller, MissionTask ) - - routines.scheduleFunction( self.Controller.setTask, { self.Controller, MissionTask}, timer.getTime() + 1 ) - - return self + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local Points = routines.utils.deepCopy( GoPoints ) + local MissionTask = { id = 'Mission', params = { route = { points = Points, }, }, } + local Controller = self:_GetController() + --Controller.setTask( Controller, MissionTask ) + routines.scheduleFunction( Controller.setTask, { Controller, MissionTask}, timer.getTime() + 1 ) + return self + end + + return nil end @@ -5012,50 +5294,57 @@ end -- @param #number Speed The speed. -- @param Base#FORMATION Formation The formation string. function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) - self:F( Zone ) - - local GroupPoint = self:GetPointVec2() - - local PointFrom = {} - PointFrom.x = GroupPoint.x - PointFrom.y = GroupPoint.y - PointFrom.type = "Turning Point" - PointFrom.action = "Cone" - PointFrom.speed = 20 / 1.6 - + self:F2( Zone ) - local PointTo = {} - local ZonePoint - - if Randomize then - ZonePoint = Zone:GetRandomPointVec2() - else - ZonePoint = Zone:GetPointVec2() - end - - PointTo.x = ZonePoint.x - PointTo.y = ZonePoint.y - PointTo.type = "Turning Point" - - if Formation then - PointTo.action = Formation - else - PointTo.action = "Cone" - end - - if Speed then - PointTo.speed = Speed - else - PointTo.speed = 20 / 1.6 - end - - local Points = { PointFrom, PointTo } - - self:T( Points ) - - self:Route( Points ) - - return self + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + + local GroupPoint = self:GetPointVec2() + + local PointFrom = {} + PointFrom.x = GroupPoint.x + PointFrom.y = GroupPoint.y + PointFrom.type = "Turning Point" + PointFrom.action = "Cone" + PointFrom.speed = 20 / 1.6 + + + local PointTo = {} + local ZonePoint + + if Randomize then + ZonePoint = Zone:GetRandomPointVec2() + else + ZonePoint = Zone:GetPointVec2() + end + + PointTo.x = ZonePoint.x + PointTo.y = ZonePoint.y + PointTo.type = "Turning Point" + + if Formation then + PointTo.action = Formation + else + PointTo.action = "Cone" + end + + if Speed then + PointTo.speed = Speed + else + PointTo.speed = 20 / 1.6 + end + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + self:Route( Points ) + + return self + end + + return nil end -- Commands @@ -5073,7 +5362,7 @@ function GROUP:CommandDoScript( DoScript ) }, } - self:T( DCSDoScript ) + self:T3( DCSDoScript ) return DCSDoScript end @@ -5082,7 +5371,7 @@ end -- @param #GROUP self -- @return #table The MissionTemplate function GROUP:GetTaskMission() - self:F( self.GroupName ) + self:F2( self.GroupName ) return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template ) end @@ -5091,7 +5380,7 @@ end -- @param #GROUP self -- @return #table The mission route defined by points. function GROUP:GetTaskRoute() - self:F( self.GroupName ) + self:F2( self.GroupName ) return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points ) end @@ -5103,7 +5392,7 @@ end -- @param #boolean Randomize Randomization of the route, when true. -- @param #number Radius When randomization is on, the randomization is within the radius. function GROUP:CopyRoute( Begin, End, Randomize, Radius ) - self:F( { Begin, End } ) + self:F2( { Begin, End } ) local Points = {} @@ -5115,7 +5404,7 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius ) GroupName = self:GetName() end - self:T( { GroupName } ) + self:T3( { GroupName } ) local Template = _DATABASE.Templates.Groups[GroupName].Template @@ -5145,36 +5434,37 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius ) return nil end ---- Get the controller for the GROUP. --- @function _GetController --- @param #GROUP self --- @return Controller#Controller -function GROUP:_GetController() - - return self.DCSGroup:getController() - -end function GROUP:GetDetectedTargets() + self:F2( self.GroupName ) - return self:_GetController():getDetectedTargets() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + return self:_GetController():getDetectedTargets() + end + return nil end function GROUP:IsTargetDetected( DCSObject ) - - local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity - = self:_GetController().isTargetDetected( self:_GetController(), DCSObject, - Controller.Detection.VISUAL, - Controller.Detection.OPTIC, - Controller.Detection.RADAR, - Controller.Detection.IRST, - Controller.Detection.RWR, - Controller.Detection.DLINK - ) - - return TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity - + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + + local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity + = self:_GetController().isTargetDetected( self:_GetController(), DCSObject, + Controller.Detection.VISUAL, + Controller.Detection.OPTIC, + Controller.Detection.RADAR, + Controller.Detection.IRST, + Controller.Detection.RWR, + Controller.Detection.DLINK + ) + return TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity + end + + return nil end -- Options @@ -5183,137 +5473,182 @@ end -- @param #GROUP self -- @return #boolean function GROUP:OptionROEHoldFirePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() or self:IsGround() or self:IsShip() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() or self:IsGround() or self:IsShip() then + return true + end + + return false end - return false + return nil end --- Holding weapons. -- @param Group#GROUP self -- @return Group#GROUP self function GROUP:OptionROEHoldFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_HOLD ) - elseif self:IsGround() then - Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD ) - elseif self:IsShip() then - Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.WEAPON_HOLD ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_HOLD ) + elseif self:IsGround() then + Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD ) + elseif self:IsShip() then + Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.WEAPON_HOLD ) + end + + return self end - return self + return nil end --- Can the GROUP attack returning on enemy fire? -- @param #GROUP self -- @return #boolean function GROUP:OptionROEReturnFirePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() or self:IsGround() or self:IsShip() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() or self:IsGround() or self:IsShip() then + return true + end + + return false end - return false + return nil end --- Return fire. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROEReturnFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.RETURN_FIRE ) - elseif self:IsGround() then - Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.RETURN_FIRE ) - elseif self:IsShip() then - Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.RETURN_FIRE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.RETURN_FIRE ) + elseif self:IsGround() then + Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.RETURN_FIRE ) + elseif self:IsShip() then + Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.RETURN_FIRE ) + end + + return self end - - return self + + return nil end --- Can the GROUP attack designated targets? -- @param #GROUP self -- @return #boolean function GROUP:OptionROEOpenFirePossible() - self:F( { self.GroupName } ) - - if self:IsAir() or self:IsGround() or self:IsShip() then - return true + self:F2( { self.GroupName } ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() or self:IsGround() or self:IsShip() then + return true + end + + return false end - return false + return nil end --- Openfire. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROEOpenFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.OPEN_FIRE ) + elseif self:IsGround() then + Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.OPEN_FIRE ) + elseif self:IsShip() then + Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.OPEN_FIRE ) + end - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.OPEN_FIRE ) - elseif self:IsGround() then - Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.OPEN_FIRE ) - elseif self:IsShip() then - Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.OPEN_FIRE ) + return self end - - return self + + return nil end --- Can the GROUP attack targets of opportunity? -- @param #GROUP self -- @return #boolean function GROUP:OptionROEWeaponFreePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end --- Weapon free. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROEWeaponFree() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_FREE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_FREE ) + end + + return self end - return self + return nil end --- Can the GROUP ignore enemy fire? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTNoReactionPossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end @@ -5321,56 +5656,76 @@ end -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTNoReaction() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.NO_REACTION ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.NO_REACTION ) + end + + return self end - return self + return nil end --- Can the GROUP evade using passive defenses? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTPassiveDefensePossible() - self:F( { self.GroupName } ) - - if self:IsAir() then - return true + self:F2( { self.GroupName } ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end --- Evasion passive defense. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTPassiveDefense() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.PASSIVE_DEFENCE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.PASSIVE_DEFENCE ) + end + + return self end - return self + return nil end --- Can the GROUP evade on enemy fire? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTEvadeFirePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end @@ -5378,28 +5733,38 @@ end -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTEvadeFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE ) + end + + return self end - return self + return nil end --- Can the GROUP evade on fire using vertical manoeuvres? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTVerticalPossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end @@ -5407,15 +5772,20 @@ end -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTVertical() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.BYPASS_AND_ESCAPE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.BYPASS_AND_ESCAPE ) + end + + return self end - return self + return nil end -- Message APIs @@ -5426,9 +5796,14 @@ end -- @param #Duration Duration The duration of the message. -- @return Message#MESSAGE function GROUP:Message( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - return MESSAGE:New( Message, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + return MESSAGE:New( Message, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) + end + + return nil end --- Send a message to all coalitions. @@ -5437,9 +5812,14 @@ end -- @param #string Message The message text -- @param #Duration Duration The duration of the message. function GROUP:MessageToAll( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToAll() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToAll() + end + + return nil end --- Send a message to the red coalition. @@ -5448,9 +5828,14 @@ end -- @param #string Message The message text -- @param #Duration Duration The duration of the message. function GROUP:MessageToRed( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToRed() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToRed() + end + + return nil end --- Send a message to the blue coalition. @@ -5459,9 +5844,14 @@ end -- @param #string Message The message text -- @param #Duration Duration The duration of the message. function GROUP:MessageToBlue( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToBlue() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToBlue() + end + + return nil end --- Send a message to a client. @@ -5471,29 +5861,89 @@ end -- @param #Duration Duration The duration of the message. -- @param Client#CLIENT Client The client object receiving the message. function GROUP:MessageToClient( Message, Duration, Client ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToClient( Client ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToClient( Client ) + end + + return nil end - - - - ---- Find the created GROUP using the DCSGroup ID. If a GROUP was created with the DCSGroupID, the the GROUP instance will be returned. --- Otherwise nil will be returned. --- @param DCSGroup#Group Group --- @return #GROUP -function GROUP.FindGroup( DCSGroup ) - - local self = GROUPS[DCSGroup:getID()] -- Group#GROUP - self:T( self:GetClassNameAndID() ) - return self - -end - - ---- UNIT Classes +--- UNIT Class +-- +-- @{UNIT} class +-- ============== +-- The @{UNIT} class is a wrapper class to handle the DCS Unit objects: +-- +-- * Support all DCS Unit APIs. +-- * Enhance with Unit specific APIs not in the DCS Unit API set. +-- * Handle local Unit Controller. +-- * Manage the "state" of the DCS Unit. +-- +-- +-- UNIT reference methods +-- ====================== +-- For each DCS Unit object alive within a running mission, a UNIT wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Unit objects are spawned (using the @{SPAWN} class). +-- +-- The UNIT class **does not contain a :New()** method, rather it provides **:Find()** methods to retrieve the object reference +-- using the DCS Unit or the DCS UnitName. +-- +-- Another thing to know is that UNIT objects do not "contain" the DCS Unit object. +-- The UNIT methods will reference the DCS Unit object by name when it is needed during API execution. +-- If the DCS Unit object does not exist or is nil, the UNIT methods will return nil and log an exception in the DCS.log file. +-- +-- The UNIT class provides the following functions to retrieve quickly the relevant UNIT instance: +-- +-- * @{#UNIT.Find}(): Find a UNIT instance from the _DATABASE object using a DCS Unit object. +-- * @{#UNIT.FindByName}(): Find a UNIT instance from the _DATABASE object using a DCS Unit name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these UNIT OBJECT REFERENCES! (make the UNIT object references nil). +-- +-- DCS UNIT APIs +-- ============= +-- The DCS Unit APIs are used extensively within MOOSE. The UNIT class has for each DCS Unit API a corresponding method. +-- To be able to distinguish easily in your code the difference between a UNIT API call and a DCS Unit API call, +-- the first letter of the method is also capitalized. So, by example, the DCS Unit method @{DCSUnit#Unit.getName}() +-- is implemented in the UNIT class as @{#UNIT.GetName}(). +-- +-- Additional UNIT APIs +-- ==================== +-- The UNIT class comes with additional methods. Find below a summary. +-- +-- Smoke, Flare Units +-- ------------------ +-- The UNIT class provides methods to smoke or flare units easily. +-- The @{#UNIT.SmokeBlue}(), @{#UNIT.SmokeGreen}(),@{#UNIT.SmokeOrange}(), @{#UNIT.SmokeRed}(), @{#UNIT.SmokeRed}() methods +-- will smoke the unit in the corresponding color. Note that smoking a unit is done at the current position of the DCS Unit. +-- When the DCS Unit moves for whatever reason, the smoking will still continue! +-- The @{#UNIT.FlareGreen}(), @{#UNIT.FlareRed}(), @{#UNIT.FlareWhite}(), @{#UNIT.FlareYellow}() +-- methods will fire off a flare in the air with the corresponding color. Note that a flare is a one-off shot and its effect is of very short duration. +-- +-- Position, Point +-- --------------- +-- The UNIT class provides methods to obtain the current point or position of the DCS Unit. +-- The @{#UNIT.GetPointVec2}(), @{#UNIT.GetPointVec3}() will obtain the current location of the DCS Unit in a Vec2 (2D) or a Vec3 (3D) vector respectively. +-- If you want to obtain the complete 3D position including oriëntation and direction vectors, consult the @{#UNIT.GetPositionVec3}() method respectively. +-- +-- Alive +-- ----- +-- The @{#UNIT.IsAlive}(), @{#UNIT.IsActive}() methods determines if the DCS Unit is alive, meaning, it is existing and active. +-- +-- Test for other units in radius +-- ------------------------------ +-- One can test if another DCS Unit is within a given radius of the current DCS Unit, by using the @{#UNIT.OtherUnitInRadius}() method. +-- +-- More functions will be added +-- ---------------------------- +-- During the MOOSE development, more functions will be added. A complete list of the current functions is below. +-- +-- +-- +-- -- @module Unit +-- @author FlightControl Include.File( "Routines" ) Include.File( "Base" ) @@ -5501,7 +5951,7 @@ Include.File( "Message" ) --- The UNIT class -- @type UNIT --- @Extends Base#BASE +-- @extends Base#BASE -- @field #UNIT.FlareColor FlareColor -- @field #UNIT.SmokeColor SmokeColor UNIT = { @@ -5542,206 +5992,639 @@ UNIT = { -- @field White -- @field Orange -- @field Blue - +-- Registration. + --- Create a new UNIT from DCSUnit. -- @param #UNIT self -- @param DCSUnit#Unit DCSUnit +-- @param Database#DATABASE Database -- @return Unit#UNIT -function UNIT:New( DCSUnit ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSUnit ) +function UNIT:Register( UnitName ) - self.DCSUnit = DCSUnit - if DCSUnit then - self.UnitName = DCSUnit:getName() - self.UnitID = DCSUnit:getID() - end - - return self + local self = BASE:Inherit( self, BASE:New() ) + self:F2( UnitName ) + self.UnitName = UnitName + return self end -function UNIT:IsAlive() - self:F( self.UnitName ) - - return ( self.DCSUnit and self.DCSUnit:isExist() ) +-- Reference methods. + +--- Finds a UNIT from the _DATABASE using a DCSUnit object. +-- @param #UNIT self +-- @param DCSUnit#Unit DCSUnit An existing DCS Unit object reference. +-- @return Unit#UNIT self +function UNIT:Find( DCSUnit ) + + local UnitName = DCSUnit:getName() + local UnitFound = _DATABASE:FindUnit( UnitName ) + return UnitFound end +--- Find a UNIT in the _DATABASE using the name of an existing DCS Unit. +-- @param #UNIT self +-- @param #string UnitName The Unit Name. +-- @return Unit#UNIT self +function UNIT:FindByName( UnitName ) + + local UnitFound = _DATABASE:FindUnit( UnitName ) + return UnitFound +end function UNIT:GetDCSUnit() - self:F( self.DCSUnit ) - - return self.DCSUnit -end - -function UNIT:GetID() - self:F( self.UnitID ) - - return self.UnitID -end - - -function UNIT:GetName() - self:F( self.UnitName ) - - return self.UnitName -end - -function UNIT:GetPlayerName() - self:F( self.UnitName ) - local DCSUnit = Unit.getByName( self.UnitName ) - local PlayerName = DCSUnit:getPlayerName() - if PlayerName == nil then - PlayerName = "" + if DCSUnit then + return DCSUnit end + + return nil +end + +--- Returns coalition of the Unit. +-- @param Unit#UNIT self +-- @return DCSCoalitionObject#coalition.side The side of the coalition. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetCoalition() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() - return PlayerName -end -function UNIT:GetTypeName() - self:F( self.UnitName ) - - return self.DCSUnit:getTypeName() + if DCSUnit then + local UnitCoalition = DCSUnit:getCoalition() + self:T3( UnitCoalition ) + return UnitCoalition + end + + return nil end -function UNIT:GetPrefix() - self:F( self.UnitName ) - - local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 ) - self:T( UnitPrefix ) +--- Returns country of the Unit. +-- @param Unit#UNIT self +-- @return DCScountry#country.id The country identifier. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetCountry() + self:F2( self.UnitName ) - return UnitPrefix + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitCountry = DCSUnit:getCountry() + self:T3( UnitCountry ) + return UnitCountry + end + + return nil +end + + +--- Returns DCS Unit object name. +-- The function provides access to non-activated units too. +-- @param Unit#UNIT self +-- @return #string The name of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetName() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitName = self.UnitName + return UnitName + end + + return nil end -function UNIT:GetCallSign() - self:F( self.UnitName ) +--- Returns if the unit is alive. +-- @param Unit#UNIT self +-- @return #boolean true if Unit is alive. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:IsAlive() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitIsAlive = DCSUnit:isExist() + return UnitIsAlive + end - return self.DCSUnit:getCallsign() -end - - -function UNIT:GetPointVec2() - self:F( self.UnitName ) - - local UnitPos = self.DCSUnit:getPosition().p - - local UnitPoint = {} - UnitPoint.x = UnitPos.x - UnitPoint.y = UnitPos.z - - self:T( UnitPoint ) - return UnitPoint -end - - -function UNIT:GetPositionVec3() - self:F( self.UnitName ) - - local UnitPos = self.DCSUnit:getPosition().p - - self:T( UnitPos ) - return UnitPos -end - -function UNIT:OtherUnitInRadius( AwaitUnit, Radius ) - self:F( { self.UnitName, AwaitUnit.UnitName, Radius } ) - - local UnitPos = self:GetPositionVec3() - local AwaitUnitPos = AwaitUnit:GetPositionVec3() - - if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then - self:T( "true" ) - return true - else - self:T( "false" ) - return false - end - - self:T( "false" ) return false end +--- Returns if the unit is activated. +-- @param Unit#UNIT self +-- @return #boolean true if Unit is activated. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:IsActive() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + + local UnitIsActive = DCSUnit:isActive() + return UnitIsActive + end + + return nil +end + +--- Returns name of the player that control the unit or nil if the unit is controlled by A.I. +-- @param Unit#UNIT self +-- @return #string Player Name +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPlayerName() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + + local PlayerName = DCSUnit:getPlayerName() + if PlayerName == nil then + PlayerName = "" + end + return PlayerName + end + + return nil +end + +--- Returns the unit's unique identifier. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.ID Unit ID +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetID() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitID = DCSUnit:getID() + return UnitID + end + + return nil +end + +--- Returns the unit's number in the group. +-- The number is the same number the unit has in ME. +-- It may not be changed during the mission. +-- If any unit in the group is destroyed, the numbers of another units will not be changed. +-- @param Unit#UNIT self +-- @return #number The Unit number. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetNumber() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitNumber = DCSUnit:getNumber() + return UnitNumber + end + + return nil +end + +--- Returns the unit's group if it exist and nil otherwise. +-- @param Unit#UNIT self +-- @return Group#GROUP The Group of the Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetGroup() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitGroup = DCSUnit:getGroup() + return UnitGroup + end + + return nil +end + + +--- Returns the unit's callsign - the localized string. +-- @param Unit#UNIT self +-- @return #string The Callsign of the Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetCallSign() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitCallSign = DCSUnit:getCallsign() + return UnitCallSign + end + + return nil +end + +--- Returns the unit's health. Dead units has health <= 1.0. +-- @param Unit#UNIT self +-- @return #number The Unit's health value. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetLife() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitLife = DCSUnit:getLife() + return UnitLife + end + + return nil +end + +--- Returns the Unit's initial health. +-- @param Unit#UNIT self +-- @return #number The Unit's initial health value. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetLife0() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitLife0 = DCSUnit:getLife0() + return UnitLife0 + end + + return nil +end + +--- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +-- @param Unit#UNIT self +-- @return #number The relative amount of fuel (from 0.0 to 1.0). +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetFuel() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitFuel = DCSUnit:getFuel() + return UnitFuel + end + + return nil +end + +--- Returns the Unit's ammunition. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.Ammo +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetAmmo() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitAmmo = DCSUnit:getAmmo() + return UnitAmmo + end + + return nil +end + +--- Returns the unit sensors. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.Sensors +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetSensors() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitSensors = DCSUnit:getSensors() + return UnitSensors + end + + return nil +end + +-- Need to add here a function per sensortype +-- unit:hasSensors(Unit.SensorType.RADAR, Unit.RadarType.AS) + +--- Returns two values: +-- +-- * First value indicates if at least one of the unit's radar(s) is on. +-- * Second value is the object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target. +-- @param Unit#UNIT self +-- @return #boolean Indicates if at least one of the unit's radar(s) is on. +-- @return DCSObject#Object The object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetRadar() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitRadarOn, UnitRadarObject = DCSUnit:getRadar() + return UnitRadarOn, UnitRadarObject + end + + return nil, nil +end + +-- Need to add here functions to check if radar is on and which object etc. + +--- Returns unit descriptor. Descriptor type depends on unit category. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.Desc The Unit descriptor. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetDesc() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitDesc = DCSUnit:getDesc() + return UnitDesc + end + + return nil +end + + +--- Returns the type name of the DCS Unit. +-- @param Unit#UNIT self +-- @return #string The type name of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetTypeName() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitTypeName = DCSUnit:getTypeName() + self:T3( UnitTypeName ) + return UnitTypeName + end + + return nil +end + + + +--- Returns the prefix name of the DCS Unit. A prefix name is a part of the name before a '#'-sign. +-- DCS Units spawned with the @{SPAWN} class contain a '#'-sign to indicate the end of the (base) DCS Unit name. +-- The spawn sequence number and unit number are contained within the name after the '#' sign. +-- @param Unit#UNIT self +-- @return #string The name of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPrefix() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 ) + self:T3( UnitPrefix ) + return UnitPrefix + end + + return nil +end + + + +--- Returns the @{DCSTypes#Vec2} vector indicating the point in 2D of the DCS Unit within the mission. +-- @param Unit#UNIT self +-- @return DCSTypes#Vec2 The 2D point vector of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPointVec2() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPointVec3 = DCSUnit:getPosition().p + + local UnitPointVec2 = {} + UnitPointVec2.x = UnitPointVec3.x + UnitPointVec2.y = UnitPointVec3.z + + self:T3( UnitPointVec2 ) + return UnitPointVec2 + end + + return nil +end + + +--- Returns the @{DCSTypes#Vec3} vector indicating the point in 3D of the DCS Unit within the mission. +-- @param Unit#UNIT self +-- @return DCSTypes#Vec3 The 3D point vector of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPointVec3() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPointVec3 = DCSUnit:getPosition().p + self:T3( UnitPointVec3 ) + return UnitPointVec3 + end + + return nil +end + +--- Returns the @{DCSTypes#Position3} position vectors indicating the point and direction vectors in 3D of the DCS Unit within the mission. +-- @param Unit#UNIT self +-- @return DCSTypes#Position The 3D position vectors of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPositionVec3() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPosition = DCSUnit:getPosition() + self:T3( UnitPosition ) + return UnitPosition + end + + return nil +end + +--- Returns the DCS Unit velocity vector. +-- @param Unit#UNIT self +-- @return DCSTypes#Vec3 The velocity vector +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetVelocity() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitVelocityVec3 = DCSUnit:getVelocity() + self:T3( UnitVelocityVec3 ) + return UnitVelocityVec3 + end + + return nil +end + +--- Returns true if the DCS Unit is in the air. +-- @param Unit#UNIT self +-- @return #boolean true if in the air. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:InAir() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitInAir = DCSUnit:inAir() + self:T3( UnitInAir ) + return UnitInAir + end + + return nil +end + +--- Returns the altitude of the DCS Unit. +-- @param Unit#UNIT self +-- @return DCSTypes#Distance The altitude of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetAltitude() + self:F2() + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPointVec3 = DCSUnit:getPoint() --DCSTypes#Vec3 + return UnitPointVec3.y + end + + return nil +end + +--- Returns true if there is an **other** DCS Unit within a radius of the current 2D point of the DCS Unit. +-- @param Unit#UNIT self +-- @param Unit#UNIT AwaitUnit The other UNIT wrapper object. +-- @param Radius The radius in meters with the DCS Unit in the centre. +-- @return true If the other DCS Unit is within the radius of the 2D point of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:OtherUnitInRadius( AwaitUnit, Radius ) + self:F2( { self.UnitName, AwaitUnit.UnitName, Radius } ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPos = self:GetPointVec3() + local AwaitUnitPos = AwaitUnit:GetPointVec3() + + if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then + self:T3( "true" ) + return true + else + self:T3( "false" ) + return false + end + end + + return nil +end + +--- Returns the DCS Unit category name as defined within the DCS Unit Descriptor. +-- @param Unit#UNIT self +-- @return #string The DCS Unit Category Name function UNIT:GetCategoryName() - return self.CategoryName[ self.DCSUnit:getDesc().category ] + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitCategoryName = self.CategoryName[ self:GetDesc().category ] + return UnitCategoryName + end + + return nil end --- Signal a flare at the position of the UNIT. -- @param #UNIT self function UNIT:Flare( FlareColor ) - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), FlareColor , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), FlareColor , 0 ) end --- Signal a white flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareWhite() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.White , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.White , 0 ) end --- Signal a yellow flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareYellow() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Yellow , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Yellow , 0 ) end --- Signal a green flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareGreen() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Green , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Green , 0 ) end --- Signal a red flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareRed() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Red, 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Red, 0 ) end --- Smoke the UNIT. -- @param #UNIT self function UNIT:Smoke( SmokeColor ) - self:F() - trigger.action.smoke( self:GetPositionVec3(), SmokeColor ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), SmokeColor ) end --- Smoke the UNIT Green. -- @param #UNIT self function UNIT:SmokeGreen() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Green ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Green ) end --- Smoke the UNIT Red. -- @param #UNIT self function UNIT:SmokeRed() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Red ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Red ) end --- Smoke the UNIT White. -- @param #UNIT self function UNIT:SmokeWhite() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.White ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.White ) end --- Smoke the UNIT Orange. -- @param #UNIT self function UNIT:SmokeOrange() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Orange ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Orange ) end --- Smoke the UNIT Blue. -- @param #UNIT self function UNIT:SmokeBlue() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Blue ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Blue ) end -- Is methods @@ -5751,14 +6634,14 @@ end -- @param #UNIT self -- @return #boolean Air category evaluation result. function UNIT:IsAir() - self:F() + self:F2() local UnitDescriptor = self.DCSUnit:getDesc() - self:T( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) + self:T3( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) local IsAirResult = ( UnitDescriptor.category == Unit.Category.AIRPLANE ) or ( UnitDescriptor.category == Unit.Category.HELICOPTER ) - self:T( IsAirResult ) + self:T3( IsAirResult ) return IsAirResult end @@ -5847,15 +6730,36 @@ end -- ================ -- Clients are those **Units** defined within the Mission Editor that have the skillset defined as __Client__ or __Player__. -- Note that clients are NOT the same as Units, they are NOT necessarily alive. +-- The @{CLIENT} class is a wrapper class to handle the DCS Unit objects that have the skillset defined as __Client__ or __Player__: +-- +-- * Wraps the DCS Unit objects with skill level set to Player or Client. +-- * Support all DCS Unit APIs. +-- * Enhance with Unit specific APIs not in the DCS Group API set. +-- * When player joins Unit, execute alive init logic. +-- * Handles messages to players. +-- * Manage the "state" of the DCS Unit. -- -- Clients are being used by the @{MISSION} class to follow players and register their successes. --- --- CLIENT construction methods: --- ============================ --- Create a new CLIENT object with the @{#CLIENT.New} method: --- --- * @{#CLIENT.New}: Creates a new CLIENT object taking the name of the **DCSUnit** that is a client as defined within the mission editor. -- +-- CLIENT reference methods +-- ======================= +-- For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts). +-- +-- The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference +-- using the DCS Unit or the DCS UnitName. +-- +-- Another thing to know is that CLIENT objects do not "contain" the DCS Unit object. +-- The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution. +-- If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file. +-- +-- The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance: +-- +-- * @{#CLIENT.Find}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object. +-- * @{#CLIENT.FindByName}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil). +-- -- @module Client -- @author FlightControl @@ -5867,7 +6771,7 @@ Include.File( "Message" ) --- The CLIENT class -- @type CLIENT --- @extends Base#BASE +-- @extends Unit#UNIT CLIENT = { ONBOARDSIDE = { NONE = 0, @@ -5888,7 +6792,35 @@ CLIENT = { } ---- Use this method to register new Clients within a mission. +--- Finds a CLIENT from the _DATABASE using the relevant DCS Unit. +-- @param #CLIENT self +-- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor. +-- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client. +-- @return #CLIENT +-- @usage +-- -- Create new Clients. +-- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' ) +-- Mission:AddGoal( DeploySA6TroopsGoal ) +-- +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) +function CLIENT:Find( DCSUnit ) + local ClientName = DCSUnit:getName() + local ClientFound = _DATABASE:FindClient( ClientName ) + + if ClientFound then + ClientFound:F( ClientName ) + return ClientFound + end + + error( "CLIENT not found for: " .. ClientName ) +end + + +--- Finds a CLIENT from the _DATABASE using the relevant Client Unit Name. +-- As an optional parameter, a briefing text can be given also. -- @param #CLIENT self -- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor. -- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client. @@ -5898,21 +6830,38 @@ CLIENT = { -- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' ) -- Mission:AddGoal( DeploySA6TroopsGoal ) -- --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() ) --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() ) --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() ) --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) -function CLIENT:New( ClientName, ClientBriefing ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( ClientName, ClientBriefing ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) +function CLIENT:FindByName( ClientName, ClientBriefing ) + local ClientFound = _DATABASE:FindClient( ClientName ) - self.ClientName = ClientName - self:AddBriefing( ClientBriefing ) - self.MessageSwitch = true - - return self + if ClientFound then + ClientFound:F( { ClientName, ClientBriefing } ) + ClientFound:AddBriefing( ClientBriefing ) + ClientFound.MessageSwitch = true + + return ClientFound + end + + error( "CLIENT not found for: " .. ClientName ) end +function CLIENT:Register( ClientName ) + local self = BASE:Inherit( self, UNIT:Register( ClientName ) ) + + self:F( ClientName ) + self.ClientName = ClientName + self.MessageSwitch = true + self.ClientAlive2 = false + + self.AliveCheckScheduler = routines.scheduleFunction( self._AliveCheckScheduler, { self }, timer.getTime() + 1, 5 ) + + return self +end + + --- Transport defines that the Client is a Transport. Transports show cargo. -- @param #CLIENT self -- @return #CLIENT @@ -5926,13 +6875,38 @@ end --- AddBriefing adds a briefing to a CLIENT when a player joins a mission. -- @param #CLIENT self -- @param #string ClientBriefing is the text defining the Mission briefing. --- @return #CLIENT +-- @return #CLIENT self function CLIENT:AddBriefing( ClientBriefing ) - self:F() + self:F( ClientBriefing ) self.ClientBriefing = ClientBriefing + self.ClientBriefingShown = false + return self end +--- Show the briefing of the MISSION to the CLIENT. +-- @param #CLIENT self +-- @return #CLIENT self +function CLIENT:ShowBriefing() + self:F( { self.ClientName, self.ClientBriefingShown } ) + + if not self.ClientBriefingShown then + self.ClientBriefingShown = true + local Briefing = "" + if self.MissionBriefing then + Briefing = Briefing .. self.MissionBriefing + end + if self.ClientBriefing then + Briefing = Briefing .. "\n" .. self.ClientBriefing + end + Briefing = Briefing .. "\nPress [LEFT ALT]+[B] to view the complete mission briefing." + self:Message( Briefing, 30, self.ClientName .. '/MissionBriefing', "Briefing" ) + end + + return self +end + + --- Resets a CLIENT. -- @param #CLIENT self @@ -5942,21 +6916,6 @@ function CLIENT:Reset( ClientName ) self._Menus = {} end ---- Checks for a client alive event and calls a function on a continuous basis. --- @param #CLIENT self --- @param #function CallBack Function. --- @return #CLIENT -function CLIENT:Alive( CallBack, ... ) - self:F() - - self.ClientAlive2 = false - self.ClientCallBack = CallBack - self.ClientParameters = arg - self.AliveCheckScheduler = routines.scheduleFunction( self._AliveCheckScheduler, { self }, timer.getTime() + 1, 5 ) - - return self -end - -- Is Functions --- Checks if the CLIENT is a multi-seated UNIT. @@ -5981,32 +6940,30 @@ function CLIENT:IsMultiSeated() return false end ---- Checks if client is alive and returns true or false. +--- Checks for a client alive event and calls a function on a continuous basis. -- @param #CLIENT self --- @returns #boolean Returns true if client is alive. -function CLIENT:IsAlive() - self:F( self.ClientName ) +-- @param #function CallBack Function. +-- @return #CLIENT +function CLIENT:Alive( CallBack, ... ) + self:F() - local ClientUnit = Unit.getByName( self.ClientName ) - - if ClientUnit and ClientUnit:isExist() then - self:T("true") - return true - end - - self:T( "false" ) - return false -end + self.ClientCallBack = CallBack + self.ClientParameters = arg + return self +end --- @param #CLIENT self function CLIENT:_AliveCheckScheduler() - self:F( { self.ClientName, self.ClientAlive2 } ) + self:F( { self.ClientName, self.ClientAlive2, self.ClientBriefingShown } ) - if self:IsAlive() then + if self:IsAlive() then -- Polymorphic call of UNIT if self.ClientAlive2 == false then - self:T("Calling Callback function") - self.ClientCallBack( self, unpack( self.ClientParameters ) ) + self:ShowBriefing() + if self.ClientCallBack then + self:T("Calling Callback function") + self.ClientCallBack( self, unpack( self.ClientParameters ) ) + end self.ClientAlive2 = true end else @@ -6127,7 +7084,7 @@ function CLIENT:GetClientGroupUnit() self:T( self.ClientDCSUnit ) if ClientDCSUnit and ClientDCSUnit:isExist() then - local ClientUnit = _DATABASE.Units[ self.ClientName ] + local ClientUnit = _DATABASE:FindUnit( self.ClientName ) self:T2( ClientUnit ) return ClientUnit end @@ -6147,109 +7104,6 @@ function CLIENT:GetClientGroupDCSUnit() end end --- TODO what is this??? check. possible double function. -function CLIENT:GetUnit() - self:F() - - return UNIT:New( self:GetClientGroupDCSUnit() ) -end - ---- Returns the position of the CLIENT in @{DCSTypes#Vec2} format.. --- @param #CLIENT self --- @return DCSTypes#Vec2 -function CLIENT:GetPointVec2() - self:F() - - local ClientGroupUnit = self:GetClientGroupDCSUnit() - - if ClientGroupUnit then - if ClientGroupUnit:isExist() then - local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3 - local PointVec2 = {} --DCSTypes#Vec2 - PointVec2.x = PointVec3.x - PointVec2.y = PointVec3.z - self:T( { PointVec2 } ) - return PointVec2 - end - end - - return nil -end - -function CLIENT:GetPositionVec3() - self:F( self.ClientName ) - - local DCSUnit = Unit.getByName( self.ClientName ) - local UnitPos = DCSUnit:getPosition().p - - self:T( UnitPos ) - return UnitPos -end - -function CLIENT:GetID() - self:F( self.ClientName ) - - local DCSUnit = Unit.getByName( self.ClientName ) - local UnitID = DCSUnit:getID() - - self:T( UnitID ) - return UnitID -end - -function CLIENT:GetName() - self:F( self.ClientName ) - - self:T( self.ClientName ) - return self.ClientName -end - -function CLIENT:GetTypeName() - self:F( self.ClientName ) - - local DCSUnit = Unit.getByName( self.ClientName ) - local TypeName = DCSUnit:getTypeName() - - self:T( TypeName ) - return TypeName -end - - - ---- Returns the position of the CLIENT in @{DCSTypes#Vec3} format. --- @param #CLIENT self --- @return DCSTypes#Vec3 -function CLIENT:ClientPosition() - self:F() - - local ClientGroupUnit = self:GetClientGroupDCSUnit() - - if ClientGroupUnit then - if ClientGroupUnit:isExist() then - return ClientGroupUnit:getPosition() - end - end - - return nil -end - ---- Returns the altitude of the CLIENT. --- @param #CLIENT self --- @return DCSTypes#Distance -function CLIENT:GetAltitude() - self:F() - - local ClientGroupUnit = self:GetClientGroupDCSUnit() - - if ClientGroupUnit then - if ClientGroupUnit:isExist() then - local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3 - return PointVec3.y - end - end - - return nil -end - --- Evaluates if the CLIENT is a transport. -- @param #CLIENT self @@ -6296,7 +7150,7 @@ end -- @param #string MessageCategory is the category of the message (the title). -- @param #number MessageInterval is the interval in seconds between the display of the @{Message#MESSAGE} when the CLIENT is in the air. function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, MessageInterval ) - self:F() + self:F( { Message, MessageDuration, MessageId, MessageCategory, MessageInterval } ) if not self.MenuMessages then if self:GetClientGroupID() then @@ -6420,18 +7274,14 @@ DATABASE = { ClientsByID = {}, }, DCSUnits = {}, - DCSUnitsAlive = {}, DCSGroups = {}, - DCSGroupsAlive = {}, - Units = {}, - UnitsAlive = {}, - Groups = {}, - GroupsAlive = {}, + UNITS = {}, + GROUPS = {}, NavPoints = {}, Statics = {}, Players = {}, PlayersAlive = {}, - Clients = {}, + CLIENTS = {}, ClientsAlive = {}, Filter = { Coalitions = nil, @@ -6499,168 +7349,67 @@ function DATABASE:New() return self end ---- Builds a set of units of coalitons. --- Possible current coalitions are red, blue and neutral. +--- Finds a Unit based on the Unit Name. -- @param #DATABASE self --- @param #string Coalitions Can take the following values: "red", "blue", "neutral". --- @return #DATABASE self -function DATABASE:FilterCoalitions( Coalitions ) - if not self.Filter.Coalitions then - self.Filter.Coalitions = {} - end - if type( Coalitions ) ~= "table" then - Coalitions = { Coalitions } - end - for CoalitionID, Coalition in pairs( Coalitions ) do - self.Filter.Coalitions[Coalition] = Coalition - end - return self +-- @param #string UnitName +-- @return Unit#UNIT The found Unit. +function DATABASE:FindUnit( UnitName ) + + local UnitFound = self.UNITS[UnitName] + return UnitFound end ---- Builds a set of units out of categories. --- Possible current categories are plane, helicopter, ground, ship. +--- Adds a Unit based on the Unit Name in the DATABASE. -- @param #DATABASE self --- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship". --- @return #DATABASE self -function DATABASE:FilterCategories( Categories ) - if not self.Filter.Categories then - self.Filter.Categories = {} - end - if type( Categories ) ~= "table" then - Categories = { Categories } - end - for CategoryID, Category in pairs( Categories ) do - self.Filter.Categories[Category] = Category - end - return self +function DATABASE:AddUnit( DCSUnit, DCSUnitName ) + + self.DCSUnits[DCSUnitName] = DCSUnit + self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName ) end ---- Builds a set of units of defined unit types. --- Possible current types are those types known within DCS world. +--- Deletes a Unit from the DATABASE based on the Unit Name. -- @param #DATABASE self --- @param #string Types Can take those type strings known within DCS world. --- @return #DATABASE self -function DATABASE:FilterTypes( Types ) - if not self.Filter.Types then - self.Filter.Types = {} - end - if type( Types ) ~= "table" then - Types = { Types } - end - for TypeID, Type in pairs( Types ) do - self.Filter.Types[Type] = Type - end - return self +function DATABASE:DeleteUnit( DCSUnitName ) + + self.DCSUnits[DCSUnitName] = nil end ---- Builds a set of units of defined countries. --- Possible current countries are those known within DCS world. +--- Finds a CLIENT based on the ClientName. -- @param #DATABASE self --- @param #string Countries Can take those country strings known within DCS world. --- @return #DATABASE self -function DATABASE:FilterCountries( Countries ) - if not self.Filter.Countries then - self.Filter.Countries = {} - end - if type( Countries ) ~= "table" then - Countries = { Countries } - end - for CountryID, Country in pairs( Countries ) do - self.Filter.Countries[Country] = Country - end - return self +-- @param #string ClientName +-- @return Client#CLIENT The found CLIENT. +function DATABASE:FindClient( ClientName ) + + local ClientFound = self.CLIENTS[ClientName] + return ClientFound end ---- Builds a set of units of defined unit prefixes. --- All the units starting with the given prefixes will be included within the set. +--- Adds a CLIENT based on the ClientName in the DATABASE. -- @param #DATABASE self --- @param #string Prefixes The prefix of which the unit name starts with. --- @return #DATABASE self -function DATABASE:FilterUnitPrefixes( Prefixes ) - if not self.Filter.UnitPrefixes then - self.Filter.UnitPrefixes = {} - end - if type( Prefixes ) ~= "table" then - Prefixes = { Prefixes } - end - for PrefixID, Prefix in pairs( Prefixes ) do - self.Filter.UnitPrefixes[Prefix] = Prefix - end - return self +function DATABASE:AddClient( ClientName ) + + self.CLIENTS[ClientName] = CLIENT:Register( ClientName ) + self:E( self.CLIENTS[ClientName]:GetClassNameAndID() ) end ---- Builds a set of units of defined group prefixes. --- All the units starting with the given group prefixes will be included within the set. +--- Finds a GROUP based on the GroupName. -- @param #DATABASE self --- @param #string Prefixes The prefix of which the group name where the unit belongs to starts with. --- @return #DATABASE self -function DATABASE:FilterGroupPrefixes( Prefixes ) - if not self.Filter.GroupPrefixes then - self.Filter.GroupPrefixes = {} - end - if type( Prefixes ) ~= "table" then - Prefixes = { Prefixes } - end - for PrefixID, Prefix in pairs( Prefixes ) do - self.Filter.GroupPrefixes[Prefix] = Prefix - end - return self +-- @param #string GroupName +-- @return Group#GROUP The found GROUP. +function DATABASE:FindGroup( GroupName ) + + local GroupFound = self.GROUPS[GroupName] + return GroupFound end ---- Starts the filtering. +--- Adds a GROUP based on the GroupName in the DATABASE. -- @param #DATABASE self --- @return #DATABASE self -function DATABASE:FilterStart() +function DATABASE:AddGroup( DCSGroup, GroupName ) - if _DATABASE then - -- OK, we have a _DATABASE - -- Now use the different filters to build the set. - -- We first take ALL of the Units of the _DATABASE. - - self:E( { "Adding Database Datapoints with filters" } ) - for DCSUnitName, DCSUnit in pairs( _DATABASE.DCSUnits ) do - - if self:_IsIncludeDCSUnit( DCSUnit ) then - - self:E( { "Adding Unit:", DCSUnitName } ) - self.DCSUnits[DCSUnitName] = _DATABASE.DCSUnits[DCSUnitName] - self.Units[DCSUnitName] = _DATABASE.Units[DCSUnitName] - - if _DATABASE.DCSUnitsAlive[DCSUnitName] then - self.DCSUnitsAlive[DCSUnitName] = _DATABASE.DCSUnitsAlive[DCSUnitName] - self.UnitsAlive[DCSUnitName] = _DATABASE.UnitsAlive[DCSUnitName] - end - - end - end - - for DCSGroupName, DCSGroup in pairs( _DATABASE.DCSGroups ) do - - --if self:_IsIncludeDCSGroup( DCSGroup ) then - self:E( { "Adding Group:", DCSGroupName } ) - self.DCSGroups[DCSGroupName] = _DATABASE.DCSGroups[DCSGroupName] - self.Groups[DCSGroupName] = _DATABASE.Groups[DCSGroupName] - --end - - if _DATABASE.DCSGroupsAlive[DCSGroupName] then - self.DCSGroupsAlive[DCSGroupName] = _DATABASE.DCSGroupsAlive[DCSGroupName] - self.GroupsAlive[DCSGroupName] = _DATABASE.GroupsAlive[DCSGroupName] - end - end - - for DCSUnitName, Client in pairs( _DATABASE.Clients ) do - self:E( { "Adding Client for Unit:", DCSUnitName } ) - self.Clients[DCSUnitName] = _DATABASE.Clients[DCSUnitName] - end - - else - self:E( "There is a structural error in MOOSE. No _DATABASE has been defined! Cannot build this custom DATABASE." ) - end - - return self + self.DCSGroups[GroupName] = DCSGroup + self.GROUPS[GroupName] = GROUP:Register( GroupName ) end - --- Instantiate new Groups within the DCSRTE. -- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined: -- SpawnCountryID, SpawnCategoryID @@ -6692,7 +7441,7 @@ function DATABASE:Spawn( SpawnTemplate ) SpawnTemplate.SpawnCategoryID = SpawnCategoryID - local SpawnGroup = GROUP:New( Group.getByName( SpawnTemplate.name ) ) + local SpawnGroup = GROUP:Register( SpawnTemplate.name ) return SpawnGroup end @@ -6787,7 +7536,7 @@ end -- @return #DATABASE self function DATABASE:_RegisterDatabase() - local CoalitionsData = { AlivePlayersRed = coalition.getGroups( coalition.side.RED ), AlivePlayersBlue = coalition.getGroups( coalition.side.BLUE ) } + local CoalitionsData = { GroupsRed = coalition.getGroups( coalition.side.RED ), GroupsBlue = coalition.getGroups( coalition.side.BLUE ) } for CoalitionId, CoalitionData in pairs( CoalitionsData ) do for DCSGroupId, DCSGroup in pairs( CoalitionData ) do @@ -6795,43 +7544,29 @@ function DATABASE:_RegisterDatabase() local DCSGroupName = DCSGroup:getName() self:E( { "Register Group:", DCSGroup, DCSGroupName } ) - self.DCSGroups[DCSGroupName] = DCSGroup - self.Groups[DCSGroupName] = GROUP:New( DCSGroup ) - - if self:_IsAliveDCSGroup(DCSGroup) then - self:E( { "Register Alive Group:", DCSGroup, DCSGroupName } ) - self.DCSGroupsAlive[DCSGroupName] = DCSGroup - self.GroupsAlive[DCSGroupName] = self.Groups[DCSGroupName] - end - + self:AddGroup( DCSGroup, DCSGroupName ) + for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do local DCSUnitName = DCSUnit:getName() self:E( { "Register Unit:", DCSUnit, DCSUnitName } ) - - self.DCSUnits[DCSUnitName] = DCSUnit - self.Units[DCSUnitName] = UNIT:New( DCSUnit ) - - if self:_IsAliveDCSUnit(DCSUnit) then - self:E( { "Register Alive Unit:", DCSUnit, DCSUnitName } ) - self.DCSUnitsAlive[DCSUnitName] = DCSUnit - self.UnitsAlive[DCSUnitName] = self.Units[DCSUnitName] - end + self:AddUnit( DCSUnit, DCSUnitName ) end else - self:E( "Group does not exist: " .. DCSGroup ) + self:E( { "Group does not exist: ", DCSGroup } ) end - for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do - self.Clients[ClientName] = CLIENT:New( ClientName ) - end end end + + for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do + self:E( { "Adding Client:", ClientName } ) + self:AddClient( ClientName ) + end return self end - --- Events --- Handles the OnBirth event for the alive units set. @@ -6842,15 +7577,8 @@ function DATABASE:_EventOnBirth( Event ) if Event.IniDCSUnit then if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - self.DCSUnits[Event.IniDCSUnitName] = Event.IniDCSUnit - self.DCSUnitsAlive[Event.IniDCSUnitName] = Event.IniDCSUnit - self.Units[Event.IniDCSUnitName] = UNIT:New( Event.IniDCSUnit ) - - --if not self.DCSGroups[Event.IniDCSGroupName] then - -- self.DCSGroups[Event.IniDCSGroupName] = Event.IniDCSGroupName - -- self.DCSGroupsAlive[Event.IniDCSGroupName] = Event.IniDCSGroupName - -- self.Groups[Event.IniDCSGroupName] = GROUP:New( Event.IniDCSGroup ) - --end + self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) + self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) self:_EventOnPlayerEnterUnit( Event ) end end @@ -6863,9 +7591,9 @@ function DATABASE:_EventOnDeadOrCrash( Event ) self:F( { Event } ) if Event.IniDCSUnit then - if self.DCSUnitsAlive[Event.IniDCSUnitName] then - self.DCSUnits[Event.IniDCSUnitName] = nil - self.DCSUnitsAlive[Event.IniDCSUnitName] = nil + if self.DCSUnits[Event.IniDCSUnitName] then + self:DeleteUnit( Event.IniDCSUnitName ) + -- add logic to correctly remove a group once all units are destroyed... end end end @@ -6881,7 +7609,7 @@ function DATABASE:_EventOnPlayerEnterUnit( Event ) if not self.PlayersAlive[Event.IniDCSUnitName] then self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() - self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ] + self.ClientsAlive[Event.IniDCSUnitName] = self.CLIENTS[ Event.IniDCSUnitName ] end end end @@ -6953,10 +7681,10 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter. -- @return #DATABASE self -function DATABASE:ForEachDCSUnitAlive( IteratorFunction, ... ) +function DATABASE:ForEachDCSUnit( IteratorFunction, ... ) self:F( arg ) - self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive ) + self:ForEach( IteratorFunction, arg, self.DCSUnits ) return self end @@ -6981,7 +7709,7 @@ end function DATABASE:ForEachClient( IteratorFunction, ... ) self:F( arg ) - self:ForEach( IteratorFunction, arg, self.Clients ) + self:ForEach( IteratorFunction, arg, self.CLIENTS ) return self end @@ -6991,7 +7719,7 @@ function DATABASE:ScanEnvironment() self:F() self.Navpoints = {} - self.Units = {} + self.UNITS = {} --Build routines.db.units and self.Navpoints for coa_name, coa_data in pairs(env.mission.coalition) do @@ -7164,7 +7892,6 @@ function DATABASE:TraceDatabase() self:F() self:T( { "DCSUnits:", self.DCSUnits } ) - self:T( { "DCSUnitsAlive:", self.DCSUnitsAlive } ) end @@ -8260,7 +8987,7 @@ function CARGO_ZONE:Signal() if SignalUnit then self:T( 'Signalling Unit' ) - local SignalVehiclePos = SignalUnit:GetPositionVec3() + local SignalVehiclePos = SignalUnit:GetPointVec3() SignalVehiclePos.y = SignalVehiclePos.y + 2 if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then @@ -8700,7 +9427,7 @@ function CARGO_GROUP:IsNear( Client, LandingZone ) if self.CargoGroupName then local CargoGroup = Group.getByName( self.CargoGroupName ) - if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 250 ) then + if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 250 ) then Near = true end end @@ -8805,7 +9532,7 @@ function CARGO_GROUP:OnBoarded( Client, LandingZone ) local CargoGroup = Group.getByName( self.CargoGroupName ) if not self.CargoInAir then - if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 25 ) then + if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 25 ) then CargoGroup:destroy() self:StatusLoaded( Client ) OnBoarded = true @@ -8904,7 +9631,7 @@ function CARGO_PACKAGE:IsNear( Client, LandingZone ) self:T( self.CargoClient.ClientName ) self:T( 'Client Exists.' ) - if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), Client:ClientPosition(), 150 ) then + if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), Client:GetPositionVec3(), 150 ) then Near = true end end @@ -9011,7 +9738,7 @@ function CARGO_PACKAGE:OnBoarded( Client, LandingZone ) local OnBoarded = false if self.CargoClient and self.CargoClient:GetDCSGroup() then - if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), self.CargoClient:ClientPosition(), 10 ) then + if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), self.CargoClient:GetPositionVec3(), 10 ) then -- Switch Cargo from self.CargoClient to Client ... Each cargo can have only one client. So assigning the new client for the cargo is enough. self:StatusLoaded( Client ) @@ -9506,7 +10233,7 @@ end function STAGEBRIEF:Execute( Mission, Client, Task ) local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) self:F() - Mission:ShowBriefing( Client ) + Client:ShowBriefing() self.StageBriefingTime = timer.getTime() return Valid end @@ -11742,25 +12469,6 @@ function MISSION:AddGoalFunction( GoalFunction ) self.GoalFunction = GoalFunction end ---- Show the briefing of the MISSION to the CLIENT. --- @param CLIENT Client to show briefing to. --- @return CLIENT -function MISSION:ShowBriefing( Client ) - self:F( { Client.ClientName } ) - - if not Client.ClientBriefingShown then - Client.ClientBriefingShown = true - local Briefing = self.MissionBriefing - if Client.ClientBriefing then - Briefing = Briefing .. "\n" .. Client.ClientBriefing - end - Briefing = Briefing .. "\n (Press [LEFT ALT]+[B] to view the graphical documentation.)" - Client:Message( Briefing, 30, self.Name .. '/MissionBriefing', "Command: Mission Briefing" ) - end - - return Client -end - --- Register a new @{CLIENT} to participate within the mission. -- @param CLIENT Client is the @{CLIENT} object. The object must have been instantiated with @{CLIENT:New}. -- @return CLIENT @@ -14670,7 +15378,7 @@ function ESCORT._HoldPosition( MenuParam ) routines.removeFunction( self.FollowScheduler ) local PointFrom = {} - local GroupPoint = EscortGroup:GetUnit(1):GetPositionVec3() + local GroupPoint = EscortGroup:GetUnit(1):GetPointVec3() PointFrom = {} PointFrom.x = GroupPoint.x PointFrom.y = GroupPoint.z @@ -15012,15 +15720,15 @@ function ESCORT:_FollowScheduler( FollowDistance ) local GroupUnit = self.EscortGroup:GetUnit( 1 ) if self.CT1 == 0 and self.GT1 == 0 then - self.CV1 = ClientUnit:GetPositionVec3() + self.CV1 = ClientUnit:GetPointVec3() self.CT1 = timer.getTime() - self.GV1 = GroupUnit:GetPositionVec3() + self.GV1 = GroupUnit:GetPointVec3() self.GT1 = timer.getTime() else local CT1 = self.CT1 local CT2 = timer.getTime() local CV1 = self.CV1 - local CV2 = ClientUnit:GetPositionVec3() + local CV2 = ClientUnit:GetPointVec3() self.CT1 = CT2 self.CV1 = CV2 @@ -15034,7 +15742,7 @@ function ESCORT:_FollowScheduler( FollowDistance ) local GT1 = self.GT1 local GT2 = timer.getTime() local GV1 = self.GV1 - local GV2 = GroupUnit:GetPositionVec3() + local GV2 = GroupUnit:GetPointVec3() self.GT1 = GT2 self.GV1 = GV2 @@ -15117,7 +15825,7 @@ function ESCORT:_ReportTargetsScheduler() self:T( EscortObject ) if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then - local EscortTargetUnit = UNIT:New( EscortObject ) + local EscortTargetUnit = UNIT:Find( EscortObject ) local EscortTargetUnitName = EscortTargetUnit:GetName() @@ -15140,8 +15848,8 @@ function ESCORT:_ReportTargetsScheduler() -- EscortTargetLastVelocity } ) - local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3() - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPointVec3() + local EscortPositionVec3 = self.EscortGroup:GetPointVec3() local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 @@ -15199,8 +15907,8 @@ function ESCORT:_ReportTargetsScheduler() EscortTargetMessage = EscortTargetMessage .. "Unknown target at " end - local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPositionVec3() - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPointVec3() + local EscortPositionVec3 = self.EscortGroup:GetPointVec3() local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 @@ -15267,7 +15975,7 @@ function ESCORT:_ReportTargetsScheduler() local TaskPoints = self:RegisterRoute() for WayPointID, WayPoint in pairs( TaskPoints ) do - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local EscortPositionVec3 = self.EscortGroup:GetPointVec3() local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 + ( WayPoint.y - EscortPositionVec3.z )^2 ) ^ 0.5 / 1000 @@ -15734,8 +16442,8 @@ function MISSILETRAINER:_EventShot( Event ) local Client = self.DBClients[TrainerTargetDCSUnitName] if Client then - local TrainerSourceUnit = UNIT:New(TrainerSourceDCSUnit) - local TrainerTargetUnit = UNIT:New(TrainerTargetDCSUnit) + local TrainerSourceUnit = UNIT:Find( TrainerSourceDCSUnit ) + local TrainerTargetUnit = UNIT:Find( TrainerTargetDCSUnit ) if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then @@ -15771,7 +16479,7 @@ function MISSILETRAINER:_AddRange( Client, TrainerWeapon ) if self.DetailsRangeOnOff then local PositionMissile = TrainerWeapon:getPoint() - local PositionTarget = Client:GetPositionVec3() + local PositionTarget = Client:GetPointVec3() local Range = ( ( PositionMissile.x - PositionTarget.x )^2 + ( PositionMissile.y - PositionTarget.y )^2 + @@ -15791,7 +16499,7 @@ function MISSILETRAINER:_AddBearing( Client, TrainerWeapon ) if self.DetailsBearingOnOff then local PositionMissile = TrainerWeapon:getPoint() - local PositionTarget = Client:GetPositionVec3() + local PositionTarget = Client:GetPointVec3() self:T2( { PositionTarget, PositionMissile }) @@ -15839,7 +16547,7 @@ function MISSILETRAINER:_TrackMissiles() if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then local PositionMissile = TrainerWeapon:getPosition().p - local PositionTarget = Client:GetPositionVec3() + local PositionTarget = Client:GetPointVec3() local Distance = ( ( PositionMissile.x - PositionTarget.x )^2 + ( PositionMissile.y - PositionTarget.y )^2 + diff --git a/Moose/Cargo.lua b/Moose/Cargo.lua index eb3152f91..9625e78d8 100644 --- a/Moose/Cargo.lua +++ b/Moose/Cargo.lua @@ -146,7 +146,7 @@ function CARGO_ZONE:Signal() if SignalUnit then self:T( 'Signalling Unit' ) - local SignalVehiclePos = SignalUnit:GetPositionVec3() + local SignalVehiclePos = SignalUnit:GetPointVec3() SignalVehiclePos.y = SignalVehiclePos.y + 2 if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then @@ -586,7 +586,7 @@ function CARGO_GROUP:IsNear( Client, LandingZone ) if self.CargoGroupName then local CargoGroup = Group.getByName( self.CargoGroupName ) - if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 250 ) then + if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 250 ) then Near = true end end @@ -691,7 +691,7 @@ function CARGO_GROUP:OnBoarded( Client, LandingZone ) local CargoGroup = Group.getByName( self.CargoGroupName ) if not self.CargoInAir then - if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 25 ) then + if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 25 ) then CargoGroup:destroy() self:StatusLoaded( Client ) OnBoarded = true @@ -790,7 +790,7 @@ function CARGO_PACKAGE:IsNear( Client, LandingZone ) self:T( self.CargoClient.ClientName ) self:T( 'Client Exists.' ) - if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), Client:ClientPosition(), 150 ) then + if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), Client:GetPositionVec3(), 150 ) then Near = true end end @@ -897,7 +897,7 @@ function CARGO_PACKAGE:OnBoarded( Client, LandingZone ) local OnBoarded = false if self.CargoClient and self.CargoClient:GetDCSGroup() then - if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), self.CargoClient:ClientPosition(), 10 ) then + if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), self.CargoClient:GetPositionVec3(), 10 ) then -- Switch Cargo from self.CargoClient to Client ... Each cargo can have only one client. So assigning the new client for the cargo is enough. self:StatusLoaded( Client ) diff --git a/Moose/Client.lua b/Moose/Client.lua index 238ca7fab..ab5bd0a6f 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -4,15 +4,36 @@ -- ================ -- Clients are those **Units** defined within the Mission Editor that have the skillset defined as __Client__ or __Player__. -- Note that clients are NOT the same as Units, they are NOT necessarily alive. +-- The @{CLIENT} class is a wrapper class to handle the DCS Unit objects that have the skillset defined as __Client__ or __Player__: +-- +-- * Wraps the DCS Unit objects with skill level set to Player or Client. +-- * Support all DCS Unit APIs. +-- * Enhance with Unit specific APIs not in the DCS Group API set. +-- * When player joins Unit, execute alive init logic. +-- * Handles messages to players. +-- * Manage the "state" of the DCS Unit. -- -- Clients are being used by the @{MISSION} class to follow players and register their successes. --- --- CLIENT construction methods: --- ============================ --- Create a new CLIENT object with the @{#CLIENT.New} method: --- --- * @{#CLIENT.New}: Creates a new CLIENT object taking the name of the **DCSUnit** that is a client as defined within the mission editor. -- +-- CLIENT reference methods +-- ======================= +-- For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts). +-- +-- The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference +-- using the DCS Unit or the DCS UnitName. +-- +-- Another thing to know is that CLIENT objects do not "contain" the DCS Unit object. +-- The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution. +-- If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file. +-- +-- The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance: +-- +-- * @{#CLIENT.Find}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object. +-- * @{#CLIENT.FindByName}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil). +-- -- @module Client -- @author FlightControl @@ -24,7 +45,7 @@ Include.File( "Message" ) --- The CLIENT class -- @type CLIENT --- @extends Base#BASE +-- @extends Unit#UNIT CLIENT = { ONBOARDSIDE = { NONE = 0, @@ -45,7 +66,35 @@ CLIENT = { } ---- Use this method to register new Clients within a mission. +--- Finds a CLIENT from the _DATABASE using the relevant DCS Unit. +-- @param #CLIENT self +-- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor. +-- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client. +-- @return #CLIENT +-- @usage +-- -- Create new Clients. +-- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' ) +-- Mission:AddGoal( DeploySA6TroopsGoal ) +-- +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) +function CLIENT:Find( DCSUnit ) + local ClientName = DCSUnit:getName() + local ClientFound = _DATABASE:FindClient( ClientName ) + + if ClientFound then + ClientFound:F( ClientName ) + return ClientFound + end + + error( "CLIENT not found for: " .. ClientName ) +end + + +--- Finds a CLIENT from the _DATABASE using the relevant Client Unit Name. +-- As an optional parameter, a briefing text can be given also. -- @param #CLIENT self -- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor. -- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client. @@ -55,21 +104,38 @@ CLIENT = { -- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' ) -- Mission:AddGoal( DeploySA6TroopsGoal ) -- --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() ) --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() ) --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() ) --- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) -function CLIENT:New( ClientName, ClientBriefing ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( ClientName, ClientBriefing ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() ) +-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() ) +function CLIENT:FindByName( ClientName, ClientBriefing ) + local ClientFound = _DATABASE:FindClient( ClientName ) - self.ClientName = ClientName - self:AddBriefing( ClientBriefing ) - self.MessageSwitch = true - - return self + if ClientFound then + ClientFound:F( { ClientName, ClientBriefing } ) + ClientFound:AddBriefing( ClientBriefing ) + ClientFound.MessageSwitch = true + + return ClientFound + end + + error( "CLIENT not found for: " .. ClientName ) end +function CLIENT:Register( ClientName ) + local self = BASE:Inherit( self, UNIT:Register( ClientName ) ) + + self:F( ClientName ) + self.ClientName = ClientName + self.MessageSwitch = true + self.ClientAlive2 = false + + self.AliveCheckScheduler = routines.scheduleFunction( self._AliveCheckScheduler, { self }, timer.getTime() + 1, 5 ) + + return self +end + + --- Transport defines that the Client is a Transport. Transports show cargo. -- @param #CLIENT self -- @return #CLIENT @@ -83,13 +149,38 @@ end --- AddBriefing adds a briefing to a CLIENT when a player joins a mission. -- @param #CLIENT self -- @param #string ClientBriefing is the text defining the Mission briefing. --- @return #CLIENT +-- @return #CLIENT self function CLIENT:AddBriefing( ClientBriefing ) - self:F() + self:F( ClientBriefing ) self.ClientBriefing = ClientBriefing + self.ClientBriefingShown = false + return self end +--- Show the briefing of the MISSION to the CLIENT. +-- @param #CLIENT self +-- @return #CLIENT self +function CLIENT:ShowBriefing() + self:F( { self.ClientName, self.ClientBriefingShown } ) + + if not self.ClientBriefingShown then + self.ClientBriefingShown = true + local Briefing = "" + if self.MissionBriefing then + Briefing = Briefing .. self.MissionBriefing + end + if self.ClientBriefing then + Briefing = Briefing .. "\n" .. self.ClientBriefing + end + Briefing = Briefing .. "\nPress [LEFT ALT]+[B] to view the complete mission briefing." + self:Message( Briefing, 30, self.ClientName .. '/MissionBriefing', "Briefing" ) + end + + return self +end + + --- Resets a CLIENT. -- @param #CLIENT self @@ -99,21 +190,6 @@ function CLIENT:Reset( ClientName ) self._Menus = {} end ---- Checks for a client alive event and calls a function on a continuous basis. --- @param #CLIENT self --- @param #function CallBack Function. --- @return #CLIENT -function CLIENT:Alive( CallBack, ... ) - self:F() - - self.ClientAlive2 = false - self.ClientCallBack = CallBack - self.ClientParameters = arg - self.AliveCheckScheduler = routines.scheduleFunction( self._AliveCheckScheduler, { self }, timer.getTime() + 1, 5 ) - - return self -end - -- Is Functions --- Checks if the CLIENT is a multi-seated UNIT. @@ -138,32 +214,30 @@ function CLIENT:IsMultiSeated() return false end ---- Checks if client is alive and returns true or false. +--- Checks for a client alive event and calls a function on a continuous basis. -- @param #CLIENT self --- @returns #boolean Returns true if client is alive. -function CLIENT:IsAlive() - self:F( self.ClientName ) +-- @param #function CallBack Function. +-- @return #CLIENT +function CLIENT:Alive( CallBack, ... ) + self:F() - local ClientUnit = Unit.getByName( self.ClientName ) - - if ClientUnit and ClientUnit:isExist() then - self:T("true") - return true - end - - self:T( "false" ) - return false -end + self.ClientCallBack = CallBack + self.ClientParameters = arg + return self +end --- @param #CLIENT self function CLIENT:_AliveCheckScheduler() - self:F( { self.ClientName, self.ClientAlive2 } ) + self:F( { self.ClientName, self.ClientAlive2, self.ClientBriefingShown } ) - if self:IsAlive() then + if self:IsAlive() then -- Polymorphic call of UNIT if self.ClientAlive2 == false then - self:T("Calling Callback function") - self.ClientCallBack( self, unpack( self.ClientParameters ) ) + self:ShowBriefing() + if self.ClientCallBack then + self:T("Calling Callback function") + self.ClientCallBack( self, unpack( self.ClientParameters ) ) + end self.ClientAlive2 = true end else @@ -284,7 +358,7 @@ function CLIENT:GetClientGroupUnit() self:T( self.ClientDCSUnit ) if ClientDCSUnit and ClientDCSUnit:isExist() then - local ClientUnit = _DATABASE.Units[ self.ClientName ] + local ClientUnit = _DATABASE:FindUnit( self.ClientName ) self:T2( ClientUnit ) return ClientUnit end @@ -304,109 +378,6 @@ function CLIENT:GetClientGroupDCSUnit() end end --- TODO what is this??? check. possible double function. -function CLIENT:GetUnit() - self:F() - - return UNIT:New( self:GetClientGroupDCSUnit() ) -end - ---- Returns the position of the CLIENT in @{DCSTypes#Vec2} format.. --- @param #CLIENT self --- @return DCSTypes#Vec2 -function CLIENT:GetPointVec2() - self:F() - - local ClientGroupUnit = self:GetClientGroupDCSUnit() - - if ClientGroupUnit then - if ClientGroupUnit:isExist() then - local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3 - local PointVec2 = {} --DCSTypes#Vec2 - PointVec2.x = PointVec3.x - PointVec2.y = PointVec3.z - self:T( { PointVec2 } ) - return PointVec2 - end - end - - return nil -end - -function CLIENT:GetPositionVec3() - self:F( self.ClientName ) - - local DCSUnit = Unit.getByName( self.ClientName ) - local UnitPos = DCSUnit:getPosition().p - - self:T( UnitPos ) - return UnitPos -end - -function CLIENT:GetID() - self:F( self.ClientName ) - - local DCSUnit = Unit.getByName( self.ClientName ) - local UnitID = DCSUnit:getID() - - self:T( UnitID ) - return UnitID -end - -function CLIENT:GetName() - self:F( self.ClientName ) - - self:T( self.ClientName ) - return self.ClientName -end - -function CLIENT:GetTypeName() - self:F( self.ClientName ) - - local DCSUnit = Unit.getByName( self.ClientName ) - local TypeName = DCSUnit:getTypeName() - - self:T( TypeName ) - return TypeName -end - - - ---- Returns the position of the CLIENT in @{DCSTypes#Vec3} format. --- @param #CLIENT self --- @return DCSTypes#Vec3 -function CLIENT:ClientPosition() - self:F() - - local ClientGroupUnit = self:GetClientGroupDCSUnit() - - if ClientGroupUnit then - if ClientGroupUnit:isExist() then - return ClientGroupUnit:getPosition() - end - end - - return nil -end - ---- Returns the altitude of the CLIENT. --- @param #CLIENT self --- @return DCSTypes#Distance -function CLIENT:GetAltitude() - self:F() - - local ClientGroupUnit = self:GetClientGroupDCSUnit() - - if ClientGroupUnit then - if ClientGroupUnit:isExist() then - local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3 - return PointVec3.y - end - end - - return nil -end - --- Evaluates if the CLIENT is a transport. -- @param #CLIENT self @@ -453,7 +424,7 @@ end -- @param #string MessageCategory is the category of the message (the title). -- @param #number MessageInterval is the interval in seconds between the display of the @{Message#MESSAGE} when the CLIENT is in the air. function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, MessageInterval ) - self:F() + self:F( { Message, MessageDuration, MessageId, MessageCategory, MessageInterval } ) if not self.MenuMessages then if self:GetClientGroupID() then diff --git a/Moose/Database.lua b/Moose/Database.lua index de88095e0..1814af91f 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -82,18 +82,14 @@ DATABASE = { ClientsByID = {}, }, DCSUnits = {}, - DCSUnitsAlive = {}, DCSGroups = {}, - DCSGroupsAlive = {}, - Units = {}, - UnitsAlive = {}, - Groups = {}, - GroupsAlive = {}, + UNITS = {}, + GROUPS = {}, NavPoints = {}, Statics = {}, Players = {}, PlayersAlive = {}, - Clients = {}, + CLIENTS = {}, ClientsAlive = {}, Filter = { Coalitions = nil, @@ -161,168 +157,67 @@ function DATABASE:New() return self end ---- Builds a set of units of coalitons. --- Possible current coalitions are red, blue and neutral. +--- Finds a Unit based on the Unit Name. -- @param #DATABASE self --- @param #string Coalitions Can take the following values: "red", "blue", "neutral". --- @return #DATABASE self -function DATABASE:FilterCoalitions( Coalitions ) - if not self.Filter.Coalitions then - self.Filter.Coalitions = {} - end - if type( Coalitions ) ~= "table" then - Coalitions = { Coalitions } - end - for CoalitionID, Coalition in pairs( Coalitions ) do - self.Filter.Coalitions[Coalition] = Coalition - end - return self +-- @param #string UnitName +-- @return Unit#UNIT The found Unit. +function DATABASE:FindUnit( UnitName ) + + local UnitFound = self.UNITS[UnitName] + return UnitFound end ---- Builds a set of units out of categories. --- Possible current categories are plane, helicopter, ground, ship. +--- Adds a Unit based on the Unit Name in the DATABASE. -- @param #DATABASE self --- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship". --- @return #DATABASE self -function DATABASE:FilterCategories( Categories ) - if not self.Filter.Categories then - self.Filter.Categories = {} - end - if type( Categories ) ~= "table" then - Categories = { Categories } - end - for CategoryID, Category in pairs( Categories ) do - self.Filter.Categories[Category] = Category - end - return self +function DATABASE:AddUnit( DCSUnit, DCSUnitName ) + + self.DCSUnits[DCSUnitName] = DCSUnit + self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName ) end ---- Builds a set of units of defined unit types. --- Possible current types are those types known within DCS world. +--- Deletes a Unit from the DATABASE based on the Unit Name. -- @param #DATABASE self --- @param #string Types Can take those type strings known within DCS world. --- @return #DATABASE self -function DATABASE:FilterTypes( Types ) - if not self.Filter.Types then - self.Filter.Types = {} - end - if type( Types ) ~= "table" then - Types = { Types } - end - for TypeID, Type in pairs( Types ) do - self.Filter.Types[Type] = Type - end - return self +function DATABASE:DeleteUnit( DCSUnitName ) + + self.DCSUnits[DCSUnitName] = nil end ---- Builds a set of units of defined countries. --- Possible current countries are those known within DCS world. +--- Finds a CLIENT based on the ClientName. -- @param #DATABASE self --- @param #string Countries Can take those country strings known within DCS world. --- @return #DATABASE self -function DATABASE:FilterCountries( Countries ) - if not self.Filter.Countries then - self.Filter.Countries = {} - end - if type( Countries ) ~= "table" then - Countries = { Countries } - end - for CountryID, Country in pairs( Countries ) do - self.Filter.Countries[Country] = Country - end - return self +-- @param #string ClientName +-- @return Client#CLIENT The found CLIENT. +function DATABASE:FindClient( ClientName ) + + local ClientFound = self.CLIENTS[ClientName] + return ClientFound end ---- Builds a set of units of defined unit prefixes. --- All the units starting with the given prefixes will be included within the set. +--- Adds a CLIENT based on the ClientName in the DATABASE. -- @param #DATABASE self --- @param #string Prefixes The prefix of which the unit name starts with. --- @return #DATABASE self -function DATABASE:FilterUnitPrefixes( Prefixes ) - if not self.Filter.UnitPrefixes then - self.Filter.UnitPrefixes = {} - end - if type( Prefixes ) ~= "table" then - Prefixes = { Prefixes } - end - for PrefixID, Prefix in pairs( Prefixes ) do - self.Filter.UnitPrefixes[Prefix] = Prefix - end - return self +function DATABASE:AddClient( ClientName ) + + self.CLIENTS[ClientName] = CLIENT:Register( ClientName ) + self:E( self.CLIENTS[ClientName]:GetClassNameAndID() ) end ---- Builds a set of units of defined group prefixes. --- All the units starting with the given group prefixes will be included within the set. +--- Finds a GROUP based on the GroupName. -- @param #DATABASE self --- @param #string Prefixes The prefix of which the group name where the unit belongs to starts with. --- @return #DATABASE self -function DATABASE:FilterGroupPrefixes( Prefixes ) - if not self.Filter.GroupPrefixes then - self.Filter.GroupPrefixes = {} - end - if type( Prefixes ) ~= "table" then - Prefixes = { Prefixes } - end - for PrefixID, Prefix in pairs( Prefixes ) do - self.Filter.GroupPrefixes[Prefix] = Prefix - end - return self +-- @param #string GroupName +-- @return Group#GROUP The found GROUP. +function DATABASE:FindGroup( GroupName ) + + local GroupFound = self.GROUPS[GroupName] + return GroupFound end ---- Starts the filtering. +--- Adds a GROUP based on the GroupName in the DATABASE. -- @param #DATABASE self --- @return #DATABASE self -function DATABASE:FilterStart() +function DATABASE:AddGroup( DCSGroup, GroupName ) - if _DATABASE then - -- OK, we have a _DATABASE - -- Now use the different filters to build the set. - -- We first take ALL of the Units of the _DATABASE. - - self:E( { "Adding Database Datapoints with filters" } ) - for DCSUnitName, DCSUnit in pairs( _DATABASE.DCSUnits ) do - - if self:_IsIncludeDCSUnit( DCSUnit ) then - - self:E( { "Adding Unit:", DCSUnitName } ) - self.DCSUnits[DCSUnitName] = _DATABASE.DCSUnits[DCSUnitName] - self.Units[DCSUnitName] = _DATABASE.Units[DCSUnitName] - - if _DATABASE.DCSUnitsAlive[DCSUnitName] then - self.DCSUnitsAlive[DCSUnitName] = _DATABASE.DCSUnitsAlive[DCSUnitName] - self.UnitsAlive[DCSUnitName] = _DATABASE.UnitsAlive[DCSUnitName] - end - - end - end - - for DCSGroupName, DCSGroup in pairs( _DATABASE.DCSGroups ) do - - --if self:_IsIncludeDCSGroup( DCSGroup ) then - self:E( { "Adding Group:", DCSGroupName } ) - self.DCSGroups[DCSGroupName] = _DATABASE.DCSGroups[DCSGroupName] - self.Groups[DCSGroupName] = _DATABASE.Groups[DCSGroupName] - --end - - if _DATABASE.DCSGroupsAlive[DCSGroupName] then - self.DCSGroupsAlive[DCSGroupName] = _DATABASE.DCSGroupsAlive[DCSGroupName] - self.GroupsAlive[DCSGroupName] = _DATABASE.GroupsAlive[DCSGroupName] - end - end - - for DCSUnitName, Client in pairs( _DATABASE.Clients ) do - self:E( { "Adding Client for Unit:", DCSUnitName } ) - self.Clients[DCSUnitName] = _DATABASE.Clients[DCSUnitName] - end - - else - self:E( "There is a structural error in MOOSE. No _DATABASE has been defined! Cannot build this custom DATABASE." ) - end - - return self + self.DCSGroups[GroupName] = DCSGroup + self.GROUPS[GroupName] = GROUP:Register( GroupName ) end - --- Instantiate new Groups within the DCSRTE. -- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined: -- SpawnCountryID, SpawnCategoryID @@ -354,7 +249,7 @@ function DATABASE:Spawn( SpawnTemplate ) SpawnTemplate.SpawnCategoryID = SpawnCategoryID - local SpawnGroup = GROUP:New( Group.getByName( SpawnTemplate.name ) ) + local SpawnGroup = GROUP:Register( SpawnTemplate.name ) return SpawnGroup end @@ -449,7 +344,7 @@ end -- @return #DATABASE self function DATABASE:_RegisterDatabase() - local CoalitionsData = { AlivePlayersRed = coalition.getGroups( coalition.side.RED ), AlivePlayersBlue = coalition.getGroups( coalition.side.BLUE ) } + local CoalitionsData = { GroupsRed = coalition.getGroups( coalition.side.RED ), GroupsBlue = coalition.getGroups( coalition.side.BLUE ) } for CoalitionId, CoalitionData in pairs( CoalitionsData ) do for DCSGroupId, DCSGroup in pairs( CoalitionData ) do @@ -457,43 +352,29 @@ function DATABASE:_RegisterDatabase() local DCSGroupName = DCSGroup:getName() self:E( { "Register Group:", DCSGroup, DCSGroupName } ) - self.DCSGroups[DCSGroupName] = DCSGroup - self.Groups[DCSGroupName] = GROUP:New( DCSGroup ) - - if self:_IsAliveDCSGroup(DCSGroup) then - self:E( { "Register Alive Group:", DCSGroup, DCSGroupName } ) - self.DCSGroupsAlive[DCSGroupName] = DCSGroup - self.GroupsAlive[DCSGroupName] = self.Groups[DCSGroupName] - end - + self:AddGroup( DCSGroup, DCSGroupName ) + for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do local DCSUnitName = DCSUnit:getName() self:E( { "Register Unit:", DCSUnit, DCSUnitName } ) - - self.DCSUnits[DCSUnitName] = DCSUnit - self.Units[DCSUnitName] = UNIT:New( DCSUnit ) - - if self:_IsAliveDCSUnit(DCSUnit) then - self:E( { "Register Alive Unit:", DCSUnit, DCSUnitName } ) - self.DCSUnitsAlive[DCSUnitName] = DCSUnit - self.UnitsAlive[DCSUnitName] = self.Units[DCSUnitName] - end + self:AddUnit( DCSUnit, DCSUnitName ) end else - self:E( "Group does not exist: " .. DCSGroup ) + self:E( { "Group does not exist: ", DCSGroup } ) end - for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do - self.Clients[ClientName] = CLIENT:New( ClientName ) - end end end + + for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do + self:E( { "Adding Client:", ClientName } ) + self:AddClient( ClientName ) + end return self end - --- Events --- Handles the OnBirth event for the alive units set. @@ -504,15 +385,8 @@ function DATABASE:_EventOnBirth( Event ) if Event.IniDCSUnit then if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then - self.DCSUnits[Event.IniDCSUnitName] = Event.IniDCSUnit - self.DCSUnitsAlive[Event.IniDCSUnitName] = Event.IniDCSUnit - self.Units[Event.IniDCSUnitName] = UNIT:New( Event.IniDCSUnit ) - - --if not self.DCSGroups[Event.IniDCSGroupName] then - -- self.DCSGroups[Event.IniDCSGroupName] = Event.IniDCSGroupName - -- self.DCSGroupsAlive[Event.IniDCSGroupName] = Event.IniDCSGroupName - -- self.Groups[Event.IniDCSGroupName] = GROUP:New( Event.IniDCSGroup ) - --end + self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) + self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) self:_EventOnPlayerEnterUnit( Event ) end end @@ -525,9 +399,9 @@ function DATABASE:_EventOnDeadOrCrash( Event ) self:F( { Event } ) if Event.IniDCSUnit then - if self.DCSUnitsAlive[Event.IniDCSUnitName] then - self.DCSUnits[Event.IniDCSUnitName] = nil - self.DCSUnitsAlive[Event.IniDCSUnitName] = nil + if self.DCSUnits[Event.IniDCSUnitName] then + self:DeleteUnit( Event.IniDCSUnitName ) + -- add logic to correctly remove a group once all units are destroyed... end end end @@ -543,7 +417,7 @@ function DATABASE:_EventOnPlayerEnterUnit( Event ) if not self.PlayersAlive[Event.IniDCSUnitName] then self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() - self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ] + self.ClientsAlive[Event.IniDCSUnitName] = self.CLIENTS[ Event.IniDCSUnitName ] end end end @@ -615,10 +489,10 @@ end -- @param #DATABASE self -- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter. -- @return #DATABASE self -function DATABASE:ForEachDCSUnitAlive( IteratorFunction, ... ) +function DATABASE:ForEachDCSUnit( IteratorFunction, ... ) self:F( arg ) - self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive ) + self:ForEach( IteratorFunction, arg, self.DCSUnits ) return self end @@ -643,7 +517,7 @@ end function DATABASE:ForEachClient( IteratorFunction, ... ) self:F( arg ) - self:ForEach( IteratorFunction, arg, self.Clients ) + self:ForEach( IteratorFunction, arg, self.CLIENTS ) return self end @@ -653,7 +527,7 @@ function DATABASE:ScanEnvironment() self:F() self.Navpoints = {} - self.Units = {} + self.UNITS = {} --Build routines.db.units and self.Navpoints for coa_name, coa_data in pairs(env.mission.coalition) do @@ -826,7 +700,6 @@ function DATABASE:TraceDatabase() self:F() self:T( { "DCSUnits:", self.DCSUnits } ) - self:T( { "DCSUnitsAlive:", self.DCSUnitsAlive } ) end diff --git a/Moose/Escort.lua b/Moose/Escort.lua index e45a3c876..f239d7eca 100644 --- a/Moose/Escort.lua +++ b/Moose/Escort.lua @@ -635,7 +635,7 @@ function ESCORT._HoldPosition( MenuParam ) routines.removeFunction( self.FollowScheduler ) local PointFrom = {} - local GroupPoint = EscortGroup:GetUnit(1):GetPositionVec3() + local GroupPoint = EscortGroup:GetUnit(1):GetPointVec3() PointFrom = {} PointFrom.x = GroupPoint.x PointFrom.y = GroupPoint.z @@ -977,15 +977,15 @@ function ESCORT:_FollowScheduler( FollowDistance ) local GroupUnit = self.EscortGroup:GetUnit( 1 ) if self.CT1 == 0 and self.GT1 == 0 then - self.CV1 = ClientUnit:GetPositionVec3() + self.CV1 = ClientUnit:GetPointVec3() self.CT1 = timer.getTime() - self.GV1 = GroupUnit:GetPositionVec3() + self.GV1 = GroupUnit:GetPointVec3() self.GT1 = timer.getTime() else local CT1 = self.CT1 local CT2 = timer.getTime() local CV1 = self.CV1 - local CV2 = ClientUnit:GetPositionVec3() + local CV2 = ClientUnit:GetPointVec3() self.CT1 = CT2 self.CV1 = CV2 @@ -999,7 +999,7 @@ function ESCORT:_FollowScheduler( FollowDistance ) local GT1 = self.GT1 local GT2 = timer.getTime() local GV1 = self.GV1 - local GV2 = GroupUnit:GetPositionVec3() + local GV2 = GroupUnit:GetPointVec3() self.GT1 = GT2 self.GV1 = GV2 @@ -1082,7 +1082,7 @@ function ESCORT:_ReportTargetsScheduler() self:T( EscortObject ) if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then - local EscortTargetUnit = UNIT:New( EscortObject ) + local EscortTargetUnit = UNIT:Find( EscortObject ) local EscortTargetUnitName = EscortTargetUnit:GetName() @@ -1105,8 +1105,8 @@ function ESCORT:_ReportTargetsScheduler() -- EscortTargetLastVelocity } ) - local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3() - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPointVec3() + local EscortPositionVec3 = self.EscortGroup:GetPointVec3() local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 @@ -1164,8 +1164,8 @@ function ESCORT:_ReportTargetsScheduler() EscortTargetMessage = EscortTargetMessage .. "Unknown target at " end - local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPositionVec3() - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPointVec3() + local EscortPositionVec3 = self.EscortGroup:GetPointVec3() local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 @@ -1232,7 +1232,7 @@ function ESCORT:_ReportTargetsScheduler() local TaskPoints = self:RegisterRoute() for WayPointID, WayPoint in pairs( TaskPoints ) do - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local EscortPositionVec3 = self.EscortGroup:GetPointVec3() local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 + ( WayPoint.y - EscortPositionVec3.z )^2 ) ^ 0.5 / 1000 diff --git a/Moose/Group.lua b/Moose/Group.lua index a886d75b3..86bdf5d71 100644 --- a/Moose/Group.lua +++ b/Moose/Group.lua @@ -1,6 +1,35 @@ ---- A GROUP class abstraction of a DCSGroup class. --- The GROUP class will take an abstraction of the DCSGroup class, providing more methods that can be done with a GROUP. +--- GROUP class. +-- +-- @{GROUP} class +-- ============== +-- The @{GROUP} class is a wrapper class to handle the DCS Group objects: +-- +-- * Support all DCS Group APIs. +-- * Enhance with Group specific APIs not in the DCS Group API set. +-- * Handle local Group Controller. +-- * Manage the "state" of the DCS Group. +-- +-- +-- GROUP reference methods +-- ======================= +-- For each DCS Group object alive within a running mission, a GROUP wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Group objects are spawned (using the @{SPAWN} class). +-- +-- The GROUP class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference +-- using the DCS Group or the DCS GroupName. +-- +-- Another thing to know is that GROUP objects do not "contain" the DCS Group object. +-- The GROUP methods will reference the DCS Group object by name when it is needed during API execution. +-- If the DCS Group object does not exist or is nil, the GROUP methods will return nil and log an exception in the DCS.log file. +-- +-- The GROUP class provides the following functions to retrieve quickly the relevant GROUP instance: +-- +-- * @{#GROUP.Find}(): Find a GROUP instance from the _DATABASE object using a DCS Group object. +-- * @{#GROUP.FindByName}(): Find a GROUP instance from the _DATABASE object using a DCS Group name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these GROUP OBJECT REFERENCES! (make the GROUP object references nil). -- @module Group +-- @author FlightControl Include.File( "Routines" ) Include.File( "Base" ) @@ -12,8 +41,6 @@ Include.File( "Unit" ) -- @extends Base#BASE -- @field DCSGroup#Group DCSGroup The DCS group class. -- @field #string GroupName The name of the group. --- @field #number GroupID the ID of the group. --- @field #table Controller The controller of the group. GROUP = { ClassName = "GROUP", GroupName = "", @@ -27,81 +54,310 @@ GROUP = { -- @type DCSGroup -- @field id_ The ID of the group in DCS ---- The GROUPS structure contains references to all the created GROUP instances. -local GROUPS = {} - --- Create a new GROUP from a DCSGroup -- @param #GROUP self --- @param DCSGroup#Group DCSGroup The DCS Group +-- @param DCSGroup#Group GroupName The DCS Group name -- @return #GROUP self -function GROUP:New( DCSGroup ) +function GROUP:Register( GroupName ) local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSGroup ) + self:F2( GroupName ) + self.GroupName = GroupName + return self +end - self.DCSGroup = DCSGroup - if self.DCSGroup and self.DCSGroup:isExist() then - self.GroupName = DCSGroup:getName() - self.GroupID = DCSGroup:getID() - self.Controller = DCSGroup:getController() - else - self:E( { "DCSGroup is nil or does not exist, cannot initialize GROUP!", self.DCSGroup } ) +-- Reference methods. + +--- Find the GROUP wrapper class instance using the DCS Group. +-- @param #GROUP self +-- @param DCSGroup#Group DCSGroup The DCS Group. +-- @return #GROUP The GROUP. +function GROUP:Find( DCSGroup ) + + local GroupName = DCSGroup:getName() -- Group#GROUP + local GroupFound = _DATABASE:FindGroup( GroupName ) + return GroupFound +end + +--- Find the created GROUP using the DCS Group Name. +-- @param #GROUP self +-- @param #string GroupName The DCS Group Name. +-- @return #GROUP The GROUP. +function GROUP:FindByName( GroupName ) + + local GroupFound = _DATABASE:FindGroup( GroupName ) + return GroupFound +end + +-- DCS Group methods support. + +--- Returns the DCS Group. +-- @param #GROUP self +-- @return DCSGroup#Group The DCS Group. +function GROUP:GetDCSGroup() + local DCSGroup = Group.getByName( self.GroupName ) + + if DCSGroup then + return DCSGroup + end + + return nil +end + + +--- Returns if the DCS Group is alive. +-- When the group exists at run-time, this method will return true, otherwise false. +-- @param #GROUP self +-- @return #boolean true if the DCS Group is alive. +function GROUP:IsAlive() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupIsAlive = DCSGroup:isExist() + self:T3( GroupIsAlive ) + return GroupIsAlive end - GROUPS[self.GroupID] = self - - return self + return nil end ---- Create a new GROUP from an existing group name. +--- Destroys the DCS Group and all of its DCS Units. +-- Note that this destroy method also raises a destroy event at run-time. +-- So all event listeners will catch the destroy event of this DCS Group. -- @param #GROUP self --- @param GroupName The name of the DCS Group. --- @return #GROUP self -function GROUP:NewFromName( GroupName ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( GroupName ) - - self.DCSGroup = Group.getByName( GroupName ) - if self.DCSGroup then - self.GroupName = self.DCSGroup:getName() - self.GroupID = self.DCSGroup:getID() - self.Controller = self.DCSGroup:getController() - end - - GROUPS[self.GroupID] = self - - return self +function GROUP:Destroy() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + self:CreateEventCrash( timer.getTime(), UnitData ) + end + DCSGroup:destroy() + DCSGroup = nil + end + + return nil end ---- Create a new GROUP from an existing DCSUnit in the mission. +--- Returns category of the DCS Group. -- @param #GROUP self --- @param DCSUnit The DCSUnit. --- @return #GROUP self -function GROUP:NewFromDCSUnit( DCSUnit ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSUnit ) +-- @return DCSGroup#Group.Category The category ID +function GROUP:GetCategory() + self:F2( self.GroupName ) - self.DCSGroup = DCSUnit:getGroup() - if self.DCSGroup then - self.GroupName = self.DCSGroup:getName() - self.GroupID = self.DCSGroup:getID() - self.Controller = self.DCSGroup:getController() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T3( GroupCategory ) + return GroupCategory + end + + return nil +end + +--- Returns the category name of the DCS Group. +-- @param #GROUP self +-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship +function GROUP:GetCategoryName() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local CategoryNames = { + [Group.Category.AIRPLANE] = "Airplane", + [Group.Category.HELICOPTER] = "Helicopter", + [Group.Category.GROUND] = "Ground Unit", + [Group.Category.SHIP] = "Ship", + } + local GroupCategory = DCSGroup:getCategory() + self:T3( GroupCategory ) + + return CategoryNames[GroupCategory] + end + + return nil +end + + +--- Returns the coalition of the DCS Group. +-- @param #GROUP self +-- @return DCSCoalitionObject#coalition.side The coalition side of the DCS Group. +function GROUP:GetCoalition() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local GroupCoalition = DCSGroup:getCoalition() + self:T3( GroupCoalition ) + return GroupCoalition + end + + return nil +end + +--- Returns the name of the DCS Group. +-- @param #GROUP self +-- @return #string The DCS Group name. +function GROUP:GetName() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupName = DCSGroup:getName() + self:T3( GroupName ) + return GroupName + end + + return nil +end + +--- Returns the DCS Group identifier. +-- @param #GROUP self +-- @return #number The identifier of the DCS Group. +function GROUP:GetID() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupID = DCSGroup:getID() + self:T3( GroupID ) + return GroupID + end + + return nil +end + +--- Returns the UNIT wrapper class with number UnitNumber. +-- If the underlying DCS Unit does not exist, the method will return nil. . +-- @param #GROUP self +-- @param #number UnitNumber The number of the UNIT wrapper class to be returned. +-- @return Unit#UNIT The UNIT wrapper class. +function GROUP:GetUnit( UnitNumber ) + self:F2( { self.GroupName, UnitNumber } ) + + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local UnitFound = UNIT:Find( DCSGroup:getUnit( UnitNumber ) ) + self:T3( UnitFound.UnitName ) + self:T2( UnitFound ) + return UnitFound end - GROUPS[self.GroupID] = self - - return self + return nil end ---- Returns the name of the Group. +--- Returns the DCS Unit with number UnitNumber. +-- If the underlying DCS Unit does not exist, the method will return nil. . -- @param #GROUP self --- @return #string GroupName -function GROUP:GetName() +-- @param #number UnitNumber The number of the DCS Unit to be returned. +-- @return DCSUnit#Unit The DCS Unit. +function GROUP:GetDCSUnit( UnitNumber ) + self:F2( { self.GroupName, UnitNumber } ) - local GroupName = self.DCSGroup:getName() + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local DCSUnitFound = DCSGroup:getUnit( UnitNumber ) + self:T3( DCSUnitFound ) + return DCSUnitFound + end - return GroupName + return nil end +--- Returns current size of the DCS Group. +-- If some of the DCS Units of the DCS Group are destroyed the size of the DCS Group is changed. +-- @param #GROUP self +-- @return #number The DCS Group size. +function GROUP:GetSize() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupSize = DCSGroup:getSize() + self:T3( GroupSize ) + return GroupSize + end + + return nil +end + +--- +--- Returns the initial size of the DCS Group. +-- If some of the DCS Units of the DCS Group are destroyed, the initial size of the DCS Group is unchanged. +-- @param #GROUP self +-- @return #number The DCS Group initial size. +function GROUP:GetInitialSize() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupInitialSize = DCSGroup:getInitialSize() + self:T3( GroupInitialSize ) + return GroupInitialSize + end + + return nil +end + +--- Returns the UNITs wrappers of the DCS Units of the DCS Group. +-- @param #GROUP self +-- @return #table The UNITs wrappers. +function GROUP:GetUnits() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local DCSUnits = DCSGroup:getUnits() + local Units = {} + for Index, UnitData in pairs( DCSUnits ) do + Units[#Units+1] = UNIT:Find( UnitData ) + end + self:T3( Units ) + return Units + end + + return nil +end + + +--- Returns the DCS Units of the DCS Group. +-- @param #GROUP self +-- @return #table The DCS Units. +function GROUP:GetDCSUnits() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local DCSUnits = DCSGroup:getUnits() + self:T3( DCSUnits ) + return DCSUnits + end + + return nil +end + +--- Get the controller for the GROUP. +-- @param #GROUP self +-- @return DCSController#Controller +function GROUP:_GetController() + self:F2( { self.GroupName } ) + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupController = DCSGroup:getController() + self:T3( GroupController ) + return GroupController + end + + return nil +end --- Retrieve the group mission and allow to place function hooks within the mission waypoint plan. @@ -109,7 +365,6 @@ end -- Use the method @{Group@GROUP:WayPointExecute) to start the execution of the new mission plan. -- Note that when WayPointInitialize is called, the Mission of the group is RESTARTED! -- @param #GROUP self --- @param #number WayPoint -- @return #GROUP function GROUP:WayPointInitialize() @@ -126,7 +381,7 @@ end -- @param #function WayPointFunction The waypoint function to be called when the group moves over the waypoint. The waypoint function takes variable parameters. -- @return #GROUP function GROUP:WayPointFunction( WayPoint, WayPointIndex, WayPointFunction, ... ) - self:F( { WayPoint, WayPointIndex, WayPointFunction } ) + self:F2( { WayPoint, WayPointIndex, WayPointFunction } ) table.insert( self.WayPoints[WayPoint].task.params.tasks, WayPointIndex ) self.WayPoints[WayPoint].task.params.tasks[WayPointIndex] = self:TaskFunction( WayPoint, WayPointIndex, WayPointFunction, arg ) @@ -139,7 +394,7 @@ function GROUP:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionAr local DCSTask local DCSScript = {} - DCSScript[#DCSScript+1] = "local MissionGroup = GROUP.FindGroup( ... ) " + DCSScript[#DCSScript+1] = "local MissionGroup = GROUP:Find( ... ) " if FunctionArguments.n > 0 then DCSScript[#DCSScript+1] = FunctionString .. "( MissionGroup, " .. table.concat( FunctionArguments, "," ) .. ")" @@ -153,7 +408,7 @@ function GROUP:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionAr ), WayPointIndex ) - self:T( DCSTask ) + self:T3( DCSTask ) return DCSTask @@ -179,7 +434,7 @@ function GROUP:WayPointExecute( WayPoint, WaitTime ) table.remove( self.WayPoints, 1 ) end - self:T( self.WayPoints ) + self:T3( self.WayPoints ) self:SetTask( self:TaskRoute( self.WayPoints ), WaitTime ) @@ -187,148 +442,70 @@ function GROUP:WayPointExecute( WayPoint, WaitTime ) end - ---- Gets the DCSGroup of the GROUP. --- @param #GROUP self --- @return DCSGroup#Group The DCSGroup. -function GROUP:GetDCSGroup() - self:F( { self.GroupName } ) - self.DCSGroup = Group.getByName( self.GroupName ) - return self.DCSGroup -end - ---- Gets the DCS Unit of the GROUP. --- @param #GROUP self --- @param #number UnitNumber The unit index to be returned from the GROUP. --- @return #Unit The DCS Unit. -function GROUP:GetDCSUnit( UnitNumber ) - self:F( { self.GroupName, UnitNumber } ) - return self.DCSGroup:getUnit( UnitNumber ) - -end - ---- Gets the DCSUnits of the GROUP. --- @param #GROUP self --- @return #table The DCSUnits. -function GROUP:GetDCSUnits() - self:F( { self.GroupName } ) - return self.DCSGroup:getUnits() - -end - --- Activates a GROUP. -- @param #GROUP self function GROUP:Activate() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) trigger.action.activateGroup( self:GetDCSGroup() ) return self:GetDCSGroup() end ---- Gets the ID of the GROUP. --- @param #GROUP self --- @return #number The ID of the GROUP. -function GROUP:GetID() - self:F( self.GroupName ) - - return self.GroupID -end - ---- Gets the name of the GROUP. --- @param #GROUP self --- @return #string The name of the GROUP. -function GROUP:GetName() - self:F( self.GroupName ) - - return self.GroupName -end --- Gets the type name of the group. -- @param #GROUP self -- @return #string The type name of the group. function GROUP:GetTypeName() - self:F( self.GroupName ) + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() - return self.DCSGroup:getUnit(1):getTypeName() + if DCSGroup then + local GroupTypeName = DCSGroup:getUnit(1):getTypeName() + self:T3( GroupTypeName ) + return( GroupTypeName ) + end + + return nil end ---- Gets the callsign of the fist unit of the group. +--- Gets the CallSign of the first DCS Unit of the DCS Group. -- @param #GROUP self --- @return #string The callsign of the first unit of the group. +-- @return #string The CallSign of the first DCS Unit of the DCS Group. function GROUP:GetCallsign() - self:F( self.GroupName ) + self:F2( self.GroupName ) - return self.DCSGroup:getUnit(1):getCallsign() + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local GroupCallSign = DCSGroup:getUnit(1):getCallsign() + self:T3( GroupCallSign ) + return GroupCallSign + end + + return nil end ---- Gets the current Point of the GROUP in VEC3 format. --- @return #Vec3 Current x,y and z position of the group. +--- Returns the current point (Vec2 vector) of the first DCS Unit in the DCS Group. +-- @return DCSTypes#Vec2 Current Vec2 point of the first DCS Unit of the DCS Group. function GROUP:GetPointVec2() - self:F( self.GroupName ) + self:F2( self.GroupName ) - local GroupPoint = self:GetUnit(1):GetPointVec2() - self:T( GroupPoint ) - return GroupPoint + local GroupPointVec2 = self:GetUnit(1):GetPointVec2() + self:T3( GroupPointVec2 ) + return GroupPointVec2 end ---- Gets the current Point of the GROUP in VEC2 format. --- @return #Vec2 Current x and y position of the group in the 2D plane. -function GROUP:GetPointVec2() - self:F( self.GroupName ) +--- Returns the current point (Vec3 vector) of the first DCS Unit in the DCS Group. +-- @return DCSTypes#Vec3 Current Vec3 point of the first DCS Unit of the DCS Group. +function GROUP:GetPointVec3() + self:F2( self.GroupName ) - local GroupPoint = self:GetUnit(1):GetPointVec2() - self:T( GroupPoint ) - return GroupPoint + local GroupPointVec3 = self:GetUnit(1):GetPointVec3() + self:T3( GroupPointVec3 ) + return GroupPointVec3 end ---- Gets the current Point of the GROUP in VEC3 format. --- @return #Vec3 Current Vec3 position of the group. -function GROUP:GetPositionVec3() - self:F( self.GroupName ) - - local GroupPoint = self:GetUnit(1):GetPositionVec3() - self:T( GroupPoint ) - return GroupPoint -end ---- Destroy a GROUP --- Note that this destroy method also raises a destroy event at run-time. --- So all event listeners will catch the destroy event of this GROUP. --- @param #GROUP self -function GROUP:Destroy() - self:F( self.GroupName ) - - for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - self:CreateEventCrash( timer.getTime(), UnitData ) - end - - self.DCSGroup:destroy() - self.DCSGroup = nil -end - ---- Gets the DCS Unit. --- @param #GROUP self --- @param #number UnitNumber The number of the Unit to be returned. --- @return Unit#UNIT The DCS Unit. -function GROUP:GetUnit( UnitNumber ) - self:F( { self.GroupName, UnitNumber } ) - return UNIT:New( self.DCSGroup:getUnit( UnitNumber ) ) -end - ---- Returns the category name of the group. --- @param #GROUP self --- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship -function GROUP:GetCategoryName() - self:F( self.GroupName ) - - local CategoryNames = { - [Group.Category.AIRPLANE] = "Airplane", - [Group.Category.HELICOPTER] = "Helicopter", - [Group.Category.GROUND] = "Ground Unit", - [Group.Category.SHIP] = "Ship", - } - - return CategoryNames[self.DCSGroup:getCategory()] -end -- Is Functions @@ -337,73 +514,85 @@ end -- @param #GROUP self -- @return #boolean Air category evaluation result. function GROUP:IsAir() - self:F() - - local IsAirResult = self.DCSGroup:getCategory() == Group.Category.AIRPLANE or self.DCSGroup:getCategory() == Group.Category.HELICOPTER + self:F2( self.GroupName ) - self:T( IsAirResult ) - return IsAirResult + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local IsAirResult = DCSGroup:getCategory() == Group.Category.AIRPLANE or DCSGroup:getCategory() == Group.Category.HELICOPTER + self:T3( IsAirResult ) + return IsAirResult + end + + return nil end ---- Returns if the group is alive. --- When the group exists at run-time, this method will return true, otherwise false. +--- Returns if the DCS Group contains Helicopters. -- @param #GROUP self --- @return #boolean Alive result. -function GROUP:IsAlive() - self:F() - - local IsAliveResult = self.DCSGroup and self.DCSGroup:isExist() - - self:T( IsAliveResult ) - return IsAliveResult -end - ---- Returns if the GROUP is a Helicopter. --- @param #GROUP self --- @return #boolean true if GROUP are Helicopters. +-- @return #boolean true if DCS Group contains Helicopters. function GROUP:IsHelicopter() - self:F2() + self:F2( self.GroupName ) - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.HELICOPTER + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.HELICOPTER + end + + return nil end ---- Returns if the GROUP are AirPlanes. +--- Returns if the DCS Group contains AirPlanes. -- @param #GROUP self --- @return #boolean true if GROUP are AirPlanes. +-- @return #boolean true if DCS Group contains AirPlanes. function GROUP:IsAirPlane() self:F2() - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.AIRPLANE + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.AIRPLANE + end + + return nil end ---- Returns if the GROUP are Ground troops. +--- Returns if the DCS Group contains Ground troops. -- @param #GROUP self --- @return #boolean true if GROUP are Ground troops. +-- @return #boolean true if DCS Group contains Ground troops. function GROUP:IsGround() self:F2() - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.GROUND + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.GROUND + end + + return nil end ---- Returns if the GROUP are Ships. +--- Returns if the DCS Group contains Ships. -- @param #GROUP self --- @return #boolean true if GROUP are Ships. +-- @return #boolean true if DCS Group contains Ships. function GROUP:IsShip() self:F2() - local GroupCategory = self.DCSGroup:getCategory() - self:T2( GroupCategory ) + local DCSGroup = self:GetDCSGroup() - return GroupCategory == Group.Category.SHIP + if DCSGroup then + local GroupCategory = DCSGroup:getCategory() + self:T2( GroupCategory ) + return GroupCategory == Group.Category.SHIP + end + + return nil end --- Returns if all units of the group are on the ground or landed. @@ -411,18 +600,24 @@ end -- @param #GROUP self -- @return #boolean All units on the ground result. function GROUP:AllOnGround() - self:F() + self:F2() - local AllOnGroundResult = true - - for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - if UnitData:inAir() then - AllOnGroundResult = false - end - end - - self:T( AllOnGroundResult ) - return AllOnGroundResult + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local AllOnGroundResult = true + + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + if UnitData:inAir() then + AllOnGroundResult = false + end + end + + self:T3( AllOnGroundResult ) + return AllOnGroundResult + end + + return nil end --- Returns the current maximum velocity of the group. @@ -430,21 +625,27 @@ end -- @param #GROUP self -- @return #number Maximum velocity found. function GROUP:GetMaxVelocity() - self:F() + self:F2() - local MaxVelocity = 0 - - for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - - local Velocity = UnitData:getVelocity() - local VelocityTotal = math.abs( Velocity.x ) + math.abs( Velocity.y ) + math.abs( Velocity.z ) - - if VelocityTotal < MaxVelocity then - MaxVelocity = VelocityTotal - end - end - - return MaxVelocity + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local MaxVelocity = 0 + + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + + local Velocity = UnitData:getVelocity() + local VelocityTotal = math.abs( Velocity.x ) + math.abs( Velocity.y ) + math.abs( Velocity.z ) + + if VelocityTotal < MaxVelocity then + MaxVelocity = VelocityTotal + end + end + + return MaxVelocity + end + + return nil end --- Returns the current minimum height of the group. @@ -452,7 +653,7 @@ end -- @param #GROUP self -- @return #number Minimum height found. function GROUP:GetMinHeight() - self:F() + self:F2() end @@ -461,7 +662,7 @@ end -- @param #GROUP self -- @return #number Maximum height found. function GROUP:GetMaxHeight() - self:F() + self:F2() end @@ -471,68 +672,85 @@ end -- @param #GROUP self -- @return Group#GROUP self function GROUP:PopCurrentTask() - self:F() + self:F2() - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - Controller:popTask() - - return self + if DCSGroup then + local Controller = self:_GetController() + Controller:popTask() + return self + end + + return nil end --- Pushing Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self function GROUP:PushTask( DCSTask, WaitTime ) - self:F() + self:F2() - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. - -- Therefore we schedule the functions to set the mission and options for the Group. - -- Controller:pushTask( DCSTask ) - - if not WaitTime then - Controller:pushTask( DCSTask ) - else - routines.scheduleFunction( Controller.pushTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + if DCSGroup then + local Controller = self:_GetController() + + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller:pushTask( DCSTask ) + + if WaitTime then + routines.scheduleFunction( Controller.pushTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + else + Controller:pushTask( DCSTask ) + end + + return self end - - return self + + return nil end --- Clearing the Task Queue and Setting the Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self function GROUP:SetTask( DCSTask, WaitTime ) - self:F( { DCSTask } ) + self:F2( { DCSTask } ) - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. - -- Therefore we schedule the functions to set the mission and options for the Group. - -- Controller.setTask( Controller, DCSTask ) - - if not WaitTime then - WaitTime = 1 + if DCSGroup then + + local Controller = self:_GetController() + + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller.setTask( Controller, DCSTask ) + + if not WaitTime then + WaitTime = 1 + end + routines.scheduleFunction( Controller.setTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + + return self end - routines.scheduleFunction( Controller.setTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) - return self + return nil end --- Return a condition section for a controlled task -- @param #GROUP self --- @param #Time time +-- @param DCSTime#Time time -- @param #string userFlag -- @param #boolean userFlagValue -- @param #string condition --- @param #Time duration +-- @param DCSTime#Time duration -- @param #number lastWayPoint -- return DCSTask#Task function GROUP:TaskCondition( time, userFlag, userFlagValue, condition, duration, lastWayPoint ) - self:F( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } ) + self:F2( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } ) local DCSStopCondition = {} DCSStopCondition.time = time @@ -542,7 +760,7 @@ function GROUP:TaskCondition( time, userFlag, userFlagValue, condition, duration DCSStopCondition.duration = duration DCSStopCondition.lastWayPoint = lastWayPoint - self:T( { DCSStopCondition } ) + self:T3( { DCSStopCondition } ) return DCSStopCondition end @@ -552,7 +770,7 @@ end -- @param #DCSStopCondition DCSStopCondition -- @return DCSTask#Task function GROUP:TaskControlled( DCSTask, DCSStopCondition ) - self:F( { DCSTask, DCSStopCondition } ) + self:F2( { DCSTask, DCSStopCondition } ) local DCSTaskControlled @@ -564,7 +782,7 @@ function GROUP:TaskControlled( DCSTask, DCSStopCondition ) } } - self:T( { DCSTaskControlled } ) + self:T3( { DCSTaskControlled } ) return DCSTaskControlled end @@ -573,7 +791,7 @@ end -- @param #list DCSTasks -- @return DCSTask#Task function GROUP:TaskCombo( DCSTasks ) - self:F( { DCSTasks } ) + self:F2( { DCSTasks } ) local DCSTaskCombo @@ -584,7 +802,7 @@ function GROUP:TaskCombo( DCSTasks ) } } - self:T( { DCSTaskCombo } ) + self:T3( { DCSTaskCombo } ) return DCSTaskCombo end @@ -593,7 +811,7 @@ end -- @param DCSCommand#Command DCSCommand -- @return DCSTask#Task function GROUP:TaskWrappedAction( DCSCommand, Index ) - self:F( { DCSCommand } ) + self:F2( { DCSCommand } ) local DCSTaskWrappedAction @@ -607,7 +825,7 @@ function GROUP:TaskWrappedAction( DCSCommand, Index ) }, } - self:T( { DCSTaskWrappedAction } ) + self:T3( { DCSTaskWrappedAction } ) return DCSTaskWrappedAction end @@ -616,13 +834,17 @@ end -- @param DCSCommand#Command DCSCommand -- @return #GROUP self function GROUP:SetCommand( DCSCommand ) - self:F( DCSCommand ) + self:F2( DCSCommand ) - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() - Controller:setCommand( DCSCommand ) - - return self + if DCSGroup then + local Controller = self:_GetController() + Controller:setCommand( DCSCommand ) + return self + end + + return nil end --- Perform a switch waypoint command @@ -631,7 +853,7 @@ end -- @param #number ToWayPoint -- @return DCSTask#Task function GROUP:CommandSwitchWayPoint( FromWayPoint, ToWayPoint, Index ) - self:F( { FromWayPoint, ToWayPoint, Index } ) + self:F2( { FromWayPoint, ToWayPoint, Index } ) local CommandSwitchWayPoint = { id = 'SwitchWaypoint', @@ -641,19 +863,19 @@ function GROUP:CommandSwitchWayPoint( FromWayPoint, ToWayPoint, Index ) }, } - self:T( { CommandSwitchWayPoint } ) + self:T3( { CommandSwitchWayPoint } ) return CommandSwitchWayPoint end --- Orbit at a specified position at a specified alititude during a specified duration with a specified speed. -- @param #GROUP self --- @param #Vec2 Point The point to hold the position. +-- @param DCSTypes#Vec2 Point The point to hold the position. -- @param #number Altitude The altitude to hold the position. -- @param #number Speed The speed flying when holding the position. -- @return #GROUP self function GROUP:TaskOrbitCircleAtVec2( Point, Altitude, Speed ) - self:F( { self.GroupName, Point, Altitude, Speed } ) + self:F2( { self.GroupName, Point, Altitude, Speed } ) -- pattern = enum AI.Task.OribtPattern, -- point = Vec2, @@ -663,7 +885,7 @@ function GROUP:TaskOrbitCircleAtVec2( Point, Altitude, Speed ) local LandHeight = land.getHeight( Point ) - self:T( { LandHeight } ) + self:T3( { LandHeight } ) local DCSTask = { id = 'Orbit', params = { pattern = AI.Task.OrbitPattern.CIRCLE, @@ -697,11 +919,16 @@ end -- @param #number Speed The speed flying when holding the position. -- @return #GROUP self function GROUP:TaskOrbitCircle( Altitude, Speed ) - self:F( { self.GroupName, Altitude, Speed } ) + self:F2( { self.GroupName, Altitude, Speed } ) - local GroupPoint = self:GetPointVec2() + local DCSGroup = self:GetDCSGroup() - return self:TaskOrbitCircleAtVec2( GroupPoint, Altitude, Speed ) + if DCSGroup then + local GroupPoint = self:GetPointVec2() + return self:TaskOrbitCircleAtVec2( GroupPoint, Altitude, Speed ) + end + + return nil end @@ -711,7 +938,7 @@ end -- @param #number Duration The maximum duration in seconds to hold the position. -- @return #GROUP self function GROUP:TaskHoldPosition() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) return self:TaskOrbitCircle( 30, 10 ) end @@ -719,11 +946,11 @@ end --- Land the group at a Vec2Point. -- @param #GROUP self --- @param #Vec2 Point The point where to land. +-- @param DCSTypes#Vec2 Point The point where to land. -- @param #number Duration The duration in seconds to stay on the ground. -- @return #GROUP self function GROUP:TaskLandAtVec2( Point, Duration ) - self:F( { self.GroupName, Point, Duration } ) + self:F2( { self.GroupName, Point, Duration } ) local DCSTask @@ -733,7 +960,7 @@ function GROUP:TaskLandAtVec2( Point, Duration ) DCSTask = { id = 'Land', params = { point = Point, durationFlag = false } } end - self:T( DCSTask ) + self:T3( DCSTask ) return DCSTask end @@ -743,7 +970,7 @@ end -- @param #number Duration The duration in seconds to stay on the ground. -- @return #GROUP self function GROUP:TaskLandAtZone( Zone, Duration, RandomPoint ) - self:F( { self.GroupName, Zone, Duration, RandomPoint } ) + self:F2( { self.GroupName, Zone, Duration, RandomPoint } ) local Point if RandomPoint then @@ -754,7 +981,7 @@ function GROUP:TaskLandAtZone( Zone, Duration, RandomPoint ) local DCSTask = self:TaskLandAtVec2( Point, Duration ) - self:T( DCSTask ) + self:T3( DCSTask ) return DCSTask end @@ -764,7 +991,7 @@ end -- @param Unit#UNIT The unit. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskAttackUnit( AttackUnit ) - self:F( { self.GroupName, AttackUnit } ) + self:F2( { self.GroupName, AttackUnit } ) -- AttackUnit = { -- id = 'AttackUnit', @@ -787,7 +1014,7 @@ function GROUP:TaskAttackUnit( AttackUnit ) }, }, - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -796,7 +1023,7 @@ end -- @param Group#GROUP AttackGroup The Group to be attacked. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskAttackGroup( AttackGroup ) - self:F( { self.GroupName, AttackGroup } ) + self:F2( { self.GroupName, AttackGroup } ) -- AttackGroup = { -- id = 'AttackGroup', @@ -820,7 +1047,7 @@ function GROUP:TaskAttackGroup( AttackGroup ) }, }, - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -830,7 +1057,7 @@ end -- @param DCSTypes#Distance Radius The radius of the zone to deploy the fire at. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskFireAtPoint( PointVec2, Radius ) - self:F( { self.GroupName, PointVec2, Radius } ) + self:F2( { self.GroupName, PointVec2, Radius } ) -- FireAtPoint = { -- id = 'FireAtPoint', @@ -847,7 +1074,7 @@ function GROUP:TaskFireAtPoint( PointVec2, Radius ) } } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -855,12 +1082,12 @@ end --- Move the group to a Vec2 Point, wait for a defined duration and embark a group. -- @param #GROUP self --- @param #Vec2 Point The point where to wait. +-- @param DCSTypes#Vec2 Point The point where to wait. -- @param #number Duration The duration in seconds to wait. -- @param #GROUP EmbarkingGroup The group to be embarked. -- @return DCSTask#Task The DCS task structure function GROUP:TaskEmbarkingAtVec2( Point, Duration, EmbarkingGroup ) - self:F( { self.GroupName, Point, Duration, EmbarkingGroup.DCSGroup } ) + self:F2( { self.GroupName, Point, Duration, EmbarkingGroup.DCSGroup } ) local DCSTask DCSTask = { id = 'Embarking', @@ -874,17 +1101,17 @@ function GROUP:TaskEmbarkingAtVec2( Point, Duration, EmbarkingGroup ) } } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end --- Move to a defined Vec2 Point, and embark to a group when arrived within a defined Radius. -- @param #GROUP self --- @param #Vec2 Point The point where to wait. +-- @param DCSTypes#Vec2 Point The point where to wait. -- @param #number Radius The radius of the embarking zone around the Point. -- @return DCSTask#Task The DCS task structure. function GROUP:TaskEmbarkToTransportAtVec2( Point, Radius ) - self:F( { self.GroupName, Point, Radius } ) + self:F2( { self.GroupName, Point, Radius } ) local DCSTask --DCSTask#Task DCSTask = { id = 'EmbarkToTransport', @@ -894,7 +1121,7 @@ function GROUP:TaskEmbarkToTransportAtVec2( Point, Radius ) } } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -903,12 +1130,12 @@ end -- @param #table TaskMission A table containing the mission task. -- @return DCSTask#Task function GROUP:TaskMission( TaskMission ) - self:F( Points ) + self:F2( Points ) local DCSTask DCSTask = { id = 'Mission', params = { TaskMission, }, } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end @@ -917,24 +1144,75 @@ end -- @param #table Points A table of route points. -- @return DCSTask#Task function GROUP:TaskRoute( Points ) - self:F( Points ) + self:F2( Points ) local DCSTask DCSTask = { id = 'Mission', params = { route = { points = Points, }, }, } - self:T( { DCSTask } ) + self:T3( { DCSTask } ) return DCSTask end ---- Make the group to fly to a given point and hover. +--- Make the DCS Group to fly to a given point and hover. -- @param #GROUP self --- @param #Vec3 Point The destination point. +-- @param DCSTypes#Vec3 Point The destination point in Vec3 format. +-- @param #number Speed The speed to travel. +-- @return #GROUP self +function GROUP:TaskRouteToVec2( Point, Speed ) + self:F2( { Point, Speed } ) + + local GroupPoint = self:GetUnit( 1 ):GetPointVec2() + + local PointFrom = {} + PointFrom.x = GroupPoint.x + PointFrom.y = GroupPoint.y + PointFrom.type = "Turning Point" + PointFrom.action = "Turning Point" + PointFrom.speed = Speed + PointFrom.speed_locked = true + PointFrom.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + + local PointTo = {} + PointTo.x = Point.x + PointTo.y = Point.y + PointTo.type = "Turning Point" + PointTo.action = "Fly Over Point" + PointTo.speed = Speed + PointTo.speed_locked = true + PointTo.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + self:Route( Points ) + + return self +end + +--- Make the DCS Group to fly to a given point and hover. +-- @param #GROUP self +-- @param DCSTypes#Vec3 Point The destination point in Vec3 format. -- @param #number Speed The speed to travel. -- @return #GROUP self function GROUP:TaskRouteToVec3( Point, Speed ) - self:F( { Point, Speed } ) + self:F2( { Point, Speed } ) - local GroupPoint = self:GetUnit( 1 ):GetPositionVec3() + local GroupPoint = self:GetUnit( 1 ):GetPointVec3() local PointFrom = {} PointFrom.x = GroupPoint.x @@ -974,7 +1252,7 @@ function GROUP:TaskRouteToVec3( Point, Speed ) local Points = { PointFrom, PointTo } - self:T( Points ) + self:T3( Points ) self:Route( Points ) @@ -988,16 +1266,20 @@ end -- @param #table GoPoints A table of Route Points. -- @return #GROUP self function GROUP:Route( GoPoints ) - self:F( GoPoints ) + self:F2( GoPoints ) - local Points = routines.utils.deepCopy( GoPoints ) - local MissionTask = { id = 'Mission', params = { route = { points = Points, }, }, } - - --self.Controller.setTask( self.Controller, MissionTask ) - - routines.scheduleFunction( self.Controller.setTask, { self.Controller, MissionTask}, timer.getTime() + 1 ) - - return self + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + local Points = routines.utils.deepCopy( GoPoints ) + local MissionTask = { id = 'Mission', params = { route = { points = Points, }, }, } + local Controller = self:_GetController() + --Controller.setTask( Controller, MissionTask ) + routines.scheduleFunction( Controller.setTask, { Controller, MissionTask}, timer.getTime() + 1 ) + return self + end + + return nil end @@ -1012,50 +1294,57 @@ end -- @param #number Speed The speed. -- @param Base#FORMATION Formation The formation string. function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) - self:F( Zone ) - - local GroupPoint = self:GetPointVec2() - - local PointFrom = {} - PointFrom.x = GroupPoint.x - PointFrom.y = GroupPoint.y - PointFrom.type = "Turning Point" - PointFrom.action = "Cone" - PointFrom.speed = 20 / 1.6 - + self:F2( Zone ) - local PointTo = {} - local ZonePoint - - if Randomize then - ZonePoint = Zone:GetRandomPointVec2() - else - ZonePoint = Zone:GetPointVec2() - end - - PointTo.x = ZonePoint.x - PointTo.y = ZonePoint.y - PointTo.type = "Turning Point" - - if Formation then - PointTo.action = Formation - else - PointTo.action = "Cone" - end - - if Speed then - PointTo.speed = Speed - else - PointTo.speed = 20 / 1.6 - end - - local Points = { PointFrom, PointTo } - - self:T( Points ) - - self:Route( Points ) - - return self + local DCSGroup = self:GetDCSGroup() + + if DCSGroup then + + local GroupPoint = self:GetPointVec2() + + local PointFrom = {} + PointFrom.x = GroupPoint.x + PointFrom.y = GroupPoint.y + PointFrom.type = "Turning Point" + PointFrom.action = "Cone" + PointFrom.speed = 20 / 1.6 + + + local PointTo = {} + local ZonePoint + + if Randomize then + ZonePoint = Zone:GetRandomPointVec2() + else + ZonePoint = Zone:GetPointVec2() + end + + PointTo.x = ZonePoint.x + PointTo.y = ZonePoint.y + PointTo.type = "Turning Point" + + if Formation then + PointTo.action = Formation + else + PointTo.action = "Cone" + end + + if Speed then + PointTo.speed = Speed + else + PointTo.speed = 20 / 1.6 + end + + local Points = { PointFrom, PointTo } + + self:T3( Points ) + + self:Route( Points ) + + return self + end + + return nil end -- Commands @@ -1073,7 +1362,7 @@ function GROUP:CommandDoScript( DoScript ) }, } - self:T( DCSDoScript ) + self:T3( DCSDoScript ) return DCSDoScript end @@ -1082,7 +1371,7 @@ end -- @param #GROUP self -- @return #table The MissionTemplate function GROUP:GetTaskMission() - self:F( self.GroupName ) + self:F2( self.GroupName ) return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template ) end @@ -1091,7 +1380,7 @@ end -- @param #GROUP self -- @return #table The mission route defined by points. function GROUP:GetTaskRoute() - self:F( self.GroupName ) + self:F2( self.GroupName ) return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points ) end @@ -1103,7 +1392,7 @@ end -- @param #boolean Randomize Randomization of the route, when true. -- @param #number Radius When randomization is on, the randomization is within the radius. function GROUP:CopyRoute( Begin, End, Randomize, Radius ) - self:F( { Begin, End } ) + self:F2( { Begin, End } ) local Points = {} @@ -1115,7 +1404,7 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius ) GroupName = self:GetName() end - self:T( { GroupName } ) + self:T3( { GroupName } ) local Template = _DATABASE.Templates.Groups[GroupName].Template @@ -1145,36 +1434,37 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius ) return nil end ---- Get the controller for the GROUP. --- @function _GetController --- @param #GROUP self --- @return Controller#Controller -function GROUP:_GetController() - - return self.DCSGroup:getController() - -end function GROUP:GetDetectedTargets() + self:F2( self.GroupName ) - return self:_GetController():getDetectedTargets() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + return self:_GetController():getDetectedTargets() + end + return nil end function GROUP:IsTargetDetected( DCSObject ) - - local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity - = self:_GetController().isTargetDetected( self:_GetController(), DCSObject, - Controller.Detection.VISUAL, - Controller.Detection.OPTIC, - Controller.Detection.RADAR, - Controller.Detection.IRST, - Controller.Detection.RWR, - Controller.Detection.DLINK - ) - - return TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity - + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + + local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity + = self:_GetController().isTargetDetected( self:_GetController(), DCSObject, + Controller.Detection.VISUAL, + Controller.Detection.OPTIC, + Controller.Detection.RADAR, + Controller.Detection.IRST, + Controller.Detection.RWR, + Controller.Detection.DLINK + ) + return TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity + end + + return nil end -- Options @@ -1183,137 +1473,182 @@ end -- @param #GROUP self -- @return #boolean function GROUP:OptionROEHoldFirePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() or self:IsGround() or self:IsShip() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() or self:IsGround() or self:IsShip() then + return true + end + + return false end - return false + return nil end --- Holding weapons. -- @param Group#GROUP self -- @return Group#GROUP self function GROUP:OptionROEHoldFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_HOLD ) - elseif self:IsGround() then - Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD ) - elseif self:IsShip() then - Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.WEAPON_HOLD ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_HOLD ) + elseif self:IsGround() then + Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD ) + elseif self:IsShip() then + Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.WEAPON_HOLD ) + end + + return self end - return self + return nil end --- Can the GROUP attack returning on enemy fire? -- @param #GROUP self -- @return #boolean function GROUP:OptionROEReturnFirePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() or self:IsGround() or self:IsShip() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() or self:IsGround() or self:IsShip() then + return true + end + + return false end - return false + return nil end --- Return fire. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROEReturnFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.RETURN_FIRE ) - elseif self:IsGround() then - Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.RETURN_FIRE ) - elseif self:IsShip() then - Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.RETURN_FIRE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.RETURN_FIRE ) + elseif self:IsGround() then + Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.RETURN_FIRE ) + elseif self:IsShip() then + Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.RETURN_FIRE ) + end + + return self end - - return self + + return nil end --- Can the GROUP attack designated targets? -- @param #GROUP self -- @return #boolean function GROUP:OptionROEOpenFirePossible() - self:F( { self.GroupName } ) - - if self:IsAir() or self:IsGround() or self:IsShip() then - return true + self:F2( { self.GroupName } ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() or self:IsGround() or self:IsShip() then + return true + end + + return false end - return false + return nil end --- Openfire. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROEOpenFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.OPEN_FIRE ) + elseif self:IsGround() then + Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.OPEN_FIRE ) + elseif self:IsShip() then + Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.OPEN_FIRE ) + end - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.OPEN_FIRE ) - elseif self:IsGround() then - Controller:setOption( AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.OPEN_FIRE ) - elseif self:IsShip() then - Controller:setOption( AI.Option.Naval.id.ROE, AI.Option.Naval.val.ROE.OPEN_FIRE ) + return self end - - return self + + return nil end --- Can the GROUP attack targets of opportunity? -- @param #GROUP self -- @return #boolean function GROUP:OptionROEWeaponFreePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end --- Weapon free. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROEWeaponFree() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_FREE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_FREE ) + end + + return self end - return self + return nil end --- Can the GROUP ignore enemy fire? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTNoReactionPossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end @@ -1321,56 +1656,76 @@ end -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTNoReaction() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.NO_REACTION ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.NO_REACTION ) + end + + return self end - return self + return nil end --- Can the GROUP evade using passive defenses? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTPassiveDefensePossible() - self:F( { self.GroupName } ) - - if self:IsAir() then - return true + self:F2( { self.GroupName } ) + + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end --- Evasion passive defense. -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTPassiveDefense() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.PASSIVE_DEFENCE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.PASSIVE_DEFENCE ) + end + + return self end - return self + return nil end --- Can the GROUP evade on enemy fire? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTEvadeFirePossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end @@ -1378,28 +1733,38 @@ end -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTEvadeFire() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE ) + end + + return self end - return self + return nil end --- Can the GROUP evade on fire using vertical manoeuvres? -- @param #GROUP self -- @return #boolean function GROUP:OptionROTVerticalPossible() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - if self:IsAir() then - return true + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + if self:IsAir() then + return true + end + + return false end - return false + return nil end @@ -1407,15 +1772,20 @@ end -- @param #GROUP self -- @return #GROUP self function GROUP:OptionROTVertical() - self:F( { self.GroupName } ) + self:F2( { self.GroupName } ) - local Controller = self:_GetController() - - if self:IsAir() then - Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.BYPASS_AND_ESCAPE ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + local Controller = self:_GetController() + + if self:IsAir() then + Controller:setOption( AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.BYPASS_AND_ESCAPE ) + end + + return self end - return self + return nil end -- Message APIs @@ -1426,9 +1796,14 @@ end -- @param #Duration Duration The duration of the message. -- @return Message#MESSAGE function GROUP:Message( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - return MESSAGE:New( Message, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + return MESSAGE:New( Message, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) + end + + return nil end --- Send a message to all coalitions. @@ -1437,9 +1812,14 @@ end -- @param #string Message The message text -- @param #Duration Duration The duration of the message. function GROUP:MessageToAll( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToAll() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToAll() + end + + return nil end --- Send a message to the red coalition. @@ -1448,9 +1828,14 @@ end -- @param #string Message The message text -- @param #Duration Duration The duration of the message. function GROUP:MessageToRed( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToRed() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToRed() + end + + return nil end --- Send a message to the blue coalition. @@ -1459,9 +1844,14 @@ end -- @param #string Message The message text -- @param #Duration Duration The duration of the message. function GROUP:MessageToBlue( Message, Duration ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToBlue() + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToBlue() + end + + return nil end --- Send a message to a client. @@ -1471,24 +1861,12 @@ end -- @param #Duration Duration The duration of the message. -- @param Client#CLIENT Client The client object receiving the message. function GROUP:MessageToClient( Message, Duration, Client ) - self:F( { Message, Duration } ) + self:F2( { Message, Duration } ) - self:Message( Message, Duration ):ToClient( Client ) + local DCSGroup = self:GetDCSGroup() + if DCSGroup then + self:Message( Message, Duration ):ToClient( Client ) + end + + return nil end - - - - ---- Find the created GROUP using the DCSGroup ID. If a GROUP was created with the DCSGroupID, the the GROUP instance will be returned. --- Otherwise nil will be returned. --- @param DCSGroup#Group Group --- @return #GROUP -function GROUP.FindGroup( DCSGroup ) - - local self = GROUPS[DCSGroup:getID()] -- Group#GROUP - self:T( self:GetClassNameAndID() ) - return self - -end - - diff --git a/Moose/MissileTrainer.lua b/Moose/MissileTrainer.lua index 71abfabd5..d7773c502 100644 --- a/Moose/MissileTrainer.lua +++ b/Moose/MissileTrainer.lua @@ -452,8 +452,8 @@ function MISSILETRAINER:_EventShot( Event ) local Client = self.DBClients[TrainerTargetDCSUnitName] if Client then - local TrainerSourceUnit = UNIT:New(TrainerSourceDCSUnit) - local TrainerTargetUnit = UNIT:New(TrainerTargetDCSUnit) + local TrainerSourceUnit = UNIT:Find( TrainerSourceDCSUnit ) + local TrainerTargetUnit = UNIT:Find( TrainerTargetDCSUnit ) if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then @@ -489,7 +489,7 @@ function MISSILETRAINER:_AddRange( Client, TrainerWeapon ) if self.DetailsRangeOnOff then local PositionMissile = TrainerWeapon:getPoint() - local PositionTarget = Client:GetPositionVec3() + local PositionTarget = Client:GetPointVec3() local Range = ( ( PositionMissile.x - PositionTarget.x )^2 + ( PositionMissile.y - PositionTarget.y )^2 + @@ -509,7 +509,7 @@ function MISSILETRAINER:_AddBearing( Client, TrainerWeapon ) if self.DetailsBearingOnOff then local PositionMissile = TrainerWeapon:getPoint() - local PositionTarget = Client:GetPositionVec3() + local PositionTarget = Client:GetPointVec3() self:T2( { PositionTarget, PositionMissile }) @@ -557,7 +557,7 @@ function MISSILETRAINER:_TrackMissiles() if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then local PositionMissile = TrainerWeapon:getPosition().p - local PositionTarget = Client:GetPositionVec3() + local PositionTarget = Client:GetPointVec3() local Distance = ( ( PositionMissile.x - PositionTarget.x )^2 + ( PositionMissile.y - PositionTarget.y )^2 + diff --git a/Moose/Mission.lua b/Moose/Mission.lua index 65e4222f4..7d6959bea 100644 --- a/Moose/Mission.lua +++ b/Moose/Mission.lua @@ -231,25 +231,6 @@ function MISSION:AddGoalFunction( GoalFunction ) self.GoalFunction = GoalFunction end ---- Show the briefing of the MISSION to the CLIENT. --- @param CLIENT Client to show briefing to. --- @return CLIENT -function MISSION:ShowBriefing( Client ) - self:F( { Client.ClientName } ) - - if not Client.ClientBriefingShown then - Client.ClientBriefingShown = true - local Briefing = self.MissionBriefing - if Client.ClientBriefing then - Briefing = Briefing .. "\n" .. Client.ClientBriefing - end - Briefing = Briefing .. "\n (Press [LEFT ALT]+[B] to view the graphical documentation.)" - Client:Message( Briefing, 30, self.Name .. '/MissionBriefing', "Command: Mission Briefing" ) - end - - return Client -end - --- Register a new @{CLIENT} to participate within the mission. -- @param CLIENT Client is the @{CLIENT} object. The object must have been instantiated with @{CLIENT:New}. -- @return CLIENT diff --git a/Moose/Set.lua b/Moose/Set.lua new file mode 100644 index 000000000..063ec2fe0 --- /dev/null +++ b/Moose/Set.lua @@ -0,0 +1,758 @@ +--- Manage sets of units and groups. +-- +-- @{#Set} class +-- ================== +-- Mission designers can use the SET class to build sets of units belonging to certain: +-- +-- * Coalitions +-- * Categories +-- * Countries +-- * Unit types +-- * Starting with certain prefix strings. +-- +-- This list will grow over time. Planned developments are to include filters and iterators. +-- Additional filters will be added around @{Zone#ZONEs}, Radiuses, Active players, ... +-- More iterators will be implemented in the near future ... +-- +-- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor. +-- +-- SET construction methods: +-- ================================= +-- Create a new SET object with the @{#SET.New} method: +-- +-- * @{#SET.New}: Creates a new SET object. +-- +-- +-- SET filter criteria: +-- ========================= +-- You can set filter criteria to define the set of units within the SET. +-- Filter criteria are defined by: +-- +-- * @{#SET.FilterCoalitions}: Builds the SET with the units belonging to the coalition(s). +-- * @{#SET.FilterCategories}: Builds the SET with the units belonging to the category(ies). +-- * @{#SET.FilterTypes}: Builds the SET with the units belonging to the unit type(s). +-- * @{#SET.FilterCountries}: Builds the SET with the units belonging to the country(ies). +-- * @{#SET.FilterUnitPrefixes}: Builds the SET with the units starting with the same prefix string(s). +-- +-- Once the filter criteria have been set for the SET, you can start filtering using: +-- +-- * @{#SET.FilterStart}: Starts the filtering of the units within the SET. +-- +-- Planned filter criteria within development are (so these are not yet available): +-- +-- * @{#SET.FilterGroupPrefixes}: Builds the SET with the groups of the units starting with the same prefix string(s). +-- * @{#SET.FilterZones}: Builds the SET with the units within a @{Zone#ZONE}. +-- +-- +-- SET iterators: +-- =================== +-- Once the filters have been defined and the SET has been built, you can iterate the SET with the available iterator methods. +-- The iterator methods will walk the SET set, and call for each element within the set a function that you provide. +-- The following iterator methods are currently available within the SET: +-- +-- * @{#SET.ForEachAliveUnit}: Calls a function for each alive unit it finds within the SET. +-- +-- Planned iterators methods in development are (so these are not yet available): +-- +-- * @{#SET.ForEachUnit}: Calls a function for each unit contained within the SET. +-- * @{#SET.ForEachGroup}: Calls a function for each group contained within the SET. +-- * @{#SET.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the SET. +-- +-- ==== +-- @module Set +-- @author FlightControl + +Include.File( "Routines" ) +Include.File( "Base" ) +Include.File( "Menu" ) +Include.File( "Group" ) +Include.File( "Unit" ) +Include.File( "Event" ) +Include.File( "Client" ) + +--- SET class +-- @type SET +-- @extends Base#BASE +SET = { + ClassName = "SET", + Templates = { + Units = {}, + Groups = {}, + ClientsByName = {}, + ClientsByID = {}, + }, + DCSUnits = {}, + DCSUnitsAlive = {}, + DCSGroups = {}, + DCSGroupsAlive = {}, + Units = {}, + UnitsAlive = {}, + Groups = {}, + GroupsAlive = {}, + NavPoints = {}, + Statics = {}, + Players = {}, + PlayersAlive = {}, + Clients = {}, + ClientsAlive = {}, + Filter = { + Coalitions = nil, + Categories = nil, + Types = nil, + Countries = nil, + UnitPrefixes = nil, + GroupPrefixes = nil, + }, + FilterMeta = { + Coalitions = { + red = coalition.side.RED, + blue = coalition.side.BLUE, + neutral = coalition.side.NEUTRAL, + }, + Categories = { + plane = Unit.Category.AIRPLANE, + helicopter = Unit.Category.HELICOPTER, + ground = Unit.Category.GROUND_UNIT, + ship = Unit.Category.SHIP, + structure = Unit.Category.STRUCTURE, + }, + }, +} + +local _DATABASECoalition = + { + [1] = "Red", + [2] = "Blue", + } + +local _DATABASECategory = + { + [Unit.Category.AIRPLANE] = "Plane", + [Unit.Category.HELICOPTER] = "Helicopter", + [Unit.Category.GROUND_UNIT] = "Vehicle", + [Unit.Category.SHIP] = "Ship", + [Unit.Category.STRUCTURE] = "Structure", + } + + +--- Creates a new SET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names. +-- @param #SET self +-- @return #SET +-- @usage +-- -- Define a new SET Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE. +-- DBObject = SET:New() +function SET:New() + + -- Inherits from BASE + local self = BASE:Inherit( self, BASE:New() ) + + _EVENTDISPATCHER:OnBirth( self._EventOnBirth, self ) + _EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self ) + _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) + + + -- Add SET with registered clients and already alive players + + -- Follow alive players and clients + _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) + _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) + + + return self +end + +--- Finds a Unit based on the Unit Name. +-- @param #SET self +-- @param #string UnitName +-- @return Unit#UNIT The found Unit. +function SET:FindUnit( UnitName ) + + local UnitFound = self.Units[UnitName] + return UnitFound +end + +--- Finds a Unit based on the Unit Name. +-- @param #SET self +-- @param Unit#UNIT UnitToAdd +-- @return Unit#UNIT The added Unit. +function SET:AddUnit( UnitToAdd ) + + self.Units[UnitToAdd.UnitName] = UnitToAdd + return self.Units[UnitToAdd.UnitName] +end + + + +--- Builds a set of units of coalitons. +-- Possible current coalitions are red, blue and neutral. +-- @param #SET self +-- @param #string Coalitions Can take the following values: "red", "blue", "neutral". +-- @return #SET self +function SET:FilterCoalitions( Coalitions ) + if not self.Filter.Coalitions then + self.Filter.Coalitions = {} + end + if type( Coalitions ) ~= "table" then + Coalitions = { Coalitions } + end + for CoalitionID, Coalition in pairs( Coalitions ) do + self.Filter.Coalitions[Coalition] = Coalition + end + return self +end + +--- Builds a set of units out of categories. +-- Possible current categories are plane, helicopter, ground, ship. +-- @param #SET self +-- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship". +-- @return #SET self +function SET:FilterCategories( Categories ) + if not self.Filter.Categories then + self.Filter.Categories = {} + end + if type( Categories ) ~= "table" then + Categories = { Categories } + end + for CategoryID, Category in pairs( Categories ) do + self.Filter.Categories[Category] = Category + end + return self +end + +--- Builds a set of units of defined unit types. +-- Possible current types are those types known within DCS world. +-- @param #SET self +-- @param #string Types Can take those type strings known within DCS world. +-- @return #SET self +function SET:FilterTypes( Types ) + if not self.Filter.Types then + self.Filter.Types = {} + end + if type( Types ) ~= "table" then + Types = { Types } + end + for TypeID, Type in pairs( Types ) do + self.Filter.Types[Type] = Type + end + return self +end + +--- Builds a set of units of defined countries. +-- Possible current countries are those known within DCS world. +-- @param #SET self +-- @param #string Countries Can take those country strings known within DCS world. +-- @return #SET self +function SET:FilterCountries( Countries ) + if not self.Filter.Countries then + self.Filter.Countries = {} + end + if type( Countries ) ~= "table" then + Countries = { Countries } + end + for CountryID, Country in pairs( Countries ) do + self.Filter.Countries[Country] = Country + end + return self +end + +--- Builds a set of units of defined unit prefixes. +-- All the units starting with the given prefixes will be included within the set. +-- @param #SET self +-- @param #string Prefixes The prefix of which the unit name starts with. +-- @return #SET self +function SET:FilterUnitPrefixes( Prefixes ) + if not self.Filter.UnitPrefixes then + self.Filter.UnitPrefixes = {} + end + if type( Prefixes ) ~= "table" then + Prefixes = { Prefixes } + end + for PrefixID, Prefix in pairs( Prefixes ) do + self.Filter.UnitPrefixes[Prefix] = Prefix + end + return self +end + +--- Builds a set of units of defined group prefixes. +-- All the units starting with the given group prefixes will be included within the set. +-- @param #SET self +-- @param #string Prefixes The prefix of which the group name where the unit belongs to starts with. +-- @return #SET self +function SET:FilterGroupPrefixes( Prefixes ) + if not self.Filter.GroupPrefixes then + self.Filter.GroupPrefixes = {} + end + if type( Prefixes ) ~= "table" then + Prefixes = { Prefixes } + end + for PrefixID, Prefix in pairs( Prefixes ) do + self.Filter.GroupPrefixes[Prefix] = Prefix + end + return self +end + +--- Starts the filtering. +-- @param #SET self +-- @return #SET self +function SET:FilterStart() + + if _DATABASE then + -- OK, we have a _DATABASE + -- Now use the different filters to build the set. + -- We first take ALL of the Units of the _DATABASE. + + self:E( { "Adding Set Datapoints with filters" } ) + for DCSUnitName, DCSUnit in pairs( _DATABASE.DCSUnits ) do + + if self:_IsIncludeDCSUnit( DCSUnit ) then + + self:E( { "Adding Unit:", DCSUnitName } ) + self.DCSUnits[DCSUnitName] = _DATABASE.DCSUnits[DCSUnitName] + self.Units[DCSUnitName] = _DATABASE:FindUnit( DCSUnitName ) + + if _DATABASE.DCSUnitsAlive[DCSUnitName] then + self.DCSUnitsAlive[DCSUnitName] = _DATABASE.DCSUnitsAlive[DCSUnitName] + self.UnitsAlive[DCSUnitName] = _DATABASE.UnitsAlive[DCSUnitName] + end + + end + end + + for DCSGroupName, DCSGroup in pairs( _DATABASE.DCSGroups ) do + + --if self:_IsIncludeDCSGroup( DCSGroup ) then + self:E( { "Adding Group:", DCSGroupName } ) + self.DCSGroups[DCSGroupName] = _DATABASE.DCSGroups[DCSGroupName] + self.Groups[DCSGroupName] = _DATABASE:FindGroups( DCSGroupName ) + --end + + if _DATABASE.DCSGroupsAlive[DCSGroupName] then + self.DCSGroupsAlive[DCSGroupName] = _DATABASE.DCSGroupsAlive[DCSGroupName] + self.GroupsAlive[DCSGroupName] = _DATABASE.GroupsAlive[DCSGroupName] + end + end + + for DCSUnitName, Client in pairs( _DATABASE.CLIENTS ) do + self:E( { "Adding Client for Unit:", DCSUnitName } ) + self.Clients[DCSUnitName] = _DATABASE.Clients[DCSUnitName] + end + + else + self:E( "There is a structural error in MOOSE. No _DATABASE has been defined! Cannot build this custom SET." ) + end + + return self +end + + + +--- Private method that registers all alive players in the mission. +-- @param #SET self +-- @return #SET self +function SET:_RegisterPlayers() + + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for UnitId, UnitData in pairs( CoalitionData ) do + self:T3( { "UnitData:", UnitData } ) + if UnitData and UnitData:isExist() then + local UnitName = UnitData:getName() + if not self.PlayersAlive[UnitName] then + self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) + self.PlayersAlive[UnitName] = UnitData:getPlayerName() + end + end + end + end + + return self +end + +--- Private method that registers all datapoints within in the mission. +-- @param #SET self +-- @return #SET self +function SET:_RegisterDatabase() + + local CoalitionsData = { AlivePlayersRed = coalition.getGroups( coalition.side.RED ), AlivePlayersBlue = coalition.getGroups( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for DCSGroupId, DCSGroup in pairs( CoalitionData ) do + + if DCSGroup:isExist() then + local DCSGroupName = DCSGroup:getName() + + self:E( { "Register Group:", DCSGroup, DCSGroupName } ) + self.DCSGroups[DCSGroupName] = DCSGroup + self.Groups[DCSGroupName] = GROUP:New( DCSGroup ) + + if self:_IsAliveDCSGroup(DCSGroup) then + self:E( { "Register Alive Group:", DCSGroup, DCSGroupName } ) + self.DCSGroupsAlive[DCSGroupName] = DCSGroup + self.GroupsAlive[DCSGroupName] = self.Groups[DCSGroupName] + end + + for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do + + local DCSUnitName = DCSUnit:getName() + self:E( { "Register Unit:", DCSUnit, DCSUnitName } ) + + self.DCSUnits[DCSUnitName] = DCSUnit + self:AddUnit( UNIT:Find( DCSUnit ) ) + --self.Units[DCSUnitName] = UNIT:Register( DCSUnit ) + + if self:_IsAliveDCSUnit(DCSUnit) then + self:E( { "Register Alive Unit:", DCSUnit, DCSUnitName } ) + self.DCSUnitsAlive[DCSUnitName] = DCSUnit + self.UnitsAlive[DCSUnitName] = self.Units[DCSUnitName] + end + end + else + self:E( "Group does not exist: " .. DCSGroup ) + end + + for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do + self.Clients[ClientName] = CLIENT:Find( ClientName ) + end + end + end + + return self +end + + +--- Events + +--- Handles the OnBirth event for the alive units set. +-- @param #SET self +-- @param Event#EVENTDATA Event +function SET:_EventOnBirth( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then + self.DCSUnits[Event.IniDCSUnitName] = Event.IniDCSUnit + self.DCSUnitsAlive[Event.IniDCSUnitName] = Event.IniDCSUnit + self:AddUnit( UNIT:Register( Event.IniDCSUnit ) ) + --self.Units[Event.IniDCSUnitName] = UNIT:Register( Event.IniDCSUnit ) + + --if not self.DCSGroups[Event.IniDCSGroupName] then + -- self.DCSGroups[Event.IniDCSGroupName] = Event.IniDCSGroupName + -- self.DCSGroupsAlive[Event.IniDCSGroupName] = Event.IniDCSGroupName + -- self.Groups[Event.IniDCSGroupName] = GROUP:New( Event.IniDCSGroup ) + --end + self:_EventOnPlayerEnterUnit( Event ) + end + end +end + +--- Handles the OnDead or OnCrash event for alive units set. +-- @param #SET self +-- @param Event#EVENTDATA Event +function SET:_EventOnDeadOrCrash( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self.DCSUnitsAlive[Event.IniDCSUnitName] then + self.DCSUnits[Event.IniDCSUnitName] = nil + self.DCSUnitsAlive[Event.IniDCSUnitName] = nil + end + end +end + +--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). +-- @param #SET self +-- @param Event#EVENTDATA Event +function SET:_EventOnPlayerEnterUnit( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then + if not self.PlayersAlive[Event.IniDCSUnitName] then + self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) + self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() + self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ] + end + end + end +end + +--- Handles the OnPlayerLeaveUnit event to clean the active players table. +-- @param #SET self +-- @param Event#EVENTDATA Event +function SET:_EventOnPlayerLeaveUnit( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then + if self.PlayersAlive[Event.IniDCSUnitName] then + self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) + self.PlayersAlive[Event.IniDCSUnitName] = nil + self.ClientsAlive[Event.IniDCSUnitName] = nil + end + end + end +end + +--- Iterators + +--- Interate the SET and call an interator function for the given set, providing the Object for each element within the set and optional parameters. +-- @param #SET self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. +-- @return #SET self +function SET:ForEach( IteratorFunction, arg, Set ) + self:F( arg ) + + local function CoRoutine() + local Count = 0 + for ObjectID, Object in pairs( Set ) do + self:T2( Object ) + IteratorFunction( Object, unpack( arg ) ) + Count = Count + 1 + if Count % 10 == 0 then + coroutine.yield( false ) + end + end + return true + end + + local co = coroutine.create( CoRoutine ) + + local function Schedule() + + local status, res = coroutine.resume( co ) + self:T( { status, res } ) + + if status == false then + error( res ) + end + if res == false then + return true -- resume next time the loop + end + + return false + end + + local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 ) + + return self +end + + +--- Interate the SET and call an interator function for each **alive** unit, providing the Unit and optional parameters. +-- @param #SET self +-- @param #function IteratorFunction The function that will be called when there is an alive unit in the SET. The function needs to accept a UNIT parameter. +-- @return #SET self +function SET:ForEachDCSUnitAlive( IteratorFunction, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive ) + + return self +end + +--- Interate the SET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +-- @param #SET self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a UNIT parameter. +-- @return #SET self +function SET:ForEachPlayer( IteratorFunction, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.PlayersAlive ) + + return self +end + + +--- Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters. +-- @param #SET self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a CLIENT parameter. +-- @return #SET self +function SET:ForEachClient( IteratorFunction, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.Clients ) + + return self +end + + +function SET:ScanEnvironment() + self:F() + + self.Navpoints = {} + self.Units = {} + --Build routines.db.units and self.Navpoints + for coa_name, coa_data in pairs(env.mission.coalition) do + + if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then + --self.Units[coa_name] = {} + + ---------------------------------------------- + -- build nav points DB + self.Navpoints[coa_name] = {} + if coa_data.nav_points then --navpoints + for nav_ind, nav_data in pairs(coa_data.nav_points) do + + if type(nav_data) == 'table' then + self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data) + + self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory. + self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it. + self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x + self.Navpoints[coa_name][nav_ind]['point']['y'] = 0 + self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y + end + end + end + ------------------------------------------------- + if coa_data.country then --there is a country table + for cntry_id, cntry_data in pairs(coa_data.country) do + + local countryName = string.lower(cntry_data.name) + --self.Units[coa_name][countryName] = {} + --self.Units[coa_name][countryName]["countryId"] = cntry_data.id + + if type(cntry_data) == 'table' then --just making sure + + for obj_type_name, obj_type_data in pairs(cntry_data) do + + if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check + + local category = obj_type_name + + if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group! + + --self.Units[coa_name][countryName][category] = {} + + for group_num, GroupTemplate in pairs(obj_type_data.group) do + + if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group + self:_RegisterGroup( GroupTemplate ) + end --if GroupTemplate and GroupTemplate.units then + end --for group_num, GroupTemplate in pairs(obj_type_data.group) do + end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then + end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then + end --for obj_type_name, obj_type_data in pairs(cntry_data) do + end --if type(cntry_data) == 'table' then + end --for cntry_id, cntry_data in pairs(coa_data.country) do + end --if coa_data.country then --there is a country table + end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then + end --for coa_name, coa_data in pairs(mission.coalition) do + + self:_RegisterDatabase() + self:_RegisterPlayers() + + return self +end + + +--- +-- @param #SET self +-- @param DCSUnit#Unit DCSUnit +-- @return #SET self +function SET:_IsIncludeDCSUnit( DCSUnit ) + self:F( DCSUnit ) + local DCSUnitInclude = true + + if self.Filter.Coalitions then + local DCSUnitCoalition = false + for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do + self:T( { "Coalition:", DCSUnit:getCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } ) + if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == DCSUnit:getCoalition() then + DCSUnitCoalition = true + end + end + DCSUnitInclude = DCSUnitInclude and DCSUnitCoalition + end + + if self.Filter.Categories then + local DCSUnitCategory = false + for CategoryID, CategoryName in pairs( self.Filter.Categories ) do + self:T( { "Category:", DCSUnit:getDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } ) + if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == DCSUnit:getDesc().category then + DCSUnitCategory = true + end + end + DCSUnitInclude = DCSUnitInclude and DCSUnitCategory + end + + if self.Filter.Types then + local DCSUnitType = false + for TypeID, TypeName in pairs( self.Filter.Types ) do + self:T( { "Type:", DCSUnit:getTypeName(), TypeName } ) + if TypeName == DCSUnit:getTypeName() then + DCSUnitType = true + end + end + DCSUnitInclude = DCSUnitInclude and DCSUnitType + end + + if self.Filter.Countries then + local DCSUnitCountry = false + for CountryID, CountryName in pairs( self.Filter.Countries ) do + self:T( { "Country:", DCSUnit:getCountry(), CountryName } ) + if country.id[CountryName] == DCSUnit:getCountry() then + DCSUnitCountry = true + end + end + DCSUnitInclude = DCSUnitInclude and DCSUnitCountry + end + + if self.Filter.UnitPrefixes then + local DCSUnitPrefix = false + for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do + self:T( { "Unit Prefix:", string.find( DCSUnit:getName(), UnitPrefix, 1 ), UnitPrefix } ) + if string.find( DCSUnit:getName(), UnitPrefix, 1 ) then + DCSUnitPrefix = true + end + end + DCSUnitInclude = DCSUnitInclude and DCSUnitPrefix + end + + self:T( DCSUnitInclude ) + return DCSUnitInclude +end + +--- +-- @param #SET self +-- @param DCSUnit#Unit DCSUnit +-- @return #SET self +function SET:_IsAliveDCSUnit( DCSUnit ) + self:F( DCSUnit ) + local DCSUnitAlive = false + if DCSUnit and DCSUnit:isExist() and DCSUnit:isActive() then + if self.DCSUnits[DCSUnit:getName()] then + DCSUnitAlive = true + end + end + self:T( DCSUnitAlive ) + return DCSUnitAlive +end + +--- +-- @param #SET self +-- @param DCSGroup#Group DCSGroup +-- @return #SET self +function SET:_IsAliveDCSGroup( DCSGroup ) + self:F( DCSGroup ) + local DCSGroupAlive = false + if DCSGroup and DCSGroup:isExist() then + if self.DCSGroups[DCSGroup:getName()] then + DCSGroupAlive = true + end + end + self:T( DCSGroupAlive ) + return DCSGroupAlive +end + + +--- Traces the current SET contents in the log ... (for debug reasons). +-- @param #SET self +-- @return #SET self +function SET:TraceDatabase() + self:F() + + self:T( { "DCSUnits:", self.DCSUnits } ) + self:T( { "DCSUnitsAlive:", self.DCSUnitsAlive } ) +end + + diff --git a/Moose/Stage.lua b/Moose/Stage.lua index 893a3b08d..5dae9ae6a 100644 --- a/Moose/Stage.lua +++ b/Moose/Stage.lua @@ -69,7 +69,7 @@ end function STAGEBRIEF:Execute( Mission, Client, Task ) local Valid = BASE:Inherited(self):Execute( Mission, Client, Task ) self:F() - Mission:ShowBriefing( Client ) + Client:ShowBriefing() self.StageBriefingTime = timer.getTime() return Valid end diff --git a/Moose/Unit.lua b/Moose/Unit.lua index fcd99cdd4..5df82eeec 100644 --- a/Moose/Unit.lua +++ b/Moose/Unit.lua @@ -1,5 +1,77 @@ ---- UNIT Classes +--- UNIT Class +-- +-- @{UNIT} class +-- ============== +-- The @{UNIT} class is a wrapper class to handle the DCS Unit objects: +-- +-- * Support all DCS Unit APIs. +-- * Enhance with Unit specific APIs not in the DCS Unit API set. +-- * Handle local Unit Controller. +-- * Manage the "state" of the DCS Unit. +-- +-- +-- UNIT reference methods +-- ====================== +-- For each DCS Unit object alive within a running mission, a UNIT wrapper object (instance) will be created within the _@{DATABASE} object. +-- This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Unit objects are spawned (using the @{SPAWN} class). +-- +-- The UNIT class **does not contain a :New()** method, rather it provides **:Find()** methods to retrieve the object reference +-- using the DCS Unit or the DCS UnitName. +-- +-- Another thing to know is that UNIT objects do not "contain" the DCS Unit object. +-- The UNIT methods will reference the DCS Unit object by name when it is needed during API execution. +-- If the DCS Unit object does not exist or is nil, the UNIT methods will return nil and log an exception in the DCS.log file. +-- +-- The UNIT class provides the following functions to retrieve quickly the relevant UNIT instance: +-- +-- * @{#UNIT.Find}(): Find a UNIT instance from the _DATABASE object using a DCS Unit object. +-- * @{#UNIT.FindByName}(): Find a UNIT instance from the _DATABASE object using a DCS Unit name. +-- +-- IMPORTANT: ONE SHOULD NEVER SANATIZE these UNIT OBJECT REFERENCES! (make the UNIT object references nil). +-- +-- DCS UNIT APIs +-- ============= +-- The DCS Unit APIs are used extensively within MOOSE. The UNIT class has for each DCS Unit API a corresponding method. +-- To be able to distinguish easily in your code the difference between a UNIT API call and a DCS Unit API call, +-- the first letter of the method is also capitalized. So, by example, the DCS Unit method @{DCSUnit#Unit.getName}() +-- is implemented in the UNIT class as @{#UNIT.GetName}(). +-- +-- Additional UNIT APIs +-- ==================== +-- The UNIT class comes with additional methods. Find below a summary. +-- +-- Smoke, Flare Units +-- ------------------ +-- The UNIT class provides methods to smoke or flare units easily. +-- The @{#UNIT.SmokeBlue}(), @{#UNIT.SmokeGreen}(),@{#UNIT.SmokeOrange}(), @{#UNIT.SmokeRed}(), @{#UNIT.SmokeRed}() methods +-- will smoke the unit in the corresponding color. Note that smoking a unit is done at the current position of the DCS Unit. +-- When the DCS Unit moves for whatever reason, the smoking will still continue! +-- The @{#UNIT.FlareGreen}(), @{#UNIT.FlareRed}(), @{#UNIT.FlareWhite}(), @{#UNIT.FlareYellow}() +-- methods will fire off a flare in the air with the corresponding color. Note that a flare is a one-off shot and its effect is of very short duration. +-- +-- Position, Point +-- --------------- +-- The UNIT class provides methods to obtain the current point or position of the DCS Unit. +-- The @{#UNIT.GetPointVec2}(), @{#UNIT.GetPointVec3}() will obtain the current location of the DCS Unit in a Vec2 (2D) or a Vec3 (3D) vector respectively. +-- If you want to obtain the complete 3D position including oriëntation and direction vectors, consult the @{#UNIT.GetPositionVec3}() method respectively. +-- +-- Alive +-- ----- +-- The @{#UNIT.IsAlive}(), @{#UNIT.IsActive}() methods determines if the DCS Unit is alive, meaning, it is existing and active. +-- +-- Test for other units in radius +-- ------------------------------ +-- One can test if another DCS Unit is within a given radius of the current DCS Unit, by using the @{#UNIT.OtherUnitInRadius}() method. +-- +-- More functions will be added +-- ---------------------------- +-- During the MOOSE development, more functions will be added. A complete list of the current functions is below. +-- +-- +-- +-- -- @module Unit +-- @author FlightControl Include.File( "Routines" ) Include.File( "Base" ) @@ -7,7 +79,7 @@ Include.File( "Message" ) --- The UNIT class -- @type UNIT --- @Extends Base#BASE +-- @extends Base#BASE -- @field #UNIT.FlareColor FlareColor -- @field #UNIT.SmokeColor SmokeColor UNIT = { @@ -48,206 +120,639 @@ UNIT = { -- @field White -- @field Orange -- @field Blue - +-- Registration. + --- Create a new UNIT from DCSUnit. -- @param #UNIT self -- @param DCSUnit#Unit DCSUnit +-- @param Database#DATABASE Database -- @return Unit#UNIT -function UNIT:New( DCSUnit ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSUnit ) +function UNIT:Register( UnitName ) - self.DCSUnit = DCSUnit - if DCSUnit then - self.UnitName = DCSUnit:getName() - self.UnitID = DCSUnit:getID() - end - - return self + local self = BASE:Inherit( self, BASE:New() ) + self:F2( UnitName ) + self.UnitName = UnitName + return self end -function UNIT:IsAlive() - self:F( self.UnitName ) - - return ( self.DCSUnit and self.DCSUnit:isExist() ) +-- Reference methods. + +--- Finds a UNIT from the _DATABASE using a DCSUnit object. +-- @param #UNIT self +-- @param DCSUnit#Unit DCSUnit An existing DCS Unit object reference. +-- @return Unit#UNIT self +function UNIT:Find( DCSUnit ) + + local UnitName = DCSUnit:getName() + local UnitFound = _DATABASE:FindUnit( UnitName ) + return UnitFound end +--- Find a UNIT in the _DATABASE using the name of an existing DCS Unit. +-- @param #UNIT self +-- @param #string UnitName The Unit Name. +-- @return Unit#UNIT self +function UNIT:FindByName( UnitName ) + + local UnitFound = _DATABASE:FindUnit( UnitName ) + return UnitFound +end function UNIT:GetDCSUnit() - self:F( self.DCSUnit ) - - return self.DCSUnit -end - -function UNIT:GetID() - self:F( self.UnitID ) - - return self.UnitID -end - - -function UNIT:GetName() - self:F( self.UnitName ) - - return self.UnitName -end - -function UNIT:GetPlayerName() - self:F( self.UnitName ) - local DCSUnit = Unit.getByName( self.UnitName ) - local PlayerName = DCSUnit:getPlayerName() - if PlayerName == nil then - PlayerName = "" + if DCSUnit then + return DCSUnit end + + return nil +end + +--- Returns coalition of the Unit. +-- @param Unit#UNIT self +-- @return DCSCoalitionObject#coalition.side The side of the coalition. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetCoalition() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() - return PlayerName -end -function UNIT:GetTypeName() - self:F( self.UnitName ) - - return self.DCSUnit:getTypeName() + if DCSUnit then + local UnitCoalition = DCSUnit:getCoalition() + self:T3( UnitCoalition ) + return UnitCoalition + end + + return nil end -function UNIT:GetPrefix() - self:F( self.UnitName ) - - local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 ) - self:T( UnitPrefix ) +--- Returns country of the Unit. +-- @param Unit#UNIT self +-- @return DCScountry#country.id The country identifier. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetCountry() + self:F2( self.UnitName ) - return UnitPrefix + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitCountry = DCSUnit:getCountry() + self:T3( UnitCountry ) + return UnitCountry + end + + return nil +end + + +--- Returns DCS Unit object name. +-- The function provides access to non-activated units too. +-- @param Unit#UNIT self +-- @return #string The name of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetName() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitName = self.UnitName + return UnitName + end + + return nil end -function UNIT:GetCallSign() - self:F( self.UnitName ) +--- Returns if the unit is alive. +-- @param Unit#UNIT self +-- @return #boolean true if Unit is alive. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:IsAlive() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitIsAlive = DCSUnit:isExist() + return UnitIsAlive + end - return self.DCSUnit:getCallsign() -end - - -function UNIT:GetPointVec2() - self:F( self.UnitName ) - - local UnitPos = self.DCSUnit:getPosition().p - - local UnitPoint = {} - UnitPoint.x = UnitPos.x - UnitPoint.y = UnitPos.z - - self:T( UnitPoint ) - return UnitPoint -end - - -function UNIT:GetPositionVec3() - self:F( self.UnitName ) - - local UnitPos = self.DCSUnit:getPosition().p - - self:T( UnitPos ) - return UnitPos -end - -function UNIT:OtherUnitInRadius( AwaitUnit, Radius ) - self:F( { self.UnitName, AwaitUnit.UnitName, Radius } ) - - local UnitPos = self:GetPositionVec3() - local AwaitUnitPos = AwaitUnit:GetPositionVec3() - - if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then - self:T( "true" ) - return true - else - self:T( "false" ) - return false - end - - self:T( "false" ) return false end +--- Returns if the unit is activated. +-- @param Unit#UNIT self +-- @return #boolean true if Unit is activated. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:IsActive() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + + local UnitIsActive = DCSUnit:isActive() + return UnitIsActive + end + + return nil +end + +--- Returns name of the player that control the unit or nil if the unit is controlled by A.I. +-- @param Unit#UNIT self +-- @return #string Player Name +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPlayerName() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + + local PlayerName = DCSUnit:getPlayerName() + if PlayerName == nil then + PlayerName = "" + end + return PlayerName + end + + return nil +end + +--- Returns the unit's unique identifier. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.ID Unit ID +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetID() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitID = DCSUnit:getID() + return UnitID + end + + return nil +end + +--- Returns the unit's number in the group. +-- The number is the same number the unit has in ME. +-- It may not be changed during the mission. +-- If any unit in the group is destroyed, the numbers of another units will not be changed. +-- @param Unit#UNIT self +-- @return #number The Unit number. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetNumber() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitNumber = DCSUnit:getNumber() + return UnitNumber + end + + return nil +end + +--- Returns the unit's group if it exist and nil otherwise. +-- @param Unit#UNIT self +-- @return Group#GROUP The Group of the Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetGroup() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitGroup = DCSUnit:getGroup() + return UnitGroup + end + + return nil +end + + +--- Returns the unit's callsign - the localized string. +-- @param Unit#UNIT self +-- @return #string The Callsign of the Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetCallSign() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitCallSign = DCSUnit:getCallsign() + return UnitCallSign + end + + return nil +end + +--- Returns the unit's health. Dead units has health <= 1.0. +-- @param Unit#UNIT self +-- @return #number The Unit's health value. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetLife() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitLife = DCSUnit:getLife() + return UnitLife + end + + return nil +end + +--- Returns the Unit's initial health. +-- @param Unit#UNIT self +-- @return #number The Unit's initial health value. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetLife0() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitLife0 = DCSUnit:getLife0() + return UnitLife0 + end + + return nil +end + +--- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +-- @param Unit#UNIT self +-- @return #number The relative amount of fuel (from 0.0 to 1.0). +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetFuel() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitFuel = DCSUnit:getFuel() + return UnitFuel + end + + return nil +end + +--- Returns the Unit's ammunition. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.Ammo +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetAmmo() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitAmmo = DCSUnit:getAmmo() + return UnitAmmo + end + + return nil +end + +--- Returns the unit sensors. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.Sensors +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetSensors() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitSensors = DCSUnit:getSensors() + return UnitSensors + end + + return nil +end + +-- Need to add here a function per sensortype +-- unit:hasSensors(Unit.SensorType.RADAR, Unit.RadarType.AS) + +--- Returns two values: +-- +-- * First value indicates if at least one of the unit's radar(s) is on. +-- * Second value is the object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target. +-- @param Unit#UNIT self +-- @return #boolean Indicates if at least one of the unit's radar(s) is on. +-- @return DCSObject#Object The object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetRadar() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitRadarOn, UnitRadarObject = DCSUnit:getRadar() + return UnitRadarOn, UnitRadarObject + end + + return nil, nil +end + +-- Need to add here functions to check if radar is on and which object etc. + +--- Returns unit descriptor. Descriptor type depends on unit category. +-- @param Unit#UNIT self +-- @return DCSUnit#Unit.Desc The Unit descriptor. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetDesc() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitDesc = DCSUnit:getDesc() + return UnitDesc + end + + return nil +end + + +--- Returns the type name of the DCS Unit. +-- @param Unit#UNIT self +-- @return #string The type name of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetTypeName() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitTypeName = DCSUnit:getTypeName() + self:T3( UnitTypeName ) + return UnitTypeName + end + + return nil +end + + + +--- Returns the prefix name of the DCS Unit. A prefix name is a part of the name before a '#'-sign. +-- DCS Units spawned with the @{SPAWN} class contain a '#'-sign to indicate the end of the (base) DCS Unit name. +-- The spawn sequence number and unit number are contained within the name after the '#' sign. +-- @param Unit#UNIT self +-- @return #string The name of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPrefix() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 ) + self:T3( UnitPrefix ) + return UnitPrefix + end + + return nil +end + + + +--- Returns the @{DCSTypes#Vec2} vector indicating the point in 2D of the DCS Unit within the mission. +-- @param Unit#UNIT self +-- @return DCSTypes#Vec2 The 2D point vector of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPointVec2() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPointVec3 = DCSUnit:getPosition().p + + local UnitPointVec2 = {} + UnitPointVec2.x = UnitPointVec3.x + UnitPointVec2.y = UnitPointVec3.z + + self:T3( UnitPointVec2 ) + return UnitPointVec2 + end + + return nil +end + + +--- Returns the @{DCSTypes#Vec3} vector indicating the point in 3D of the DCS Unit within the mission. +-- @param Unit#UNIT self +-- @return DCSTypes#Vec3 The 3D point vector of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPointVec3() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPointVec3 = DCSUnit:getPosition().p + self:T3( UnitPointVec3 ) + return UnitPointVec3 + end + + return nil +end + +--- Returns the @{DCSTypes#Position3} position vectors indicating the point and direction vectors in 3D of the DCS Unit within the mission. +-- @param Unit#UNIT self +-- @return DCSTypes#Position The 3D position vectors of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetPositionVec3() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPosition = DCSUnit:getPosition() + self:T3( UnitPosition ) + return UnitPosition + end + + return nil +end + +--- Returns the DCS Unit velocity vector. +-- @param Unit#UNIT self +-- @return DCSTypes#Vec3 The velocity vector +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetVelocity() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitVelocityVec3 = DCSUnit:getVelocity() + self:T3( UnitVelocityVec3 ) + return UnitVelocityVec3 + end + + return nil +end + +--- Returns true if the DCS Unit is in the air. +-- @param Unit#UNIT self +-- @return #boolean true if in the air. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:InAir() + self:F2( self.UnitName ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitInAir = DCSUnit:inAir() + self:T3( UnitInAir ) + return UnitInAir + end + + return nil +end + +--- Returns the altitude of the DCS Unit. +-- @param Unit#UNIT self +-- @return DCSTypes#Distance The altitude of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetAltitude() + self:F2() + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPointVec3 = DCSUnit:getPoint() --DCSTypes#Vec3 + return UnitPointVec3.y + end + + return nil +end + +--- Returns true if there is an **other** DCS Unit within a radius of the current 2D point of the DCS Unit. +-- @param Unit#UNIT self +-- @param Unit#UNIT AwaitUnit The other UNIT wrapper object. +-- @param Radius The radius in meters with the DCS Unit in the centre. +-- @return true If the other DCS Unit is within the radius of the 2D point of the DCS Unit. +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:OtherUnitInRadius( AwaitUnit, Radius ) + self:F2( { self.UnitName, AwaitUnit.UnitName, Radius } ) + + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitPos = self:GetPointVec3() + local AwaitUnitPos = AwaitUnit:GetPointVec3() + + if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then + self:T3( "true" ) + return true + else + self:T3( "false" ) + return false + end + end + + return nil +end + +--- Returns the DCS Unit category name as defined within the DCS Unit Descriptor. +-- @param Unit#UNIT self +-- @return #string The DCS Unit Category Name function UNIT:GetCategoryName() - return self.CategoryName[ self.DCSUnit:getDesc().category ] + local DCSUnit = self:GetDCSUnit() + + if DCSUnit then + local UnitCategoryName = self.CategoryName[ self:GetDesc().category ] + return UnitCategoryName + end + + return nil end --- Signal a flare at the position of the UNIT. -- @param #UNIT self function UNIT:Flare( FlareColor ) - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), FlareColor , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), FlareColor , 0 ) end --- Signal a white flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareWhite() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.White , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.White , 0 ) end --- Signal a yellow flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareYellow() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Yellow , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Yellow , 0 ) end --- Signal a green flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareGreen() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Green , 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Green , 0 ) end --- Signal a red flare at the position of the UNIT. -- @param #UNIT self function UNIT:FlareRed() - self:F() - trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Red, 0 ) + self:F2() + trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Red, 0 ) end --- Smoke the UNIT. -- @param #UNIT self function UNIT:Smoke( SmokeColor ) - self:F() - trigger.action.smoke( self:GetPositionVec3(), SmokeColor ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), SmokeColor ) end --- Smoke the UNIT Green. -- @param #UNIT self function UNIT:SmokeGreen() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Green ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Green ) end --- Smoke the UNIT Red. -- @param #UNIT self function UNIT:SmokeRed() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Red ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Red ) end --- Smoke the UNIT White. -- @param #UNIT self function UNIT:SmokeWhite() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.White ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.White ) end --- Smoke the UNIT Orange. -- @param #UNIT self function UNIT:SmokeOrange() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Orange ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Orange ) end --- Smoke the UNIT Blue. -- @param #UNIT self function UNIT:SmokeBlue() - self:F() - trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Blue ) + self:F2() + trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Blue ) end -- Is methods @@ -257,14 +762,14 @@ end -- @param #UNIT self -- @return #boolean Air category evaluation result. function UNIT:IsAir() - self:F() + self:F2() local UnitDescriptor = self.DCSUnit:getDesc() - self:T( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) + self:T3( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) local IsAirResult = ( UnitDescriptor.category == Unit.Category.AIRPLANE ) or ( UnitDescriptor.category == Unit.Category.HELICOPTER ) - self:T( IsAirResult ) + self:T3( IsAirResult ) return IsAirResult end diff --git a/Presentations/DCS World - MOOSE - Development - Part 3 - The DATABASE - UNIT - CLIENT - GROUP - ZONE, .pptx b/Presentations/DCS World - MOOSE - Development - Part 3 - The DATABASE - UNIT - CLIENT - GROUP - ZONE, .pptx new file mode 100644 index 000000000..62b627f62 Binary files /dev/null and b/Presentations/DCS World - MOOSE - Development - Part 3 - The DATABASE - UNIT - CLIENT - GROUP - ZONE, .pptx differ diff --git a/Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz b/Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz index af1132ad3..d64a61ca6 100644 Binary files a/Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz and b/Test Missions/Moose_Test_DESTROY/MOOSE_Test_DESTROY.miz differ diff --git a/Test Missions/Moose_Test_DESTROY/Moose_Test_DESTROY.lua b/Test Missions/Moose_Test_DESTROY/Moose_Test_DESTROY.lua index 4eecb01d7..2caa20805 100644 --- a/Test Missions/Moose_Test_DESTROY/Moose_Test_DESTROY.lua +++ b/Test Missions/Moose_Test_DESTROY/Moose_Test_DESTROY.lua @@ -12,7 +12,7 @@ Include.File( "Event" ) do local Mission = MISSION:New( 'Destroy Gound', 'Ground', 'Briefing', 'CCCP' ) - Mission:AddClient( CLIENT:New( 'Client Plane', "Just wait and observe the SU-25T destoying targets. Your mission goal should increase..." ) ) + Mission:AddClient( CLIENT:FindByName( 'Client Plane', "Just wait and observe the SU-25T destoying targets. Your mission goal should increase..." ) ) local DESTROYGROUPSTASK = DESTROYGROUPSTASK:New( 'Ground Vehicle', 'Ground Vehicles', { 'DESTROY Test 1' }, 100 ) -- 75% of a patriot battery needs to be destroyed to achieve mission success... DESTROYGROUPSTASK:SetGoalTotal( 1 ) @@ -25,7 +25,7 @@ end do local Mission = MISSION:New( 'Destroy Helicopters', 'Helicopters', 'Briefing', 'CCCP' ) - Mission:AddClient( CLIENT:New( 'Client Plane', "Just wait and observe the SU-25T destoying the helicopters. The helicopter mission goal should increase once all are destroyed ..." ) ) + Mission:AddClient( CLIENT:FindByName( 'Client Plane', "Just wait and observe the SU-25T destoying the helicopters. The helicopter mission goal should increase once all are destroyed ..." ) ) local DESTROYGROUPSTASK = DESTROYGROUPSTASK:New( 'Helicopter', 'Helicopters', { 'DESTROY Test 2' }, 50 ) DESTROYGROUPSTASK:SetGoalTotal( 2 ) diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua index 6e5e36e0b..e6803dad4 100644 --- a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua +++ b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua @@ -53,8 +53,8 @@ do SpawnEscortGround = SPAWN:New( "Escort Ground" ) SpawnEscortShip = SPAWN:New( "Escort Ship" ) - EscortClientHeli = CLIENT:New( "Lead Helicopter", "Fly around and observe the behaviour of the escort helicopter" ):Alive( EventAliveHelicopter ) - EscortClientPlane = CLIENT:New( "Lead Plane", "Fly around and observe the behaviour of the escort airplane. Select Navigate->Joun-Up and airplane should follow you. Change speed and directions." ) + EscortClientHeli = CLIENT:FindByName( "Lead Helicopter", "Fly around and observe the behaviour of the escort helicopter" ):Alive( EventAliveHelicopter ) + EscortClientPlane = CLIENT:FindByName( "Lead Plane", "Fly around and observe the behaviour of the escort airplane. Select Navigate->Joun-Up and airplane should follow you. Change speed and directions." ) :Alive( EventAlivePlane ) end diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz index 2b8e5b658..b0ae3d33e 100644 Binary files a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz and b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz differ diff --git a/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz b/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz index 009a8dcde..2c83c8948 100644 Binary files a/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz and b/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz differ diff --git a/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua b/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua index 71bb56e2f..293d8faf8 100644 --- a/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua +++ b/Test Missions/Moose_Test_SPAWN/MOOSE_Test_SPAWN.lua @@ -26,7 +26,7 @@ Group_Vehicle6 = Spawn_Vehicle:Spawn() Group_Vehicle1:TaskRouteToZone( ZONE:New( "Landing Zone" ), true, 40, "Cone" ) -- Now land the spawned plane on to the Vinson, by copying the route of another object. -Route_Plane = GROUP:NewFromName( "Spawn Helicopter Route Copy" ):CopyRoute( 1, 0 ) +Route_Plane = GROUP:FindByName( "Spawn Helicopter Route Copy" ):CopyRoute( 1, 0 ) Group_Plane:Route( Route_Plane ) diff --git a/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.lua b/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.lua index 516bf390a..53728aaa4 100644 --- a/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.lua +++ b/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.lua @@ -14,8 +14,8 @@ Include.File( "CleanUp" ) do local Mission = MISSION:New( 'Pickup', 'Operational', 'Pickup Troops', 'NATO' ) - Mission:AddClient( CLIENT:New( 'DE Pickup Test 1' ):Transport() ) - Mission:AddClient( CLIENT:New( 'DE Pickup Test 2' ):Transport() ) + Mission:AddClient( CLIENT:FindByName( 'DE Pickup Test 1' ):Transport() ) + Mission:AddClient( CLIENT:FindByName( 'DE Pickup Test 2' ):Transport() ) local CargoTable = {} @@ -62,7 +62,7 @@ end do local Mission = MISSION:New( 'Deliver secret letter', 'Operational', 'Pickup letter to the commander.', 'NATO' ) - Client_Package_1 = CLIENT:New( 'BE Package Test 1' ):Transport() + Client_Package_1 = CLIENT:FindByName( 'BE Package Test 1' ):Transport() Mission:AddClient( Client_Package_1 ) @@ -95,8 +95,8 @@ end do local Mission = MISSION:New( 'Sling load Cargo', 'Operational', 'Sling Load Cargo to Deploy Zone.', 'NATO' ) - Mission:AddClient( CLIENT:New( 'Sling Load Test Client 1' ):Transport() ) - Mission:AddClient( CLIENT:New( 'Sling Load Test Client 2' ):Transport() ) + Mission:AddClient( CLIENT:FindByName( 'Sling Load Test Client 1' ):Transport() ) + Mission:AddClient( CLIENT:FindByName( 'Sling Load Test Client 2' ):Transport() ) Sling_Load_Pickup_Zone = CARGO_ZONE:New( 'Sling Load Pickup Zone', 'Sling Load Guard' ):RedSmoke() diff --git a/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz b/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz index 28934e59b..f92fcbb52 100644 Binary files a/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz and b/Test Missions/Moose_Test_TASK_Pickup_and_Deploy/MOOSE_Test_TASK_Pickup_and_Deploy.miz differ diff --git a/Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.lua b/Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.lua new file mode 100644 index 000000000..dc09e4e7d --- /dev/null +++ b/Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.lua @@ -0,0 +1,39 @@ + +Include.File( "Group" ) +Include.File( "Unit" ) +Include.File( "Client" ) + +BASE:TraceClass( "UNIT" ) +BASE:TraceClass( "GROUP" ) +BASE:TraceClass( "CLIENT" ) + +UnitTankAI1 = _DATABASE:FindUnit( "Smoke Test 1" ) +UnitTankAI2 = _DATABASE:FindUnit( "Smoke Test 2" ) +UnitTankAI3 = UNIT:FindByName( "Smoke Test 3" ) +UnitTankAI4 = _DATABASE:FindUnit( "Smoke Test 4" ) + +UnitTankAI1:SmokeBlue() + +UnitTankAI3:SmokeOrange() + +UnitTankAI2:T( UnitTankAI2:GetAmmo() ) + +GroupTanks = GROUP:FindByName( "Smoke Test" ) + +GroupTanks:T( GroupTanks:OptionROEOpenFirePossible() ) + +GroupTanks:OptionROEOpenFire() + + local function ClientAlive( Client, ClientNumber ) + GroupTanks:MessageToClient( "Hello Client " .. ClientNumber .. "! We are reporting to you on our way...", 5, Client ) + end + + +ClientHeli = CLIENT:FindByName( "Client Test 1", "Fly slowly to waypoint 3 of the Command Post!" ):Alive( ClientAlive, 1 ) +ClientHeli2 = CLIENT:FindByName( "Client Test 2", "Fly slowly to waypoint 3 of the Command Post!" ):Alive( ClientAlive, 2 ) + + + + + + diff --git a/Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz b/Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz new file mode 100644 index 000000000..521c49aa2 Binary files /dev/null and b/Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz differ
    UNIT.ClassName +
    UNIT:Find(DCSUnit) +

    Finds a UNIT from the _DATABASE using a DCSUnit object.

    +
    UNIT:FindByName(UnitName) +

    Find a UNIT in the _DATABASE using the name of an existing DCS Unit.

    UNIT:FlareYellow()

    Signal a yellow flare at the position of the UNIT.

    +
    UNIT:GetAltitude() +

    Returns the altitude of the DCS Unit.

    +
    UNIT:GetAmmo() +

    Returns the Unit's ammunition.

    UNIT:GetCallSign() - +

    Returns the unit's callsign - the localized string.

    UNIT:GetCategoryName() - +

    Returns the DCS Unit category name as defined within the DCS Unit Descriptor.

    +
    UNIT:GetCoalition() +

    Returns coalition of the Unit.

    +
    UNIT:GetCountry() +

    Returns country of the Unit.

    UNIT:GetDCSUnit() +
    UNIT:GetDesc() +

    Returns unit descriptor.

    +
    UNIT:GetFuel() +

    Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks.

    +
    UNIT:GetGroup() +

    Returns the unit's group if it exist and nil otherwise.

    UNIT:GetID() - +

    Returns the unit's unique identifier.

    +
    UNIT:GetLife() +

    Returns the unit's health.

    +
    UNIT:GetLife0() +

    Returns the Unit's initial health.

    UNIT:GetName() - +

    Returns DCS Unit object name.

    +
    UNIT:GetNumber() +

    Returns the unit's number in the group.

    UNIT:GetPlayerName() - +

    Returns name of the player that control the unit or nil if the unit is controlled by A.I.

    UNIT:GetPointVec2() - +

    Returns the DCSTypes#Vec2 vector indicating the point in 2D of the DCS Unit within the mission.

    +
    UNIT:GetPointVec3() +

    Returns the DCSTypes#Vec3 vector indicating the point in 3D of the DCS Unit within the mission.

    UNIT:GetPositionVec3() - +

    Returns the DCSTypes#Position3 position vectors indicating the point and direction vectors in 3D of the DCS Unit within the mission.

    UNIT:GetPrefix() +

    Returns the prefix name of the DCS Unit.

    +
    UNIT:GetRadar() +

    Returns two values:

    +
      +
    • First value indicates if at least one of the unit's radar(s) is on.
    • +
    +
    UNIT:GetSensors() +

    Returns the unit sensors.

    UNIT:GetTypeName() - +

    Returns the type name of the DCS Unit.

    +
    UNIT:GetVelocity() +

    Returns the DCS Unit velocity vector.

    +
    UNIT:InAir() +

    Returns true if the DCS Unit is in the air.

    +
    UNIT:IsActive() +

    Returns if the unit is activated.

    UNIT:IsAlive() - -
    UNIT:New(DCSUnit) -

    Create a new UNIT from DCSUnit.

    +

    Returns if the unit is alive.

    UNIT:OtherUnitInRadius(AwaitUnit, Radius) - +

    Returns true if there is an other DCS Unit within a radius of the current 2D point of the DCS Unit.

    +
    UNIT:Register(DCSUnit, Database, UnitName) +

    Create a new UNIT from DCSUnit.

    Client

    The CLIENT models client units in multi player missions.

    +
    DCSAirbase + +
    DCSCoalitionObject + +
    DCSCommand + +
    DCSController + +
    DCSGroup + +
    DCSObject + +
    DCSTask + +
    DCSTypes + +
    DCSUnit + +
    DCSWorld + +
    DCStimer +
    Group -

    A GROUP class abstraction of a DCSGroup class.

    +

    GROUP class.

    Sead

    Provides defensive behaviour to a set of SAM sites within a running Mission.

    +
    Set +

    Manage sets of units and groups.

    Spawn

    Dynamic spawning of groups (and units).

    +
    StaticObject +
    Unit -

    UNIT Classes

    +

    UNIT Class

    + +

    UNIT class

    +

    The UNIT class is a wrapper class to handle the DCS Unit objects:

    + +
      +
    • Support all DCS Unit APIs.
    • +
    Zone

    ZONE Classes

    +
    env + +
    land +