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/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 cec5967a3..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/CARGO.html b/Documentation/CARGO.html index 3927ac107..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/CLEANUP.html b/Documentation/CLEANUP.html index 4e3e55cb0..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Client.html b/Documentation/Client.html index b45d4be53..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -60,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)

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

    - - - - @@ -171,6 +202,18 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

    + + + + + + + + @@ -237,24 +280,12 @@ Note that clients are NOT the same as Units, they are NOT necessarily alive.

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

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

    Return value

    -

    #CLIENT:

    - +

    #CLIENT: +self

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

    #CLIENT:

    - - -
    -
    - - - -CLIENT.AliveCheckScheduler - -
    -
    - - -
    @@ -536,7 +559,6 @@ Function.

    - CLIENT.ClientName @@ -573,6 +595,100 @@ Function.

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

    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

    + +

    #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() )
    +
    @@ -794,20 +910,6 @@ is the interval in seconds between the display of the -
    - - #boolean - -CLIENT.MessageSwitch - -
    -
    - - -
    @@ -822,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() )
    -
    @@ -927,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 8f8bebbc4..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYBASETASK.html b/Documentation/DESTROYBASETASK.html index 2fdf173df..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYGROUPSTASK.html b/Documentation/DESTROYGROUPSTASK.html index 88cb8aba6..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYRADARSTASK.html b/Documentation/DESTROYRADARSTASK.html index e7de3a904..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/DESTROYUNITTYPESTASK.html b/Documentation/DESTROYUNITTYPESTASK.html index cb581bed7..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Database.html b/Documentation/Database.html index 07554c5b7..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -143,6 +157,12 @@ The following iterator methods are currently available within the DATABASE:

    + + + + @@ -152,13 +172,13 @@ The following iterator methods are currently available within the DATABASE:

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

    + + + + @@ -236,15 +262,15 @@ The following iterator methods are currently available within the DATABASE:

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

    - + @@ -421,6 +447,32 @@ The following iterator methods are currently available within the DATABASE:

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

    Adds a GROUP based on the GroupName in the DATABASE.

    + +

    Parameters

    + +
    +
    +
    +
    + DATABASE:AddUnit(DCSUnit, DCSUnitName) @@ -447,9 +499,9 @@ The following iterator methods are currently available within the DATABASE:

    - #string - -DATABASE.ClassName + + +DATABASE.CLIENTS
    @@ -461,9 +513,9 @@ The following iterator methods are currently available within the DATABASE:

    - - -DATABASE.Clients + #string + +DATABASE.ClassName
    @@ -592,6 +644,32 @@ The found CLIENT.

    + +DATABASE:FindGroup(GroupName) + +
    +
    + +

    Finds a GROUP based on the GroupName.

    + +

    Parameter

    +
      +
    • + +

      #string GroupName :

      + +
    • +
    +

    Return value

    + +

    Group#GROUP: +The found GROUP.

    + +
    +
    +
    +
    + DATABASE:FindUnit(UnitName) @@ -746,6 +824,20 @@ The function that will be called when there is an alive player in the database.

    #DATABASE: self

    +
    +
    +
    +
    + + + +DATABASE.GROUPS + +
    +
    + + +
    @@ -767,20 +859,6 @@ self

    -
    -
    -
    -
    - - - -DATABASE.Groups - -
    -
    - - -
    @@ -970,8 +1048,8 @@ self

    - -DATABASE.Units + +DATABASE.UNITS
    diff --git a/Documentation/Escort.html b/Documentation/Escort.html index 5c70cc46c..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -1836,6 +1850,7 @@ self

    + ESCORT.ReportTargetsScheduler diff --git a/Documentation/Event.html b/Documentation/Event.html index ce93521fd..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/GOHOMETASK.html b/Documentation/GOHOMETASK.html index a2aedee46..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Group.html b/Documentation/Group.html index eccd41bc8..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
  • @@ -45,19 +56,52 @@
  • 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)

    CLIENT:Alive(CallBack, ...)

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

    -
    CLIENT.AliveCheckScheduler -
    CLIENT.ClientTransport +
    CLIENT:Find(ClientName, ClientBriefing, DCSUnit) +

    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:Message(Message, MessageDuration, MessageId, MessageCategory, MessageInterval)

    The main message driver for the CLIENT.

    -
    CLIENT.MessageSwitch -
    CLIENT.Messages -
    CLIENT:New(ClientName, ClientBriefing) -

    Use this method to register new Clients within a mission.

    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.

    DATABASE: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.ClassNameDATABASE.CLIENTS
    DATABASE.ClientsDATABASE.ClassName DATABASE:FindClient(ClientName)

    Finds a CLIENT based on the ClientName.

    +
    DATABASE:FindGroup(GroupName) +

    Finds a GROUP based on the GroupName.

    DATABASE:GetStatusGroup(GroupName)DATABASE.GROUPS -

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

    +
    DATABASE.GroupsDATABASE:GetStatusGroup(GroupName) - +

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

    DATABASE.UnitsDATABASE.UNITS
    @@ -113,7 +157,7 @@ @@ -131,44 +175,61 @@ - + + + + + + + + + + + + + @@ -180,7 +241,15 @@ Note that this destroy method also raises a destroy event at run-time.

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

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

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

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

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

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

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

    - + @@ -619,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: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 -
    @@ -799,14 +858,13 @@ All units on the ground result.

    - #table GROUP.Controller
    -

    The controller of the group.

    +
    @@ -873,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.

    @@ -925,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

    @@ -943,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

    @@ -955,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.

    @@ -979,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.

    @@ -1006,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.

    @@ -1037,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.

    @@ -1118,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.

    @@ -1136,12 +1275,12 @@ 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.

    @@ -1154,12 +1293,33 @@ Current x,y and z position of the group.

    -

    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.

    @@ -1226,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.

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

    -

    the ID of the group.

    +
    @@ -1302,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.

    @@ -1320,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.

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

    Return value

    #boolean: -Alive result.

    +true if the DCS Group is alive.

    @@ -1341,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.

    @@ -1359,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.

    @@ -1377,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.

    @@ -1573,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() @@ -1991,6 +2091,33 @@ self

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

    Create a new GROUP from a DCSGroup

    + +

    Parameter

    + +

    Return value

    + +

    #GROUP: +self

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

    • -

      #Time time :

      +

      DCSTime#Time time :

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

    • -

      #Time duration :

      +

      DCSTime#Time duration :

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

      • -

        #Vec2 Point : +

        DCSTypes#Vec2 Point : The point where to wait.

      • @@ -2290,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

    +
    @@ -2621,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 d20297316..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -273,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.

    @@ -1157,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 2e1825e50..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Menu.html b/Documentation/Menu.html index c2e778b76..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Message.html b/Documentation/Message.html index ecaa029d9..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/MissileTrainer.html b/Documentation/MissileTrainer.html index 54a295ba7..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/NOTASK.html b/Documentation/NOTASK.html index d56be9578..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/PICKUPTASK.html b/Documentation/PICKUPTASK.html index 3b5c01584..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/ROUTETASK.html b/Documentation/ROUTETASK.html index 9ab3852b2..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/STAGE.html b/Documentation/STAGE.html index 985997808..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Scheduler.html b/Documentation/Scheduler.html index cb5845838..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Scoring.html b/Documentation/Scoring.html index ad5556374..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Sead.html b/Documentation/Sead.html index 55b652c23..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Set.html b/Documentation/Set.html index 078f9d754..e43329a31 100644 --- a/Documentation/Set.html +++ b/Documentation/Set.html @@ -21,6 +21,17 @@
  • CARGO
  • CleanUp
  • Client
  • +
  • DCSAirbase
  • +
  • DCSCoalitionObject
  • +
  • DCSCommand
  • +
  • DCSController
  • +
  • DCSGroup
  • +
  • DCSObject
  • +
  • DCSTask
  • +
  • DCSTypes
  • +
  • DCSUnit
  • +
  • DCSWorld
  • +
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Spawn.html b/Documentation/Spawn.html index b0c92b062..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
  • @@ -45,9 +56,12 @@
  • 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 fee28dd8f..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Documentation/Unit.html b/Documentation/Unit.html index c55741f7e..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -67,7 +81,7 @@ @@ -75,7 +89,7 @@

    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 +

    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. @@ -86,11 +100,45 @@ If the DCS Unit object does not exist or is nil, the UNIT methods will return ni

    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)

    diff --git a/Documentation/Zone.html b/Documentation/Zone.html index f3c5ffc36..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
  • @@ -45,9 +56,12 @@
  • 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 7ac67ba31..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • @@ -76,6 +90,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -135,7 +215,7 @@ @@ -220,6 +300,12 @@ + + + + @@ -245,6 +331,18 @@ + + + + + + + + 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 6dd92ef95..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
  • @@ -45,9 +56,12 @@
  • Sead
  • Set
  • Spawn
  • +
  • StaticObject
  • TASK
  • Unit
  • Zone
  • +
  • env
  • +
  • land
  • routines
  • diff --git a/Embedded/Moose_Embedded.lua b/Embedded/Moose_Embedded.lua index 302dd40da..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 ) - - local GroupPoint = self:GetUnit(1):GetPointVec2() - self:T( GroupPoint ) - return GroupPoint -end - ---- Gets the current Point of the GROUP in VEC3 format. --- @return #Vec3 Current Vec3 position of the group. +--- 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:F( self.GroupName ) + self:F2( self.GroupName ) - local GroupPoint = self:GetUnit(1):GetPointVec3() - self:T( GroupPoint ) - return GroupPoint + local GroupPointVec3 = self:GetUnit(1):GetPointVec3() + self:T3( GroupPointVec3 ) + return GroupPointVec3 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,22 +5144,73 @@ 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 ):GetPointVec3() @@ -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,205 +5992,638 @@ 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:GetPointVec3() - 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:GetPointVec3() - local AwaitUnitPos = AwaitUnit:GetPointVec3() - - 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() + 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() + 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() + 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() + 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() + self:F2() trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Red, 0 ) end --- Smoke the UNIT. -- @param #UNIT self function UNIT:Smoke( SmokeColor ) - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), SmokeColor ) end --- Smoke the UNIT Green. -- @param #UNIT self function UNIT:SmokeGreen() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Green ) end --- Smoke the UNIT Red. -- @param #UNIT self function UNIT:SmokeRed() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Red ) end --- Smoke the UNIT White. -- @param #UNIT self function UNIT:SmokeWhite() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.White ) end --- Smoke the UNIT Orange. -- @param #UNIT self function UNIT:SmokeOrange() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Orange ) end --- Smoke the UNIT Blue. -- @param #UNIT self function UNIT:SmokeBlue() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Blue ) end @@ -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:GetPointVec3() - 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:GetPositionVec3() - 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 @@ -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 @@ -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() @@ -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 diff --git a/Moose/Client.lua b/Moose/Client.lua index b1d4d2e24..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 @@ -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,26 +104,34 @@ 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 ) - self = _DATABASE:FindClient( ClientName ) +-- 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:F( ClientName, ClientBriefing ) - self.ClientName = ClientName - self:AddBriefing( ClientBriefing ) - self.MessageSwitch = true + if ClientFound then + ClientFound:F( { ClientName, ClientBriefing } ) + ClientFound:AddBriefing( ClientBriefing ) + ClientFound.MessageSwitch = true - return self + 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 @@ -92,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 @@ -108,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. @@ -147,15 +214,30 @@ function CLIENT:IsMultiSeated() return false 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.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 -- 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 @@ -276,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 @@ -342,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 b725d9728..1814af91f 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -83,13 +83,13 @@ DATABASE = { }, DCSUnits = {}, DCSGroups = {}, - Units = {}, - Groups = {}, + UNITS = {}, + GROUPS = {}, NavPoints = {}, Statics = {}, Players = {}, PlayersAlive = {}, - Clients = {}, + CLIENTS = {}, ClientsAlive = {}, Filter = { Coalitions = nil, @@ -163,7 +163,7 @@ end -- @return Unit#UNIT The found Unit. function DATABASE:FindUnit( UnitName ) - local UnitFound = self.Units[UnitName] + local UnitFound = self.UNITS[UnitName] return UnitFound end @@ -172,7 +172,7 @@ end function DATABASE:AddUnit( DCSUnit, DCSUnitName ) self.DCSUnits[DCSUnitName] = DCSUnit - self.Units[DCSUnitName] = UNIT:Register( DCSUnitName ) + self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName ) end --- Deletes a Unit from the DATABASE based on the Unit Name. @@ -188,7 +188,7 @@ end -- @return Client#CLIENT The found CLIENT. function DATABASE:FindClient( ClientName ) - local ClientFound = self.Clients[ClientName] + local ClientFound = self.CLIENTS[ClientName] return ClientFound end @@ -196,7 +196,26 @@ end -- @param #DATABASE self function DATABASE:AddClient( ClientName ) - self.Clients[ClientName] = CLIENT:Register( ClientName ) + self.CLIENTS[ClientName] = CLIENT:Register( ClientName ) + self:E( self.CLIENTS[ClientName]:GetClassNameAndID() ) +end + +--- Finds a GROUP based on the GroupName. +-- @param #DATABASE self +-- @param #string GroupName +-- @return Group#GROUP The found GROUP. +function DATABASE:FindGroup( GroupName ) + + local GroupFound = self.GROUPS[GroupName] + return GroupFound +end + +--- Adds a GROUP based on the GroupName in the DATABASE. +-- @param #DATABASE self +function DATABASE:AddGroup( DCSGroup, GroupName ) + + self.DCSGroups[GroupName] = DCSGroup + self.GROUPS[GroupName] = GROUP:Register( GroupName ) end --- Instantiate new Groups within the DCSRTE. @@ -230,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 @@ -333,8 +352,7 @@ function DATABASE:_RegisterDatabase() local DCSGroupName = DCSGroup:getName() self:E( { "Register Group:", DCSGroup, DCSGroupName } ) - self.DCSGroups[DCSGroupName] = DCSGroup - self.Groups[DCSGroupName] = GROUP:New( DCSGroup ) + self:AddGroup( DCSGroup, DCSGroupName ) for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do @@ -368,12 +386,7 @@ function DATABASE:_EventOnBirth( Event ) if Event.IniDCSUnit then if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName ) - - --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:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName ) self:_EventOnPlayerEnterUnit( Event ) end end @@ -388,6 +401,7 @@ function DATABASE:_EventOnDeadOrCrash( Event ) if Event.IniDCSUnit then 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 @@ -403,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 @@ -503,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 @@ -513,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 diff --git a/Moose/Group.lua b/Moose/Group.lua index d532c23df..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 ) - - local GroupPoint = self:GetUnit(1):GetPointVec2() - self:T( GroupPoint ) - return GroupPoint -end - ---- Gets the current Point of the GROUP in VEC3 format. --- @return #Vec3 Current Vec3 position of the group. +--- 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:F( self.GroupName ) + self:F2( self.GroupName ) - local GroupPoint = self:GetUnit(1):GetPointVec3() - self:T( GroupPoint ) - return GroupPoint + local GroupPointVec3 = self:GetUnit(1):GetPointVec3() + self:T3( GroupPointVec3 ) + return GroupPointVec3 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:Find( 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,22 +1144,73 @@ 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 ):GetPointVec3() @@ -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/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 index e10978d3a..063ec2fe0 100644 --- a/Moose/Set.lua +++ b/Moose/Set.lua @@ -308,7 +308,7 @@ function SET:FilterStart() self:E( { "Adding Unit:", DCSUnitName } ) self.DCSUnits[DCSUnitName] = _DATABASE.DCSUnits[DCSUnitName] - self.Units[DCSUnitName] = _DATABASE.Units[DCSUnitName] + self.Units[DCSUnitName] = _DATABASE:FindUnit( DCSUnitName ) if _DATABASE.DCSUnitsAlive[DCSUnitName] then self.DCSUnitsAlive[DCSUnitName] = _DATABASE.DCSUnitsAlive[DCSUnitName] @@ -323,7 +323,7 @@ function SET:FilterStart() --if self:_IsIncludeDCSGroup( DCSGroup ) then self:E( { "Adding Group:", DCSGroupName } ) self.DCSGroups[DCSGroupName] = _DATABASE.DCSGroups[DCSGroupName] - self.Groups[DCSGroupName] = _DATABASE.Groups[DCSGroupName] + self.Groups[DCSGroupName] = _DATABASE:FindGroups( DCSGroupName ) --end if _DATABASE.DCSGroupsAlive[DCSGroupName] then @@ -332,7 +332,7 @@ function SET:FilterStart() end end - for DCSUnitName, Client in pairs( _DATABASE.Clients ) do + for DCSUnitName, Client in pairs( _DATABASE.CLIENTS ) do self:E( { "Adding Client for Unit:", DCSUnitName } ) self.Clients[DCSUnitName] = _DATABASE.Clients[DCSUnitName] 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 99d13daf2..5df82eeec 100644 --- a/Moose/Unit.lua +++ b/Moose/Unit.lua @@ -7,7 +7,7 @@ -- * 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 objects. +-- * Manage the "state" of the DCS Unit. -- -- -- UNIT reference methods @@ -15,7 +15,7 @@ -- 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 +-- 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. @@ -25,10 +25,51 @@ -- 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 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 @@ -38,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 = { @@ -79,6 +120,8 @@ UNIT = { -- @field White -- @field Orange -- @field Blue + +-- Registration. --- Create a new UNIT from DCSUnit. -- @param #UNIT self @@ -88,11 +131,12 @@ UNIT = { function UNIT:Register( UnitName ) local self = BASE:Inherit( self, BASE:New() ) - self:F( UnitName ) + self:F2( UnitName ) self.UnitName = UnitName return self end +-- Reference methods. --- Finds a UNIT from the _DATABASE using a DCSUnit object. -- @param #UNIT self @@ -110,10 +154,9 @@ end -- @param #string UnitName The Unit Name. -- @return Unit#UNIT self function UNIT:FindByName( UnitName ) --- self:F( UnitName ) - local FoundUnit = _DATABASE:FindUnit( UnitName ) - return FoundUnit + local UnitFound = _DATABASE:FindUnit( UnitName ) + return UnitFound end function UNIT:GetDCSUnit() @@ -131,13 +174,13 @@ end -- @return DCSCoalitionObject#coalition.side The side of the coalition. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetCoalition() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitCoalition = DCSUnit:getCoalition() - self:T( UnitCoalition ) + self:T3( UnitCoalition ) return UnitCoalition end @@ -149,13 +192,13 @@ end -- @return DCScountry#country.id The country identifier. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetCountry() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitCountry = DCSUnit:getCountry() - self:T( UnitCountry ) + self:T3( UnitCountry ) return UnitCountry end @@ -169,7 +212,7 @@ end -- @return #string The name of the DCS Unit. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetName() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -187,7 +230,7 @@ end -- @return #boolean true if Unit is alive. -- @return #nil The DCS Unit is not existing or alive. function UNIT:IsAlive() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -204,7 +247,7 @@ end -- @return #boolean true if Unit is activated. -- @return #nil The DCS Unit is not existing or alive. function UNIT:IsActive() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -222,7 +265,7 @@ end -- @return #string Player Name -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetPlayerName() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -243,7 +286,7 @@ end -- @return DCSUnit#Unit.ID Unit ID -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetID() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -263,7 +306,7 @@ end -- @return #number The Unit number. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetNumber() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -280,7 +323,7 @@ end -- @return Group#GROUP The Group of the Unit. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetGroup() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -298,7 +341,7 @@ end -- @return #string The Callsign of the Unit. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetCallSign() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -315,7 +358,7 @@ end -- @return #number The Unit's health value. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetLife() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -332,7 +375,7 @@ end -- @return #number The Unit's initial health value. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetLife0() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -349,7 +392,7 @@ end -- @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:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -366,7 +409,7 @@ end -- @return DCSUnit#Unit.Ammo -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetAmmo() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -383,7 +426,7 @@ end -- @return DCSUnit#Unit.Sensors -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetSensors() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -407,7 +450,7 @@ end -- @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:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -426,7 +469,7 @@ end -- @return DCSUnit#Unit.Desc The Unit descriptor. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetDesc() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -444,13 +487,13 @@ end -- @return #string The type name of the DCS Unit. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetTypeName() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitTypeName = DCSUnit:getTypeName() - self:T( UnitTypeName ) + self:T3( UnitTypeName ) return UnitTypeName end @@ -466,13 +509,13 @@ end -- @return #string The name of the DCS Unit. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetPrefix() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 ) - self:T( UnitPrefix ) + self:T3( UnitPrefix ) return UnitPrefix end @@ -486,7 +529,7 @@ end -- @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:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() @@ -497,7 +540,7 @@ function UNIT:GetPointVec2() UnitPointVec2.x = UnitPointVec3.x UnitPointVec2.y = UnitPointVec3.z - self:T( UnitPointVec2 ) + self:T3( UnitPointVec2 ) return UnitPointVec2 end @@ -510,13 +553,13 @@ end -- @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:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitPointVec3 = DCSUnit:getPosition().p - self:T( UnitPointVec3 ) + self:T3( UnitPointVec3 ) return UnitPointVec3 end @@ -528,13 +571,13 @@ end -- @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:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitPosition = DCSUnit:getPosition() - self:T( UnitPosition ) + self:T3( UnitPosition ) return UnitPosition end @@ -546,13 +589,13 @@ end -- @return DCSTypes#Vec3 The velocity vector -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetVelocity() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitVelocityVec3 = DCSUnit:getVelocity() - self:T( UnitVelocityVec3 ) + self:T3( UnitVelocityVec3 ) return UnitVelocityVec3 end @@ -564,13 +607,13 @@ end -- @return #boolean true if in the air. -- @return #nil The DCS Unit is not existing or alive. function UNIT:InAir() - self:F( self.UnitName ) + self:F2( self.UnitName ) local DCSUnit = self:GetDCSUnit() if DCSUnit then local UnitInAir = DCSUnit:inAir() - self:T( UnitInAir ) + self:T3( UnitInAir ) return UnitInAir end @@ -582,7 +625,7 @@ end -- @return DCSTypes#Distance The altitude of the DCS Unit. -- @return #nil The DCS Unit is not existing or alive. function UNIT:GetAltitude() - self:F() + self:F2() local DCSUnit = self:GetDCSUnit() @@ -601,7 +644,7 @@ end -- @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:F( { self.UnitName, AwaitUnit.UnitName, Radius } ) + self:F2( { self.UnitName, AwaitUnit.UnitName, Radius } ) local DCSUnit = self:GetDCSUnit() @@ -610,10 +653,10 @@ function UNIT:OtherUnitInRadius( AwaitUnit, Radius ) local AwaitUnitPos = AwaitUnit:GetPointVec3() if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then - self:T( "true" ) + self:T3( "true" ) return true else - self:T( "false" ) + self:T3( "false" ) return false end end @@ -638,77 +681,77 @@ end --- Signal a flare at the position of the UNIT. -- @param #UNIT self function UNIT:Flare( FlareColor ) - self:F() + 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() + 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() + 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() + 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() + self:F2() trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Red, 0 ) end --- Smoke the UNIT. -- @param #UNIT self function UNIT:Smoke( SmokeColor ) - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), SmokeColor ) end --- Smoke the UNIT Green. -- @param #UNIT self function UNIT:SmokeGreen() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Green ) end --- Smoke the UNIT Red. -- @param #UNIT self function UNIT:SmokeRed() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Red ) end --- Smoke the UNIT White. -- @param #UNIT self function UNIT:SmokeWhite() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.White ) end --- Smoke the UNIT Orange. -- @param #UNIT self function UNIT:SmokeOrange() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Orange ) end --- Smoke the UNIT Blue. -- @param #UNIT self function UNIT:SmokeBlue() - self:F() + self:F2() trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Blue ) end @@ -719,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 index fbb0df741..62b627f62 100644 Binary files a/Presentations/DCS World - MOOSE - Development - Part 3 - The DATABASE - UNIT - CLIENT - GROUP - ZONE, .pptx 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_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 2c514f752..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..3ba158dad Binary files /dev/null and b/Test Missions/Moose_Test_WRAPPER/Moose_Test_WRAPPER.miz differ
    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.

    Spawn

    Dynamic spawning of groups (and units).

    +
    StaticObject +
    Zone

    ZONE Classes

    +
    env + +
    land +