diff --git a/Documentation/Base.html b/Documentation/Base.html index 53a908d0f..c691d7457 100644 --- a/Documentation/Base.html +++ b/Documentation/Base.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/CARGO.html b/Documentation/CARGO.html index 30d778ea2..dbce3e8d9 100644 --- a/Documentation/CARGO.html +++ b/Documentation/CARGO.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -213,6 +201,8 @@

    Type CARGO

    +

    Type CARGO_ZONE

    + diff --git a/Documentation/CLEANUP.html b/Documentation/CLEANUP.html index 4d2aa04a7..6946d1aa9 100644 --- a/Documentation/CLEANUP.html +++ b/Documentation/CLEANUP.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Client.html b/Documentation/Client.html index 6ea751dae..f19da4d0b 100644 --- a/Documentation/Client.html +++ b/Documentation/Client.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -68,8 +56,20 @@

    The CLIENT models client units in multi player missions.

    -

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

    + +

    #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.

    + +

    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:

    + +

    Global(s)

    @@ -77,12 +77,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. CLIENT - - - -
    -
    ClientGroupUnit -
    @@ -158,12 +152,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. CLIENT.ClientGroupUnit - - - - CLIENT.ClientID - - @@ -224,12 +212,36 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. CLIENT:GetDCSGroup()

    Return the DCSGroup of a Client.

    + + + + CLIENT:GetID() + + + + + + CLIENT:GetName() + + CLIENT:GetPointVec2()

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

    + + + + CLIENT:GetPositionVec3() + + + + + + CLIENT:GetTypeName() + + @@ -289,7 +301,7 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. CLIENT:New(ClientName, ClientBriefing) -

    Use this method to register new Clients within the MOF.

    +

    Use this method to register new Clients within a mission.

    @@ -355,20 +367,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. - -
    -
    - - - -ClientGroupUnit - -
    -
    - - -

    Type Client

    @@ -538,6 +536,7 @@ Function.

    + CLIENT.ClientGroupID @@ -565,7 +564,6 @@ Function.

    - CLIENT.ClientGroupUnit @@ -574,20 +572,6 @@ Function.

    - -
    -
    -
    - - - -CLIENT.ClientID - -
    -
    - - -
    @@ -759,6 +743,32 @@ Function.

    DCSGroup#Group:

    + +
    +
    +
    + + +CLIENT:GetID() + +
    +
    + + + +
    +
    +
    +
    + + +CLIENT:GetName() + +
    +
    + + +
    @@ -777,6 +787,32 @@ Function.

    DCSTypes#Vec2:

    + +
    +
    +
    + + +CLIENT:GetPositionVec3() + +
    +
    + + + +
    +
    +
    +
    + + +CLIENT:GetTypeName() + +
    +
    + + +
    @@ -958,14 +994,14 @@ is the interval in seconds between the display of the CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/DESTROYBASETASK.html b/Documentation/DESTROYBASETASK.html index e239668bd..32d486ea6 100644 --- a/Documentation/DESTROYBASETASK.html +++ b/Documentation/DESTROYBASETASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/DESTROYGROUPSTASK.html b/Documentation/DESTROYGROUPSTASK.html index 0307805d5..01411a4f9 100644 --- a/Documentation/DESTROYGROUPSTASK.html +++ b/Documentation/DESTROYGROUPSTASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/DESTROYRADARSTASK.html b/Documentation/DESTROYRADARSTASK.html index 26d37714a..6cb878888 100644 --- a/Documentation/DESTROYRADARSTASK.html +++ b/Documentation/DESTROYRADARSTASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/DESTROYUNITTYPESTASK.html b/Documentation/DESTROYUNITTYPESTASK.html index 48e9b5d50..9890c4507 100644 --- a/Documentation/DESTROYUNITTYPESTASK.html +++ b/Documentation/DESTROYUNITTYPESTASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Database.html b/Documentation/Database.html index 33e0e3f55..8192f0de6 100644 --- a/Documentation/Database.html +++ b/Documentation/Database.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -151,25 +139,19 @@ The following iterator methods are currently available within the DATABASE:

    Type DATABASE

    - - - - - + - + @@ -253,9 +235,27 @@ The following iterator methods are currently available within the DATABASE:

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

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

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

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

    + + + + @@ -334,6 +358,24 @@ The following iterator methods are currently available within the DATABASE:

    + + + + + + + + + + + + @@ -346,12 +388,24 @@ The following iterator methods are currently available within the DATABASE:

    + + + + + + + +
    DATABASE.AlivePlayers - -
    DATABASE.ClassName
    DATABASE.ClientsByIDDATABASE.Clients
    DATABASE.ClientsByNameDATABASE.ClientsAlive
    DATABASE:ForEachAliveUnit(IteratorFunction, ...)DATABASE:ForEach(IteratorFunction, arg, Set) +

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

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

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

    +
    DATABASE:ForEachDCSUnitAlive(IteratorFunction, ...)

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

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

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

    DATABASE.Groups +
    DATABASE.GroupsAlive +
    DATABASE.Players +
    DATABASE.PlayersAlive +
    DATABASE.Statics +
    DATABASE.Templates +
    DATABASE.Units +
    DATABASE.UnitsAlive +
    DATABASE:_EventOnDeadOrCrash(Event)

    Handles the OnDead or OnCrash event for alive units set.

    +
    DATABASE:_EventOnPlayerEnterUnit(Event) +

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

    +
    DATABASE:_EventOnPlayerLeaveUnit(Event) +

    Handles the OnPlayerLeaveUnit event to clean the active players table.

    +
    DATABASE:_IsAliveDCSGroup(DCSGroup) +
    DATABASE:_IsIncludeDCSUnit(DCSUnit) +
    DATABASE:_RegisterDatabase() +

    Private method that registers all datapoints within in the mission.

    DATABASE:_RegisterGroup(GroupTemplate) -

    Registers new Group Templates within the DATABASE Object.

    +

    Private method that registers new Group Templates within the DATABASE Object.

    +
    DATABASE:_RegisterPlayers() +

    Private method that registers all alive players in the mission.

    @@ -381,20 +435,6 @@ The following iterator methods are currently available within the DATABASE:

    - - -DATABASE.AlivePlayers - -
    -
    - - - -
    -
    -
    -
    - #string DATABASE.ClassName @@ -410,8 +450,8 @@ The following iterator methods are currently available within the DATABASE:

    - -DATABASE.ClientsByID + +DATABASE.Clients
    @@ -424,8 +464,8 @@ The following iterator methods are currently available within the DATABASE:

    - -DATABASE.ClientsByName + +DATABASE.ClientsAlive
    @@ -719,8 +759,77 @@ self

    - -DATABASE:ForEachAliveUnit(IteratorFunction, ...) + +DATABASE:ForEach(IteratorFunction, arg, Set) + +
    +
    + +

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

    + +

    Parameters

    +
      +
    • + +

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

      + +
    • +
    • + +

      arg :

      + +
    • +
    • + +

      Set :

      + +
    • +
    +

    Return value

    + +

    #DATABASE: +self

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

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

    + +

    Parameters

    +
      +
    • + +

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

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #DATABASE: +self

    + +
    +
    +
    +
    + + +DATABASE:ForEachDCSUnitAlive(IteratorFunction, ...)
    @@ -751,6 +860,38 @@ self

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

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

    + +

    Parameters

    +
      +
    • + +

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

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #DATABASE: +self

    + +
    +
    +
    +
    + DATABASE:GetStatusGroup(GroupName) @@ -781,6 +922,20 @@ self

    +
    +
    +
    +
    + + + +DATABASE.GroupsAlive + +
    +
    + + +
    @@ -831,6 +986,20 @@ DBObject = DATABASE:New() +
    +
    +
    +
    + + + +DATABASE.PlayersAlive + +
    +
    + + +
    @@ -892,10 +1061,15 @@ This method is used by the SPAWN class.

    • -

      SpawnTemplate :

      +

      #table SpawnTemplate :

    +

    Return value

    + +

    #DATABASE: +self

    +
    @@ -910,6 +1084,20 @@ This method is used by the SPAWN class.

    + +
    +
    +
    + + + +DATABASE.Templates + +
    +
    + + +
    @@ -945,6 +1133,20 @@ self

    + +
    +
    +
    + + + +DATABASE.UnitsAlive + +
    +
    + + +
    @@ -992,6 +1194,74 @@ self

    + +DATABASE:_EventOnPlayerEnterUnit(Event) + +
    +
    + +

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

    + +

    Parameter

    + +
    +
    +
    +
    + + +DATABASE:_EventOnPlayerLeaveUnit(Event) + +
    +
    + +

    Handles the OnPlayerLeaveUnit event to clean the active players table.

    + +

    Parameter

    + +
    +
    +
    +
    + + +DATABASE:_IsAliveDCSGroup(DCSGroup) + +
    +
    + + + +

    Parameter

    + +

    Return value

    + +

    #DATABASE: +self

    + +
    +
    +
    +
    + DATABASE:_IsAliveDCSUnit(DCSUnit) @@ -1044,22 +1314,63 @@ self

    + +DATABASE:_RegisterDatabase() + +
    +
    + +

    Private method that registers all datapoints within in the mission.

    + +

    Return value

    + +

    #DATABASE: +self

    + +
    +
    +
    +
    + DATABASE:_RegisterGroup(GroupTemplate)
    -

    Registers new Group Templates within the DATABASE Object.

    +

    Private method that registers new Group Templates within the DATABASE Object.

    Parameter

    • -

      GroupTemplate :

      +

      #table GroupTemplate :

    +

    Return value

    + +

    #DATABASE: +self

    + +
    +
    +
    +
    + + +DATABASE:_RegisterPlayers() + +
    +
    + +

    Private method that registers all alive players in the mission.

    + +

    Return value

    + +

    #DATABASE: +self

    +
    diff --git a/Documentation/Escort.html b/Documentation/Escort.html index d38a27767..b1fe8f549 100644 --- a/Documentation/Escort.html +++ b/Documentation/Escort.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Event.html b/Documentation/Event.html index eaa58b863..b05cb6788 100644 --- a/Documentation/Event.html +++ b/Documentation/Event.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -232,6 +220,18 @@ EVENT:OnPilotDeadForUnit(EventDCSUnitName, EventFunction, EventSelf)

    Set a new listener for an SEVENTPILOT_DEAD event.

    + + + + EVENT:OnPlayerEnterUnit(EventFunction, EventSelf) + +

    Set a new listener for an SEVENTPLAYERENTERUNIT event.

    + + + + EVENT:OnPlayerLeaveUnit(EventFunction, EventSelf) + +

    Set a new listener for an SEVENTPLAYERLEAVEUNIT event.

    @@ -1259,6 +1259,72 @@ The self instance of the class for which the event is.

    #EVENT:

    + +
    +
    +
    + + +EVENT:OnPlayerEnterUnit(EventFunction, EventSelf) + +
    +
    + +

    Set a new listener for an SEVENTPLAYERENTERUNIT event.

    + +

    Parameters

    +
      +
    • + +

      #function EventFunction : +The function to be called when the event occurs for the unit.

      + +
    • +
    • + +

      Base#BASE EventSelf : +The self instance of the class for which the event is.

      + +
    • +
    +

    Return value

    + +

    #EVENT:

    + + +
    +
    +
    +
    + + +EVENT:OnPlayerLeaveUnit(EventFunction, EventSelf) + +
    +
    + +

    Set a new listener for an SEVENTPLAYERLEAVEUNIT event.

    + +

    Parameters

    +
      +
    • + +

      #function EventFunction : +The function to be called when the event occurs for the unit.

      + +
    • +
    • + +

      Base#BASE EventSelf : +The self instance of the class for which the event is.

      + +
    • +
    +

    Return value

    + +

    #EVENT:

    + +
    diff --git a/Documentation/GOHOMETASK.html b/Documentation/GOHOMETASK.html index b1ebecdcd..4b63dc32e 100644 --- a/Documentation/GOHOMETASK.html +++ b/Documentation/GOHOMETASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Group.html b/Documentation/Group.html index 3298e9321..be3012b46 100644 --- a/Documentation/Group.html +++ b/Documentation/Group.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -113,6 +101,12 @@ GROUP:CommandDoScript(DoScript)

    Do Script command

    + + + + GROUP:CommandSwitchWayPoint(FromWayPoint, ToWayPoint, Index) + +

    Perform a switch waypoint command

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

    GROUP:GetName() -

    Gets the name of the GROUP.

    +

    Returns the name of the Group.

    @@ -462,12 +456,24 @@ Note that this destroy method also raises a destroy event at run-time.

    GROUP:Route(GoPoints)

    Make the group to follow a given route.

    + + + + GROUP:SetCommand(DCSCommand) + +

    Executes a command action

    GROUP:SetTask(DCSTask, WaitTime)

    Clearing the Task Queue and Setting the Task on the queue from the group.

    + + + + GROUP:TaskAttackGroup(AttackGroup) + +

    Attack a Group.

    @@ -751,6 +757,42 @@ All units on the ground result.

    #DCSCommand:

    + +
    +
    +
    + + +GROUP:CommandSwitchWayPoint(FromWayPoint, ToWayPoint, Index) + +
    +
    + +

    Perform a switch waypoint command

    + +

    Parameters

    +
      +
    • + +

      #number FromWayPoint :

      + +
    • +
    • + +

      #number ToWayPoint :

      + +
    • +
    • + +

      Index :

      + +
    • +
    +

    Return value

    + +

    DCSTask#Task:

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

    -

    Gets the name of the GROUP.

    +

    Returns the name of the Group.

    Return value

    #string: -The name of the GROUP.

    +GroupName

    @@ -1975,6 +2017,32 @@ self

    + +GROUP:SetCommand(DCSCommand) + +
    +
    + +

    Executes a command action

    + +

    Parameter

    + +

    Return value

    + +

    #GROUP: +self

    + +
    +
    +
    +
    + GROUP:SetTask(DCSTask, WaitTime) @@ -2006,6 +2074,33 @@ self

    + +GROUP:TaskAttackGroup(AttackGroup) + +
    +
    + +

    Attack a Group.

    + +

    Parameter

    +
      +
    • + +

      Group#GROUP AttackGroup : +The Group to be attacked.

      + +
    • +
    +

    Return value

    + +

    DCSTask#Task: +The DCS task structure.

    + +
    +
    +
    +
    + GROUP:TaskAttackUnit(The, AttackUnit) diff --git a/Documentation/MISSION.html b/Documentation/MISSION.html index 81752775f..9de091e4d 100644 --- a/Documentation/MISSION.html +++ b/Documentation/MISSION.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/MOVEMENT.html b/Documentation/MOVEMENT.html index 1fd0bfce1..98df22b0c 100644 --- a/Documentation/MOVEMENT.html +++ b/Documentation/MOVEMENT.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Menu.html b/Documentation/Menu.html index a82742975..58ccee4f5 100644 --- a/Documentation/Menu.html +++ b/Documentation/Menu.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -91,6 +79,18 @@ MENU_CLIENT_COMMAND + + + + MENU_COALITION + + + + + + MENU_COALITION_COMMAND + + @@ -208,6 +208,56 @@ MENU_CLIENT_COMMAND:Remove() + + + + +

    Type MENU_COALITION

    + + + + + + + + + + + + + + + + + +
    MENU_COALITION.ClassName + +
    MENU_COALITION:New(MenuCoalition, MenuText, ParentMenu) +

    Creates a new coalition menu item

    +
    MENU_COALITION:Remove() +

    Removes the sub menus recursively of this MENU_COALITION.

    +
    MENU_COALITION:RemoveSubMenus() +

    Removes the sub menus recursively of this MENU_COALITION.

    +
    + +

    Type MENU_COALITION_COMMAND

    + + + + + + + + + + + +
    MENU_COALITION_COMMAND.ClassName + +
    MENU_COALITION_COMMAND:New(MenuCoalition, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument) +

    Creates a new radio command item for a group

    +
    MENU_COALITION_COMMAND:Remove() +

    Removes a radio command item for a coalition

    @@ -283,6 +333,34 @@ + +
    +
    +
    + + #MENU_COALITION + +MENU_COALITION + +
    +
    + + + +
    +
    +
    +
    + + #MENU_COALITION_COMMAND + +MENU_COALITION_COMMAND + +
    +
    + + +
    @@ -645,6 +723,190 @@ self

    + +
    + +

    Type MENU_COALITION

    + +

    The MENU_COALITION class

    + +

    Field(s)

    +
    +
    + + #string + +MENU_COALITION.ClassName + +
    +
    + + + +
    +
    +
    +
    + + +MENU_COALITION:New(MenuCoalition, MenuText, ParentMenu) + +
    +
    + +

    Creates a new coalition menu item

    + +

    Parameters

    +
      +
    • + +

      DCSCoalition#coalition.side MenuCoalition : +The coalition owning the menu.

      + +
    • +
    • + +

      #string MenuText : +The text for the menu.

      + +
    • +
    • + +

      #table ParentMenu : +The parent menu.

      + +
    • +
    +

    Return value

    + +

    #MENU_COALITION: +self

    + +
    +
    +
    +
    + + +MENU_COALITION:Remove() + +
    +
    + +

    Removes the sub menus recursively of this MENU_COALITION.

    + +

    Return value

    + +

    #MENU_COALITION: +self

    + +
    +
    +
    +
    + + +MENU_COALITION:RemoveSubMenus() + +
    +
    + +

    Removes the sub menus recursively of this MENU_COALITION.

    + +

    Return value

    + +

    #MENU_COALITION: +self

    + +
    +
    + +

    Type MENU_COALITION_COMMAND

    + +

    The MENUCOALITIONCOMMAND class

    + +

    Field(s)

    +
    +
    + + #string + +MENU_COALITION_COMMAND.ClassName + +
    +
    + + + +
    +
    +
    +
    + + +MENU_COALITION_COMMAND:New(MenuCoalition, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument) + +
    +
    + +

    Creates a new radio command item for a group

    + +

    Parameters

    +
      +
    • + +

      DCSCoalition#coalition.side MenuCoalition : +The coalition owning the menu.

      + +
    • +
    • + +

      MenuText : +The text for the menu.

      + +
    • +
    • + +

      ParentMenu : +The parent menu.

      + +
    • +
    • + +

      CommandMenuFunction : +A function that is called when the menu key is pressed.

      + +
    • +
    • + +

      CommandMenuArgument : +An argument for the function.

      + +
    • +
    +

    Return value

    + +

    #MENUCOALITIONCOMMAND: +self

    + +
    +
    +
    +
    + + +MENU_COALITION_COMMAND:Remove() + +
    +
    + +

    Removes a radio command item for a coalition

    + +

    Return value

    + +

    #MENUCOALITIONCOMMAND: +self

    +
    diff --git a/Documentation/Message.html b/Documentation/Message.html index 66c9d6c91..dd4087bf7 100644 --- a/Documentation/Message.html +++ b/Documentation/Message.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/MissileTrainer.html b/Documentation/MissileTrainer.html new file mode 100644 index 000000000..3ad2d3679 --- /dev/null +++ b/Documentation/MissileTrainer.html @@ -0,0 +1,884 @@ + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +

    Module MissileTrainer

    + +

    Provides missile training functions.

    + + + +

    #MISSILETRAINER class

    +

    The #MISSILETRAINER class uses the DCS world messaging system to be alerted of any missiles fired, and when a missile would hit your aircraft, +the class will destroy the missile within a certain range, to avoid damage to your aircraft. +It suports the following functionality:

    + +
      +
    • Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes.
    • +
    • Provide alerts of missile launches, including detailed information of the units launching, including bearing, range …
    • +
    • Provide alerts when a missile would have killed your aircraft.
    • +
    • Provide alerts when the missile self destructs.
    • +
    • Enable / Disable and Configure the Missile Trainer using the various menu options.
    • +
    + +

    When running a mission where MISSILETRAINER is used, the following radio menu structure ( 'Radio Menu' -> 'Other (F10)' -> 'MissileTrainer' ) options are available for the players:

    + +
      +
    • Messages: Menu to configure all messages. +
        +
      • Messages On: Show all messages.
      • +
      • Messages Off: Disable all messages.
      • +
    • +
    • Tracking: Menu to configure missile tracking messages. +
        +
      • To All: Shows missile tracking messages to all players.
      • +
      • To Target: Shows missile tracking messages only to the player where the missile is targetted at.
      • +
      • Tracking On: Show missile tracking messages.
      • +
      • Tracking Off: Disable missile tracking messages.
      • +
    • +
    • Alerts: Menu to configure alert messages. +
        +
      • To All: Shows alert messages to all players.
      • +
      • To Target: Shows alter messages only to the player where the missile is (was) targetted at.
      • +
      • Hits On: Show missile hit alert messages.
      • +
      • Hits Off: Disable missile hit altert messages.
      • +
      • Launches On: Show missile launch messages.
      • +
      • Launches Off: Disable missile launch messages.
      • +
    • +
    • Details: Menu to configure message details. +
        +
      • Range On: Shows range information when a missile is fired to a target.
      • +
      • Range Off: Disable range information when a missile is fired to a target.
      • +
      • Bearing On: Shows bearing information when a missile is fired to a target.
      • +
      • Bearing Off: Disable bearing information when a missile is fired to a target.
      • +
    • +
    • Distance: Menu to configure the distance when a missile needs to be destroyed when near to a player, during tracking. + This will improve/influence hit calculation accuracy, but has the risk of damaging the aircraft when the missile reaches the aircraft before the distance is measured. +
        +
      • 50 meter: Destroys the missile when the distance to the aircraft is below or equal to 50 meter.
      • +
      • 100 meter: Destroys the missile when the distance to the aircraft is below or equal to 100 meter.
      • +
      • 150 meter: Destroys the missile when the distance to the aircraft is below or equal to 150 meter.
      • +
      • 200 meter: Destroys the missile when the distance to the aircraft is below or equal to 200 meter.
      • +
    • +
    + + +

    MISSILETRAINER construction methods:

    +

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

    + +
      +
    • MISSILETRAINER.New: Creates a new MISSILETRAINER object taking the maximum distance to your aircraft to evaluate when a missile needs to be destroyed.
    • +
    + +

    MISSILETRAINER will collect each unit declared in the mission with a skill level "Client" and "Player", and will monitor the missiles shot at those.

    + +

    MISSILETRAINER initialization methods:

    +

    A MISSILETRAINER object will behave differently based on the usage of initialization methods:

    + + + + +

    Global(s)

    + + + + + +
    MISSILETRAINER + +
    +

    Type MISSILETRAINER

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    MISSILETRAINER.AlertsHitsOnOff + +
    MISSILETRAINER.AlertsLaunchesOnOff + +
    MISSILETRAINER.AlertsToAll + +
    MISSILETRAINER.ClassName + +
    MISSILETRAINER.DetailsBearingOnOff + +
    MISSILETRAINER.DetailsRangeOnOff + +
    MISSILETRAINER:InitAlertsHitsOnOff(AlertsHitsOnOff) +

    Sets by default the display of hit alerts ON or OFF.

    +
    MISSILETRAINER:InitAlertsLaunchesOnOff(AlertsLaunchesOnOff) +

    Sets by default the display of launch alerts ON or OFF.

    +
    MISSILETRAINER:InitAlertsToAll(AlertsToAll) +

    Sets by default the display of alerts to be shown to all players or only to you.

    +
    MISSILETRAINER:InitBearingOnOff(DetailsBearingOnOff) +

    Sets by default the display of bearing information of missiles ON of OFF.

    +
    MISSILETRAINER:InitMenusOnOff(MenusOnOff) +

    Enables / Disables the menus.

    +
    MISSILETRAINER:InitMessagesOnOff(MessagesOnOff) +

    Sets by default the display of any message to be ON or OFF.

    +
    MISSILETRAINER:InitRangeOnOff(DetailsRangeOnOff) +

    Sets by default the display of range information of missiles ON of OFF.

    +
    MISSILETRAINER:InitTrackingOnOff(TrackingOnOff) +

    Sets by default the display of missile tracking report to be ON or OFF.

    +
    MISSILETRAINER:InitTrackingToAll(TrackingToAll) +

    Sets by default the missile tracking report for all players or only for those missiles targetted to you.

    +
    MISSILETRAINER.MenusOnOff + +
    MISSILETRAINER.MessageLastTime + +
    MISSILETRAINER.MessagesOnOff + +
    MISSILETRAINER.New(#, Distance, self) +

    Creates the main object which is handling missile tracking.

    +
    MISSILETRAINER.TrackingOnOff + +
    MISSILETRAINER.TrackingToAll + +
    MISSILETRAINER:_AddBearing(Client, TrainerWeapon) + +
    MISSILETRAINER:_AddRange(Client, TrainerWeapon) + +
    MISSILETRAINER:_EventShot(Event) +

    Detects if an SA site was shot with an anti radiation missile.

    +
    MISSILETRAINER._MenuMessages(MenuParameters) + +
    MISSILETRAINER:_TrackMissiles() + +
    + +

    Global(s)

    +
    +
    + + #MISSILETRAINER + +MISSILETRAINER + +
    +
    + + + +
    +
    +

    Type MissileTrainer

    + +

    Type MISSILETRAINER

    + +

    The MISSILETRAINER class

    + +

    Field(s)

    +
    +
    + + + +MISSILETRAINER.AlertsHitsOnOff + +
    +
    + + + +
    +
    +
    +
    + + + +MISSILETRAINER.AlertsLaunchesOnOff + +
    +
    + + + +
    +
    +
    +
    + + + +MISSILETRAINER.AlertsToAll + +
    +
    + + + +
    +
    +
    +
    + + #string + +MISSILETRAINER.ClassName + +
    +
    + + + +
    +
    +
    +
    + + + +MISSILETRAINER.DetailsBearingOnOff + +
    +
    + + + +
    +
    +
    +
    + + + +MISSILETRAINER.DetailsRangeOnOff + +
    +
    + + + +
    +
    +
    +
    + + +MISSILETRAINER:InitAlertsHitsOnOff(AlertsHitsOnOff) + +
    +
    + +

    Sets by default the display of hit alerts ON or OFF.

    + +

    Parameter

    +
      +
    • + +

      #boolean AlertsHitsOnOff : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitAlertsLaunchesOnOff(AlertsLaunchesOnOff) + +
    +
    + +

    Sets by default the display of launch alerts ON or OFF.

    + +

    Parameter

    +
      +
    • + +

      #boolean AlertsLaunchesOnOff : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitAlertsToAll(AlertsToAll) + +
    +
    + +

    Sets by default the display of alerts to be shown to all players or only to you.

    + +

    Parameter

    +
      +
    • + +

      #boolean AlertsToAll : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitBearingOnOff(DetailsBearingOnOff) + +
    +
    + +

    Sets by default the display of bearing information of missiles ON of OFF.

    + +

    Parameter

    +
      +
    • + +

      #boolean DetailsBearingOnOff : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitMenusOnOff(MenusOnOff) + +
    +
    + +

    Enables / Disables the menus.

    + +

    Parameter

    +
      +
    • + +

      #boolean MenusOnOff : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitMessagesOnOff(MessagesOnOff) + +
    +
    + +

    Sets by default the display of any message to be ON or OFF.

    + +

    Parameter

    +
      +
    • + +

      #boolean MessagesOnOff : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitRangeOnOff(DetailsRangeOnOff) + +
    +
    + +

    Sets by default the display of range information of missiles ON of OFF.

    + +

    Parameter

    +
      +
    • + +

      #boolean DetailsRangeOnOff : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitTrackingOnOff(TrackingOnOff) + +
    +
    + +

    Sets by default the display of missile tracking report to be ON or OFF.

    + +

    Parameter

    +
      +
    • + +

      #boolean TrackingOnOff : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + +MISSILETRAINER:InitTrackingToAll(TrackingToAll) + +
    +
    + +

    Sets by default the missile tracking report for all players or only for those missiles targetted to you.

    + +

    Parameter

    +
      +
    • + +

      #boolean TrackingToAll : +true or false

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER: +self

    + +
    +
    +
    +
    + + + +MISSILETRAINER.MenusOnOff + +
    +
    + + + +
    +
    +
    +
    + + + +MISSILETRAINER.MessageLastTime + +
    +
    + + + +
    +
    +
    +
    + + + +MISSILETRAINER.MessagesOnOff + +
    +
    + + + +
    +
    +
    +
    + + +MISSILETRAINER.New(#, Distance, self) + +
    +
    + +

    Creates the main object which is handling missile tracking.

    + + +

    When a missile is fired a SCHEDULER is set off that follows the missile. When near a certain a client player, the missile will be destroyed.

    + +

    Parameters

    +
      +
    • + +

      # : +ISSILETRAINER

      + +
    • +
    • + +

      #number Distance : +The distance in meters when a tracked missile needs to be destroyed when close to a player.

      + +
    • +
    • + +

      self :

      + +
    • +
    +

    Return value

    + +

    #MISSILETRAINER:

    + + +
    +
    +
    +
    + + + +MISSILETRAINER.TrackingOnOff + +
    +
    + + + +
    +
    +
    +
    + + + +MISSILETRAINER.TrackingToAll + +
    +
    + + + +
    +
    +
    +
    + + +MISSILETRAINER:_AddBearing(Client, TrainerWeapon) + +
    +
    + + + +

    Parameters

    +
      +
    • + +

      Client :

      + +
    • +
    • + +

      TrainerWeapon :

      + +
    • +
    +
    +
    +
    +
    + + +MISSILETRAINER:_AddRange(Client, TrainerWeapon) + +
    +
    + + + +

    Parameters

    +
      +
    • + +

      Client :

      + +
    • +
    • + +

      TrainerWeapon :

      + +
    • +
    +
    +
    +
    +
    + + +MISSILETRAINER:_EventShot(Event) + +
    +
    + +

    Detects if an SA site was shot with an anti radiation missile.

    + + +

    In this case, take evasive actions based on the skill level set within the ME.

    + +

    Parameter

    + +
    +
    +
    +
    + + +MISSILETRAINER._MenuMessages(MenuParameters) + +
    +
    + + + +

    Parameter

    +
      +
    • + +

      MenuParameters :

      + +
    • +
    +
    +
    +
    +
    + + +MISSILETRAINER:_TrackMissiles() + +
    +
    + + + +
    +
    + +
    + +
    + + diff --git a/Documentation/NOTASK.html b/Documentation/NOTASK.html index 4fa604429..d49ebedf5 100644 --- a/Documentation/NOTASK.html +++ b/Documentation/NOTASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/PICKUPTASK.html b/Documentation/PICKUPTASK.html index e9fcbf698..d888999c0 100644 --- a/Documentation/PICKUPTASK.html +++ b/Documentation/PICKUPTASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/ROUTETASK.html b/Documentation/ROUTETASK.html index 87dc106be..c95432e3e 100644 --- a/Documentation/ROUTETASK.html +++ b/Documentation/ROUTETASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/STAGE.html b/Documentation/STAGE.html index bc38980e4..fd2ceedc0 100644 --- a/Documentation/STAGE.html +++ b/Documentation/STAGE.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Scheduler.html b/Documentation/Scheduler.html new file mode 100644 index 000000000..10a410720 --- /dev/null +++ b/Documentation/Scheduler.html @@ -0,0 +1,237 @@ + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +

    Module Scheduler

    + +

    Models time events calling event handing functions.

    + +

    Global(s)

    + + + + + +
    SCHEDULER + +
    +

    Type SCHEDULER

    + + + + + + + + + + + + + + + + + + + + + +
    SCHEDULER.ClassName + +
    SCHEDULER:New(TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds) +

    SCHEDULER constructor.

    +
    SCHEDULER:Scheduler() + +
    SCHEDULER:Start() + +
    SCHEDULER:Stop() + +
    + +

    Global(s)

    +
    +
    + + #SCHEDULER + +SCHEDULER + +
    +
    + + + +
    +
    +

    Type Scheduler

    + +

    Type SCHEDULER

    + +

    The SCHEDULER class

    + +

    Field(s)

    +
    +
    + + #string + +SCHEDULER.ClassName + +
    +
    + + + +
    +
    +
    +
    + + +SCHEDULER:New(TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds) + +
    +
    + +

    SCHEDULER constructor.

    + +

    Parameters

    +
      +
    • + +

      #table TimeEventObject :

      + +
    • +
    • + +

      #function TimeEventFunction :

      + +
    • +
    • + +

      #table TimeEventFunctionArguments :

      + +
    • +
    • + +

      #number StartSeconds :

      + +
    • +
    • + +

      #number RepeatSecondsInterval :

      + +
    • +
    • + +

      #number RandomizationFactor :

      + +
    • +
    • + +

      #number StopSeconds :

      + +
    • +
    +

    Return value

    + +

    #SCHEDULER:

    + + +
    +
    +
    +
    + + +SCHEDULER:Scheduler() + +
    +
    + + + +
    +
    +
    +
    + + +SCHEDULER:Start() + +
    +
    + + + +
    +
    +
    +
    + + +SCHEDULER:Stop() + +
    +
    + + + +
    +
    + +
    + +
    + + diff --git a/Documentation/Scoring.html b/Documentation/Scoring.html index b70b673fb..34d058056 100644 --- a/Documentation/Scoring.html +++ b/Documentation/Scoring.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Sead.html b/Documentation/Sead.html index 95c47ee9e..d4631a922 100644 --- a/Documentation/Sead.html +++ b/Documentation/Sead.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Spawn.html b/Documentation/Spawn.html index cef33f470..2f5ba12ef 100644 --- a/Documentation/Spawn.html +++ b/Documentation/Spawn.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -116,7 +104,7 @@ So in principle, the group list will contain all parameters and configurations a
  • SPAWN.RandomizeTemplate: Randomize the group templates so that when a new group is spawned, a random group template is selected from one of the templates defined.
  • SPAWN.Uncontrolled: Spawn plane groups uncontrolled.
  • SPAWN.Array: Make groups visible before they are actually activated, and order these groups like a batallion in an array.
  • -
  • SPAWN.Repeat: Re-spawn groups when they land at the home base. Similar functions are SPAWN.RepeatOnLanding and SPAWN.RepeatOnEngineShutDown.
  • +
  • SPAWN.InitRepeat: Re-spawn groups when they land at the home base. Similar functions are SPAWN.InitRepeatOnLanding and SPAWN.InitRepeatOnEngineShutDown.
  • SPAWN spawning methods:

    @@ -158,12 +146,6 @@ Check the SPAWN.CleanUp for further info.

    Type SPAWN

    - - - - - + @@ -215,6 +197,24 @@ Check the SPAWN.CleanUp for further info.

    + + + + + + + + + + + + @@ -254,9 +254,9 @@ Check the SPAWN.CleanUp for further info.

    - + @@ -293,12 +293,6 @@ Check the SPAWN.CleanUp for further info.

    - - - - @@ -329,24 +323,12 @@ Check the SPAWN.CleanUp for further info.

    - - - - - - - - @@ -389,18 +371,12 @@ Check the SPAWN.CleanUp for further info.

    - - - - @@ -416,7 +392,7 @@ Check the SPAWN.CleanUp for further info.

    - + @@ -550,13 +526,13 @@ Check the SPAWN.CleanUp for further info.

    @@ -604,20 +580,6 @@ Check the SPAWN.CleanUp for further info.

    - #number - -SPAWN.AliveFactor - -
    -
    - - - -
    -
    -
    -
    - SPAWN:Array(SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY) @@ -721,14 +683,17 @@ self

    - -SPAWN.CleanUpFunction + +SPAWN.CleanUpScheduler
    + +

    self.CleanUpFunction = routines.scheduleFunction( self._SpawnCleanUpScheduler, { self }, timer.getTime() + 1, SpawnCleanUpInterval )

    +
    @@ -876,6 +841,71 @@ When no group is found, #nil is returned.

    + +SPAWN:InitRepeat() + +
    +
    + +

    For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.

    + + +

    This function is used to re-spawn automatically (so no extra call is needed anymore) the same group after it has landed. +This will enable a spawned group to be re-spawned after it lands, until it is destroyed... +Note: When the group is respawned, it will re-spawn from the original airbase where it took off. +So ensure that the routes for groups that respawn, always return to the original airbase, or players may get confused ...

    + +

    Return value

    + +

    #SPAWN: +self

    + +

    Usage:

    +
    -- RU Su-34 - AI Ship Attack
    +-- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically. 
    +SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()
    + +
    +
    +
    +
    + + +SPAWN:InitRepeatOnEngineShutDown() + +
    +
    + +

    Respawn after landing when its engines have shut down.

    + +

    Return value

    + +

    #SPAWN: +self

    + +
    +
    +
    +
    + + +SPAWN:InitRepeatOnLanding() + +
    +
    + +

    Respawn group after landing.

    + +

    Return value

    + +

    #SPAWN: +self

    + +
    +
    +
    +
    + SPAWN:Limit(SpawnMaxUnitsAlive, SpawnMaxGroups) @@ -1123,29 +1153,14 @@ The group that was spawned. You can use this group for further actions.

    + #boolean -SPAWN:Repeat() +SPAWN.Repeat
    -

    For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.

    - -

    This function is used to re-spawn automatically (so no extra call is needed anymore) the same group after it has landed. -This will enable a spawned group to be re-spawned after it lands, until it is destroyed... -Note: When the group is respawned, it will re-spawn from the original airbase where it took off. -So ensure that the routes for groups that respawn, always return to the original airbase, or players may get confused ...

    - -

    Return value

    - -

    #SPAWN: -self

    - -

    Usage:

    -
    -- RU Su-34 - AI Ship Attack
    --- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically. 
    -SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()
    @@ -1238,23 +1253,6 @@ The group that was spawned. You can use this group for further actions.

    - -
    -
    -
    - - #number - -SPAWN.SpawnCurrentTimer - -
    -
    - - - - -

    The internal timer counter to trigger a scheduled spawning of SpawnTemplatePrefix.

    -
    @@ -1412,20 +1410,6 @@ Is the number of the Group that is to be spawned.

    #string: SpawnGroupName

    - -
    -
    -
    - - #number - -SPAWN.SpawnHighTimer - -
    -
    - - -
    @@ -1479,20 +1463,6 @@ when nothing was spawned.

    - -
    -
    -
    - - #number - -SPAWN.SpawnLowTimer - -
    -
    - - -
    @@ -1597,20 +1567,6 @@ when nothing was spawned.

    - -
    -
    -
    - - #boolean - -SPAWN.SpawnRepeat - -
    -
    - - -
    @@ -1622,10 +1578,10 @@ when nothing was spawned.

    -

    Will start the spawning scheduler.

    +

    Will re-start the spawning scheduler.

    -

    Note: This function is called automatically when SPAWN.Scheduled is called.

    +

    Note: This function is only required to be called when the schedule was stopped.

    @@ -1692,18 +1648,15 @@ Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
    - #number - -SPAWN.SpawnSetTimer + + +SPAWN.SpawnScheduler
    - -

    The internal timer value when a scheduled spawning of SpawnTemplatePrefix occurs.

    -
    @@ -2022,10 +1975,15 @@ Nothing found

    • -

      SpawnTemplatePrefix :

      +

      #string SpawnTemplatePrefix :

    +

    Return value

    + + +

    @SPAWN self

    +
    @@ -2184,15 +2142,20 @@ This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.

  • -

    SpawnTemplatePrefix :

    +

    #string SpawnTemplatePrefix :

  • -

    SpawnIndex :

    +

    #number SpawnIndex :

  • +

    Return value

    + +

    #SPAWN: +self

    +
    @@ -2204,7 +2167,7 @@ This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.

    -

    Internal function randomizing the routes.

    +

    Private method randomizing the routes.

    Parameter

      @@ -2231,16 +2194,21 @@ The index of the group to be spawned.

      - +

      Private method that randomizes the template of the group.

      Parameter

      • -

        SpawnIndex :

        +

        #number SpawnIndex :

      +

      Return value

      + +

      #SPAWN: +self

      +
    diff --git a/Documentation/TASK.html b/Documentation/TASK.html index bc244726c..d18c673ff 100644 --- a/Documentation/TASK.html +++ b/Documentation/TASK.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Documentation/Unit.html b/Documentation/Unit.html index 985e6a1e7..ec8a45111 100644 --- a/Documentation/Unit.html +++ b/Documentation/Unit.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -154,6 +142,12 @@
    + + + + @@ -510,6 +504,19 @@ + + +
    +
    + + +UNIT:GetPlayerName() + +
    +
    + + +
    diff --git a/Documentation/Zone.html b/Documentation/Zone.html index 1b9c3cb4b..ca4efd886 100644 --- a/Documentation/Zone.html +++ b/Documentation/Zone.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -88,6 +76,12 @@
    + + + + @@ -157,6 +151,27 @@ + + +
    +
    + + +ZONE:GetPointVec3(Height) + +
    +
    + + + +

    Parameter

    +
      +
    • + +

      Height :

      + +
    • +
    diff --git a/Documentation/index.html b/Documentation/index.html index 0464d0694..6900f9112 100644 --- a/Documentation/index.html +++ b/Documentation/index.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • @@ -87,72 +75,6 @@
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -237,6 +159,12 @@ + + + + @@ -261,6 +189,12 @@ + + + + @@ -279,12 +213,6 @@ - - - - @@ -303,18 +231,6 @@ - - - - - - - - diff --git a/Documentation/routines.html b/Documentation/routines.html index d33caf801..806bd57e3 100644 --- a/Documentation/routines.html +++ b/Documentation/routines.html @@ -21,17 +21,6 @@
  • CARGO
  • CleanUp
  • Client
  • -
  • DCSAirbase
  • -
  • DCSCoalitionObject
  • -
  • DCSCommand
  • -
  • DCSController
  • -
  • DCSGroup
  • -
  • DCSObject
  • -
  • DCSTask
  • -
  • DCSTypes
  • -
  • DCSUnit
  • -
  • DCSWorld
  • -
  • DCStimer
  • DEPLOYTASK
  • DESTROYBASETASK
  • DESTROYGROUPSTASK
  • @@ -46,19 +35,18 @@
  • MOVEMENT
  • Menu
  • Message
  • +
  • MissileTrainer
  • NOTASK
  • PICKUPTASK
  • ROUTETASK
  • STAGE
  • +
  • Scheduler
  • Scoring
  • Sead
  • Spawn
  • -
  • StaticObject
  • TASK
  • Unit
  • Zone
  • -
  • env
  • -
  • land
  • routines
  • diff --git a/Embedded/Moose_Create_Embedded.bat b/Embedded/Moose_Create_Embedded.bat index c4e58833c..673cf37b3 100644 --- a/Embedded/Moose_Create_Embedded.bat +++ b/Embedded/Moose_Create_Embedded.bat @@ -9,12 +9,12 @@ copy /b Moose_Embedded.lua + ..\Moose\Menu.lua Moose_Embedded.l copy /b Moose_Embedded.lua + ..\Moose\Group.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Unit.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Zone.lua Moose_Embedded.lua +copy /b Moose_Embedded.lua + ..\Moose\Client.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Database.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Moose.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Scheduler.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Scoring.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Cargo.lua Moose_Embedded.lua -copy /b Moose_Embedded.lua + ..\Moose\Client.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Message.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Stage.lua Moose_Embedded.lua copy /b Moose_Embedded.lua + ..\Moose\Task.lua Moose_Embedded.lua diff --git a/Embedded/Moose_Embedded.lua b/Embedded/Moose_Embedded.lua index 2ceb43472..c003f0bd0 100644 --- a/Embedded/Moose_Embedded.lua +++ b/Embedded/Moose_Embedded.lua @@ -1738,7 +1738,7 @@ function routines.getGroupRoute(groupIdent, task) -- same as getGroupPoints bu -- refactor to search by groupId and allow groupId and groupName as inputs local gpId = groupIdent if type(groupIdent) == 'string' and not tonumber(groupIdent) then - gpId = _DATABASE.Groups[groupIdent].groupId + gpId = _DATABASE.Templates.Groups[groupIdent].groupId end for coa_name, coa_data in pairs(env.mission.coalition) do @@ -3555,6 +3555,32 @@ function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) return self end +--- Set a new listener for an S_EVENT_PLAYER_ENTER_UNIT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnPlayerEnterUnit( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_ENTER_UNIT ) + + return self +end + +--- Set a new listener for an S_EVENT_PLAYER_LEAVE_UNIT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnPlayerLeaveUnit( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_LEAVE_UNIT ) + + return self +end + function EVENT:onEvent( Event ) @@ -3586,6 +3612,7 @@ function EVENT:onEvent( Event ) Event.WeaponName = Event.Weapon:getTypeName() --Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() end + self:E( { _EVENTCODES[Event.id], Event } ) for ClassName, EventData in pairs( self.Events[Event.id] ) do if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then self:T2( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } ) @@ -5057,7 +5084,7 @@ end function GROUP:GetTaskMission() self:F( self.GroupName ) - return routines.utils.deepCopy( _DATABASE.Groups[self.GroupName].Template ) + return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template ) end --- Return the mission route of the group. @@ -5066,7 +5093,7 @@ end function GROUP:GetTaskRoute() self:F( self.GroupName ) - return routines.utils.deepCopy( _DATABASE.Groups[self.GroupName].Template.route.points ) + return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points ) end --- Return the route of a group by using the @{Database#DATABASE} class. @@ -5090,7 +5117,7 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius ) self:T( { GroupName } ) - local Template = _DATABASE.Groups[GroupName].Template + local Template = _DATABASE.Templates.Groups[GroupName].Template if Template then if not Begin then @@ -5523,11 +5550,13 @@ UNIT = { -- @return Unit#UNIT function UNIT:New( DCSUnit ) local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSUnit:getName() ) + self:F( DCSUnit ) self.DCSUnit = DCSUnit - self.UnitName = DCSUnit:getName() - self.UnitID = DCSUnit:getID() + if DCSUnit then + self.UnitName = DCSUnit:getName() + self.UnitID = DCSUnit:getID() + end return self end @@ -5558,6 +5587,18 @@ function UNIT:GetName() 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 = "" + end + + return PlayerName +end function UNIT:GetTypeName() self:F( self.UnitName ) @@ -5800,6 +5841,499 @@ function ZONE:GetRadius() return Zone.radius end +--- The CLIENT models client units in multi player missions. +-- +-- @{#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. +-- +-- 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. +-- +-- @module Client +-- @author FlightControl + +Include.File( "Routines" ) +Include.File( "Base" ) +Include.File( "Cargo" ) +Include.File( "Message" ) + + +--- The CLIENT class +-- @type CLIENT +-- @extends Base#BASE +CLIENT = { + ONBOARDSIDE = { + NONE = 0, + LEFT = 1, + RIGHT = 2, + BACK = 3, + FRONT = 4 + }, + ClassName = "CLIENT", + ClientName = nil, + ClientAlive = false, + ClientTransport = false, + ClientBriefingShown = false, + _Menus = {}, + _Tasks = {}, + Messages = { + } +} + + +--- Use this method to register new Clients within a mission. +-- @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: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 ) + + self.ClientName = ClientName + self:AddBriefing( ClientBriefing ) + self.MessageSwitch = true + + return self +end + +--- Transport defines that the Client is a Transport. Transports show cargo. +-- @param #CLIENT self +-- @return #CLIENT +function CLIENT:Transport() + self:F() + + self.ClientTransport = true + return self +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 +function CLIENT:AddBriefing( ClientBriefing ) + self:F() + self.ClientBriefing = ClientBriefing + return self +end + + +--- Resets a CLIENT. +-- @param #CLIENT self +-- @param #string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client. +function CLIENT:Reset( ClientName ) + self:F() + 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. +-- @param #CLIENT self +-- @return #boolean true if multi-seated. +function CLIENT:IsMultiSeated() + self:F( self.ClientName ) + + local ClientMultiSeatedTypes = { + ["Mi-8MT"] = "Mi-8MT", + ["UH-1H"] = "UH-1H", + ["P-51B"] = "P-51B" + } + + if self:IsAlive() then + local ClientTypeName = self:GetClientGroupUnit():GetTypeName() + if ClientMultiSeatedTypes[ClientTypeName] then + return true + end + end + + return false +end + +--- Checks if client is alive and returns true or false. +-- @param #CLIENT self +-- @returns #boolean Returns true if client is alive. +function CLIENT:IsAlive() + self:F( self.ClientName ) + + local ClientUnit = Unit.getByName( self.ClientName ) + + if ClientUnit and ClientUnit:isExist() then + self:T("true") + return true + end + + self:T( "false" ) + return false +end + + +--- @param #CLIENT self +function CLIENT:_AliveCheckScheduler() + self:F( { self.ClientName, self.ClientAlive2 } ) + + if self:IsAlive() then + if self.ClientAlive2 == false then + self:T("Calling Callback function") + self.ClientCallBack( self, unpack( self.ClientParameters ) ) + self.ClientAlive2 = true + end + else + if self.ClientAlive2 == true then + self.ClientAlive2 = false + end + end +end + +--- Return the DCSGroup of a Client. +-- This function is modified to deal with a couple of bugs in DCS 1.5.3 +-- @param #CLIENT self +-- @return DCSGroup#Group +function CLIENT:GetDCSGroup() + self:F3() + +-- local ClientData = Group.getByName( self.ClientName ) +-- if ClientData and ClientData:isExist() then +-- self:T( self.ClientName .. " : group found!" ) +-- return ClientData +-- else +-- return nil +-- end + + local ClientUnit = Unit.getByName( self.ClientName ) + + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + self:T3( { "CoalitionData:", CoalitionData } ) + for UnitId, UnitData in pairs( CoalitionData ) do + self:T3( { "UnitData:", UnitData } ) + if UnitData and UnitData:isExist() then + + --self:E(self.ClientName) + if ClientUnit then + local ClientGroup = ClientUnit:getGroup() + if ClientGroup then + self:T3( "ClientGroup = " .. self.ClientName ) + if ClientGroup:isExist() and UnitData:getGroup():isExist() then + if ClientGroup:getID() == UnitData:getGroup():getID() then + self:T3( "Normal logic" ) + self:T3( self.ClientName .. " : group found!" ) + self.ClientGroupID = ClientGroup:getID() + self.ClientGroupName = ClientGroup:getName() + return ClientGroup + end + else + -- Now we need to resolve the bugs in DCS 1.5 ... + -- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil) + self:T3( "Bug 1.5 logic" ) + local ClientGroupTemplate = _DATABASE.Templates.Units[self.ClientName].GroupTemplate + self.ClientGroupID = ClientGroupTemplate.groupId + self.ClientGroupName = _DATABASE.Templates.Units[self.ClientName].GroupName + self:T3( self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) + return ClientGroup + end + -- else + -- error( "Client " .. self.ClientName .. " not found!" ) + end + end + end + end + end + + -- For non player clients + if ClientUnit then + local ClientGroup = ClientUnit:getGroup() + if ClientGroup then + self:T3( "ClientGroup = " .. self.ClientName ) + if ClientGroup:isExist() then + self:T3( "Normal logic" ) + self:T3( self.ClientName .. " : group found!" ) + return ClientGroup + end + end + end + + self.ClientGroupID = nil + self.ClientGroupUnit = nil + + return nil +end + + +-- TODO: Check DCSTypes#Group.ID +--- Get the group ID of the client. +-- @param #CLIENT self +-- @return DCSTypes#Group.ID +function CLIENT:GetClientGroupID() + + local ClientGroup = self:GetDCSGroup() + + --self:E( self.ClientGroupID ) -- Determined in GetDCSGroup() + return self.ClientGroupID +end + + +--- Get the name of the group of the client. +-- @param #CLIENT self +-- @return #string +function CLIENT:GetClientGroupName() + + local ClientGroup = self:GetDCSGroup() + + self:T( self.ClientGroupName ) -- Determined in GetDCSGroup() + return self.ClientGroupName +end + +--- Returns the UNIT of the CLIENT. +-- @param #CLIENT self +-- @return Unit#UNIT +function CLIENT:GetClientGroupUnit() + self:F2() + + local ClientDCSUnit = Unit.getByName( self.ClientName ) + + self:T( self.ClientDCSUnit ) + if ClientDCSUnit and ClientDCSUnit:isExist() then + local ClientUnit = _DATABASE.Units[ self.ClientName ] + self:T2( ClientUnit ) + return ClientUnit + end +end + +--- Returns the DCSUnit of the CLIENT. +-- @param #CLIENT self +-- @return DCSTypes#Unit +function CLIENT:GetClientGroupDCSUnit() + self:F2() + + local ClientDCSUnit = Unit.getByName( self.ClientName ) + + if ClientDCSUnit and ClientDCSUnit:isExist() then + self:T2( ClientDCSUnit ) + return ClientDCSUnit + end +end + +-- TODO what is this??? check. possible double function. +function CLIENT:GetUnit() + self:F() + + return UNIT:New( self:GetClientGroupDCSUnit() ) +end + +--- Returns the position of the CLIENT in @{DCSTypes#Vec2} format.. +-- @param #CLIENT self +-- @return DCSTypes#Vec2 +function CLIENT:GetPointVec2() + self:F() + + local ClientGroupUnit = self:GetClientGroupDCSUnit() + + if ClientGroupUnit then + if ClientGroupUnit:isExist() then + local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3 + local PointVec2 = {} --DCSTypes#Vec2 + PointVec2.x = PointVec3.x + PointVec2.y = PointVec3.z + self:T( { PointVec2 } ) + return PointVec2 + end + end + + return nil +end + +function CLIENT:GetPositionVec3() + self:F( self.ClientName ) + + local DCSUnit = Unit.getByName( self.ClientName ) + local UnitPos = DCSUnit:getPosition().p + + self:T( UnitPos ) + return UnitPos +end + +function CLIENT:GetID() + self:F( self.ClientName ) + + local DCSUnit = Unit.getByName( self.ClientName ) + local UnitID = DCSUnit:getID() + + self:T( UnitID ) + return UnitID +end + +function CLIENT:GetName() + self:F( self.ClientName ) + + self:T( self.ClientName ) + return self.ClientName +end + +function CLIENT:GetTypeName() + self:F( self.ClientName ) + + local DCSUnit = Unit.getByName( self.ClientName ) + local TypeName = DCSUnit:getTypeName() + + self:T( TypeName ) + return TypeName +end + + + +--- Returns the position of the CLIENT in @{DCSTypes#Vec3} format. +-- @param #CLIENT self +-- @return DCSTypes#Vec3 +function CLIENT:ClientPosition() + self:F() + + local ClientGroupUnit = self:GetClientGroupDCSUnit() + + if ClientGroupUnit then + if ClientGroupUnit:isExist() then + return ClientGroupUnit:getPosition() + end + end + + return nil +end + +--- Returns the altitude of the CLIENT. +-- @param #CLIENT self +-- @return DCSTypes#Distance +function CLIENT:GetAltitude() + self:F() + + local ClientGroupUnit = self:GetClientGroupDCSUnit() + + if ClientGroupUnit then + if ClientGroupUnit:isExist() then + local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3 + return PointVec3.y + end + end + + return nil +end + + +--- Evaluates if the CLIENT is a transport. +-- @param #CLIENT self +-- @return #boolean true is a transport. +function CLIENT:IsTransport() + self:F() + return self.ClientTransport +end + +--- Shows the @{Cargo#CARGO} contained within the CLIENT to the player as a message. +-- The @{Cargo#CARGO} is shown using the @{Message#MESSAGE} distribution system. +-- @param #CLIENT self +function CLIENT:ShowCargo() + self:F() + + local CargoMsg = "" + + for CargoName, Cargo in pairs( CARGOS ) do + if self == Cargo:IsLoadedInClient() then + CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType .. " Weight: " .. Cargo.CargoWeight .. "\n" + end + end + + if CargoMsg == "" then + CargoMsg = "empty" + end + + self:Message( CargoMsg, 15, self.ClientName .. "/Cargo", "Co-Pilot: Cargo Status", 30 ) + +end + +-- TODO (1) I urgently need to revise this. +--- A local function called by the DCS World Menu system to switch off messages. +function CLIENT.SwitchMessages( PrmTable ) + PrmTable[1].MessageSwitch = PrmTable[2] +end + +--- The main message driver for the CLIENT. +-- This function displays various messages to the Player logged into the CLIENT through the DCS World Messaging system. +-- @param #CLIENT self +-- @param #string Message is the text describing the message. +-- @param #number MessageDuration is the duration in seconds that the Message should be displayed. +-- @param #string MessageId is a text identifying the Message in the MessageQueue. The Message system overwrites Messages with the same MessageId +-- @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() + + if not self.MenuMessages then + if self:GetClientGroupID() then + self.MenuMessages = MENU_CLIENT:New( self, 'Messages' ) + self.MenuRouteMessageOn = MENU_CLIENT_COMMAND:New( self, 'Messages On', self.MenuMessages, CLIENT.SwitchMessages, { self, true } ) + self.MenuRouteMessageOff = MENU_CLIENT_COMMAND:New( self,'Messages Off', self.MenuMessages, CLIENT.SwitchMessages, { self, false } ) + end + end + + if self.MessageSwitch == true then + if MessageCategory == nil then + MessageCategory = "Messages" + end + if self.Messages[MessageId] == nil then + self.Messages[MessageId] = {} + self.Messages[MessageId].MessageId = MessageId + self.Messages[MessageId].MessageTime = timer.getTime() + self.Messages[MessageId].MessageDuration = MessageDuration + if MessageInterval == nil then + self.Messages[MessageId].MessageInterval = 600 + else + self.Messages[MessageId].MessageInterval = MessageInterval + end + MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) + else + if self:GetClientGroupDCSUnit() and not self:GetClientGroupDCSUnit():inAir() then + if timer.getTime() - self.Messages[MessageId].MessageTime >= self.Messages[MessageId].MessageDuration + 10 then + MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) + self.Messages[MessageId].MessageTime = timer.getTime() + end + else + if timer.getTime() - self.Messages[MessageId].MessageTime >= self.Messages[MessageId].MessageDuration + self.Messages[MessageId].MessageInterval then + MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) + self.Messages[MessageId].MessageTime = timer.getTime() + end + end + end + end +end --- Manage sets of units and groups. -- -- @{#Database} class @@ -5868,25 +6402,35 @@ Include.File( "Routines" ) Include.File( "Base" ) Include.File( "Menu" ) Include.File( "Group" ) +Include.File( "Unit" ) Include.File( "Event" ) +Include.File( "Client" ) --- DATABASE class -- @type DATABASE -- @extends Base#BASE DATABASE = { ClassName = "DATABASE", + Templates = { + Units = {}, + Groups = {}, + ClientsByName = {}, + ClientsByID = {}, + }, DCSUnits = {}, DCSUnitsAlive = {}, - Units = {}, - Groups = {}, DCSGroups = {}, DCSGroupsAlive = {}, + Units = {}, + UnitsAlive = {}, + Groups = {}, + GroupsAlive = {}, NavPoints = {}, Statics = {}, Players = {}, - AlivePlayers = {}, - ClientsByName = {}, - ClientsByID = {}, + PlayersAlive = {}, + Clients = {}, + ClientsAlive = {}, Filter = { Coalitions = nil, Categories = nil, @@ -5942,6 +6486,14 @@ function DATABASE:New() _EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self ) _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) + + -- Add database with registered clients and already alive players + + -- Follow alive players and clients + _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) + _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) + + return self end @@ -6062,16 +6614,43 @@ function DATABASE:FilterStart() -- OK, we have a _DATABASE -- Now use the different filters to build the set. -- We first take ALL of the Units of the _DATABASE. - for UnitRegistrationID, UnitRegistration in pairs( _DATABASE.Units ) do - self:T( UnitRegistration ) - local DCSUnit = Unit.getByName( UnitRegistration.UnitName ) + + self:E( { "Adding Database Datapoints with filters" } ) + for DCSUnitName, DCSUnit in pairs( _DATABASE.DCSUnits ) do + if self:_IsIncludeDCSUnit( DCSUnit ) then - self.DCSUnits[DCSUnit:getName()] = DCSUnit - end - if self:_IsAliveDCSUnit( DCSUnit ) then - self.DCSUnitsAlive[DCSUnit:getName()] = DCSUnit + + 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 @@ -6120,7 +6699,7 @@ end function DATABASE:SetStatusGroup( GroupName, Status ) self:F( Status ) - self.Groups[GroupName].Status = Status + self.Templates.Groups[GroupName].Status = Status end @@ -6128,8 +6707,8 @@ end function DATABASE:GetStatusGroup( GroupName ) self:F( Status ) - if self.Groups[GroupName] then - return self.Groups[GroupName].Status + if self.Templates.Groups[GroupName] then + return self.Templates.Groups[GroupName].Status else return "" end @@ -6143,9 +6722,9 @@ function DATABASE:_RegisterGroup( GroupTemplate ) local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) - if not self.Groups[GroupTemplateName] then - self.Groups[GroupTemplateName] = {} - self.Groups[GroupTemplateName].Status = nil + if not self.Templates.Groups[GroupTemplateName] then + self.Templates.Groups[GroupTemplateName] = {} + self.Templates.Groups[GroupTemplateName].Status = nil end -- Delete the spans from the route, it is not needed and takes memory. @@ -6153,31 +6732,102 @@ function DATABASE:_RegisterGroup( GroupTemplate ) GroupTemplate.route.spans = nil end - self.Groups[GroupTemplateName].GroupName = GroupTemplateName - self.Groups[GroupTemplateName].Template = GroupTemplate - self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId - self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units - self.Groups[GroupTemplateName].Units = GroupTemplate.units + self.Templates.Groups[GroupTemplateName].GroupName = GroupTemplateName + self.Templates.Groups[GroupTemplateName].Template = GroupTemplate + self.Templates.Groups[GroupTemplateName].groupId = GroupTemplate.groupId + self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units + self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units - self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) + self:T( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) - for unit_num, UnitTemplate in pairs(GroupTemplate.units) do + for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name) - self.Units[UnitTemplateName] = {} - self.Units[UnitTemplateName].UnitName = UnitTemplateName - self.Units[UnitTemplateName].Template = UnitTemplate - self.Units[UnitTemplateName].GroupName = GroupTemplateName - self.Units[UnitTemplateName].GroupTemplate = GroupTemplate - self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId + self.Templates.Units[UnitTemplateName] = {} + self.Templates.Units[UnitTemplateName].UnitName = UnitTemplateName + self.Templates.Units[UnitTemplateName].Template = UnitTemplate + self.Templates.Units[UnitTemplateName].GroupName = GroupTemplateName + self.Templates.Units[UnitTemplateName].GroupTemplate = GroupTemplate + self.Templates.Units[UnitTemplateName].GroupId = GroupTemplate.groupId + self:E( {"skill",UnitTemplate.skill}) if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then - self.ClientsByName[UnitTemplateName] = UnitTemplate - self.ClientsByID[UnitTemplate.unitId] = UnitTemplate + self.Templates.ClientsByName[UnitTemplateName] = UnitTemplate + self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate end - self:E( { "Unit", self.Units[UnitTemplateName].UnitName } ) + self:E( { "Unit", self.Templates.Units[UnitTemplateName].UnitName } ) end end +--- Private method that registers all alive players in the mission. +-- @param #DATABASE self +-- @return #DATABASE self +function DATABASE:_RegisterPlayers() + + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for UnitId, UnitData in pairs( CoalitionData ) do + self:T3( { "UnitData:", UnitData } ) + if UnitData and UnitData:isExist() then + local UnitName = UnitData:getName() + if not self.PlayersAlive[UnitName] then + self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) + self.PlayersAlive[UnitName] = UnitData:getPlayerName() + end + end + end + end + + return self +end + +--- Private method that registers all datapoints within in the mission. +-- @param #DATABASE self +-- @return #DATABASE self +function DATABASE:_RegisterDatabase() + + local CoalitionsData = { AlivePlayersRed = coalition.getGroups( coalition.side.RED ), AlivePlayersBlue = coalition.getGroups( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for DCSGroupId, DCSGroup in pairs( CoalitionData ) do + + local DCSGroupName = DCSGroup:getName() + + self:E( { "Register Group:", DCSGroup, DCSGroupName } ) + self.DCSGroups[DCSGroupName] = DCSGroup + self.Groups[DCSGroupName] = GROUP:New( DCSGroup ) + + if self:_IsAliveDCSGroup(DCSGroup) then + self:E( { "Register Alive Group:", DCSGroup, DCSGroupName } ) + self.DCSGroupsAlive[DCSGroupName] = DCSGroup + self.GroupsAlive[DCSGroupName] = self.Groups[DCSGroupName] + end + + for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do + + local DCSUnitName = DCSUnit:getName() + self:E( { "Register Unit:", DCSUnit, DCSUnitName } ) + + self.DCSUnits[DCSUnitName] = DCSUnit + self.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 + end + + for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do + self.Clients[ClientName] = CLIENT:New( ClientName ) + end + end + end + + return self +end + + +--- Events + --- Handles the OnBirth event for the alive units set. -- @param #DATABASE self -- @param Event#EVENTDATA Event @@ -6187,7 +6837,15 @@ 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.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:_EventOnPlayerEnterUnit( Event ) end end end @@ -6206,18 +6864,54 @@ function DATABASE:_EventOnDeadOrCrash( Event ) end end ---- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). -- @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. +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnPlayerEnterUnit( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then + if not self.PlayersAlive[Event.IniDCSUnitName] then + self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) + self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() + self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ] + end + end + end +end + +--- Handles the OnPlayerLeaveUnit event to clean the active players table. +-- @param #DATABASE self +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnPlayerLeaveUnit( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then + if self.PlayersAlive[Event.IniDCSUnitName] then + self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) + self.PlayersAlive[Event.IniDCSUnitName] = nil + self.ClientsAlive[Event.IniDCSUnitName] = nil + end + end + end +end + +--- Iterators + +--- Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self -function DATABASE:ForEachAliveUnit( IteratorFunction, ... ) +function DATABASE:ForEach( IteratorFunction, arg, Set ) self:F( arg ) local function CoRoutine() local Count = 0 - for DCSUnitID, DCSUnit in pairs( self.DCSUnitsAlive ) do - self:T2( DCSUnit ) - IteratorFunction( DCSUnit, unpack( arg ) ) + for ObjectID, Object in pairs( Set ) do + self:T2( Object ) + IteratorFunction( Object, unpack( arg ) ) Count = Count + 1 if Count % 10 == 0 then coroutine.yield( false ) @@ -6237,15 +6931,56 @@ function DATABASE:ForEachAliveUnit( IteratorFunction, ... ) error( res ) end if res == false then - timer.scheduleFunction( Schedule, {}, timer.getTime() + 0.001 ) + return true -- resume next time the loop end + + return false end - timer.scheduleFunction( Schedule, {}, timer.getTime() + 1 ) + local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 ) return self end + +--- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +-- @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, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive ) + + return self +end + +--- Interate the DATABASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachPlayer( IteratorFunction, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.PlayersAlive ) + + return self +end + + +--- Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter. +-- @return #DATABASE self +function DATABASE:ForEachClient( IteratorFunction, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.Clients ) + + return self +end + + function DATABASE:ScanEnvironment() self:F() @@ -6309,6 +7044,9 @@ function DATABASE:ScanEnvironment() end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then end --for coa_name, coa_data in pairs(mission.coalition) do + self:_RegisterDatabase() + self:_RegisterPlayers() + return self end @@ -6396,6 +7134,22 @@ function DATABASE:_IsAliveDCSUnit( DCSUnit ) return DCSUnitAlive end +--- +-- @param #DATABASE self +-- @param DCSGroup#Group DCSGroup +-- @return #DATABASE self +function DATABASE:_IsAliveDCSGroup( DCSGroup ) + self:F( DCSGroup ) + local DCSGroupAlive = false + if DCSGroup and DCSGroup:isExist() then + if self.DCSGroups[DCSGroup:getName()] then + DCSGroupAlive = true + end + end + self:T( DCSGroupAlive ) + return DCSGroupAlive +end + --- Traces the current database contents in the log ... (for debug reasons). -- @param #DATABASE self @@ -8428,461 +9182,6 @@ function CARGO_SLINGLOAD:UnLoad( Client, TargetZoneName ) return Cargo end ---- The CLIENT models client units in multi player missions. --- Clients are those groups defined within the Mission Editor that have the skillset defined as "Client" or "Player". --- Note that clients are NOT the same as groups, they are NOT necessarily alive. --- @module Client --- @author FlightControl - -Include.File( "Routines" ) -Include.File( "Base" ) -Include.File( "Cargo" ) -Include.File( "Message" ) - - ---- The CLIENT class --- @type CLIENT --- @extends Base#BASE -CLIENT = { - ONBOARDSIDE = { - NONE = 0, - LEFT = 1, - RIGHT = 2, - BACK = 3, - FRONT = 4 - }, - ClassName = "CLIENT", - ClientName = nil, - ClientAlive = false, - ClientTransport = false, - ClientBriefingShown = false, - _Menus = {}, - _Tasks = {}, - Messages = { - } -} - - ---- Use this method to register new Clients within the MOF. --- @param #CLIENT self --- @param #string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client. --- @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: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 ) - - self.ClientName = ClientName - self:AddBriefing( ClientBriefing ) - self.MessageSwitch = true - - return self -end - ---- Transport defines that the Client is a Transport. Transports show cargo. --- @param #CLIENT self --- @return #CLIENT -function CLIENT:Transport() - self:F() - - self.ClientTransport = true - return self -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 -function CLIENT:AddBriefing( ClientBriefing ) - self:F() - self.ClientBriefing = ClientBriefing - return self -end - - ---- Resets a CLIENT. --- @param #CLIENT self --- @param #string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client. -function CLIENT:Reset( ClientName ) - self:F() - 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. --- @param #CLIENT self --- @return #boolean true if multi-seated. -function CLIENT:IsMultiSeated() - self:F( self.ClientName ) - - local ClientMultiSeatedTypes = { - ["Mi-8MT"] = "Mi-8MT", - ["UH-1H"] = "UH-1H", - ["P-51B"] = "P-51B" - } - - if self:IsAlive() then - local ClientTypeName = self:GetClientGroupUnit():GetTypeName() - if ClientMultiSeatedTypes[ClientTypeName] then - return true - end - end - - return false -end - ---- Checks if client is alive and returns true or false. --- @param #CLIENT self --- @returns #boolean Returns true if client is alive. -function CLIENT:IsAlive() - self:F( self.ClientName ) - - local ClientDCSGroup = self:GetDCSGroup() - - if ClientDCSGroup then - self:T("true") - return true - end - - self:T( "false" ) - return false -end - - ---- @param #CLIENT self -function CLIENT:_AliveCheckScheduler() - self:F( { self.ClientName, self.ClientAlive2 } ) - - if self:IsAlive() then - if self.ClientAlive2 == false then - self:T("Calling Callback function") - self.ClientCallBack( self, unpack( self.ClientParameters ) ) - self.ClientAlive2 = true - end - else - if self.ClientAlive2 == true then - self.ClientAlive2 = false - end - end -end - ---- Return the DCSGroup of a Client. --- This function is modified to deal with a couple of bugs in DCS 1.5.3 --- @param #CLIENT self --- @return DCSGroup#Group -function CLIENT:GetDCSGroup() - self:F3() - --- local ClientData = Group.getByName( self.ClientName ) --- if ClientData and ClientData:isExist() then --- self:T( self.ClientName .. " : group found!" ) --- return ClientData --- else --- return nil --- end - - local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } - for CoalitionId, CoalitionData in pairs( CoalitionsData ) do - self:T3( { "CoalitionData:", CoalitionData } ) - for UnitId, UnitData in pairs( CoalitionData ) do - self:T3( { "UnitData:", UnitData } ) - if UnitData and UnitData:isExist() then - - local ClientGroup = Group.getByName( self.ClientName ) - if ClientGroup then - self:T3( "ClientGroup = " .. self.ClientName ) - if ClientGroup:isExist() then - if ClientGroup:getID() == UnitData:getGroup():getID() then - self:T3( "Normal logic" ) - self:T3( self.ClientName .. " : group found!" ) - return ClientGroup - end - else - -- Now we need to resolve the bugs in DCS 1.5 ... - -- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil) - self:T3( "Bug 1.5 logic" ) - local ClientUnits = _DATABASE.Groups[self.ClientName].Units - self:T3( { ClientUnits[1].name, env.getValueDictByKey(ClientUnits[1].name) } ) - for ClientUnitID, ClientUnitData in pairs( ClientUnits ) do - self:T3( { tonumber(UnitData:getID()), ClientUnitData.unitId } ) - if tonumber(UnitData:getID()) == ClientUnitData.unitId then - local ClientGroupTemplate = _DATABASE.Groups[self.ClientName].Template - self.ClientID = ClientGroupTemplate.groupId - self.ClientGroupUnit = UnitData - self:T3( self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) - return ClientGroup - end - end - end --- else --- error( "Client " .. self.ClientName .. " not found!" ) - end - end - end - end - - -- For non player clients - local ClientGroup = Group.getByName( self.ClientName ) - if ClientGroup then - self:T3( "ClientGroup = " .. self.ClientName ) - if ClientGroup:isExist() then - self:T3( "Normal logic" ) - self:T3( self.ClientName .. " : group found!" ) - return ClientGroup - end - end - - self.ClientGroupID = nil - self.ClientGroupUnit = nil - - return nil -end - - --- TODO: Check DCSTypes#Group.ID ---- Get the group ID of the client. --- @param #CLIENT self --- @return DCSTypes#Group.ID -function CLIENT:GetClientGroupID() - - if not self.ClientGroupID then - local ClientGroup = self:GetDCSGroup() - if ClientGroup and ClientGroup:isExist() then - self.ClientGroupID = ClientGroup:getID() - else - self.ClientGroupID = self.ClientID - end - end - - self:T( self.ClientGroupID ) - return self.ClientGroupID -end - - ---- Get the name of the group of the client. --- @param #CLIENT self --- @return #string -function CLIENT:GetClientGroupName() - - if not self.ClientGroupName then - local ClientGroup = self:GetDCSGroup() - if ClientGroup and ClientGroup:isExist() then - self.ClientGroupName = ClientGroup:getName() - else - self.ClientGroupName = self.ClientName - end - end - - self:T( self.ClientGroupName ) - return self.ClientGroupName -end - ---- Returns the UNIT of the CLIENT. --- @param #CLIENT self --- @return Unit#UNIT -function CLIENT:GetClientGroupUnit() - self:F() - - local ClientGroup = self:GetDCSGroup() - - if ClientGroup and ClientGroup:isExist() then - return UNIT:New( ClientGroup:getUnit(1) ) - else - return UNIT:New( self.ClientGroupUnit ) - end -end - ---- Returns the DCSUnit of the CLIENT. --- @param #CLIENT self --- @return DCSTypes#Unit -function CLIENT:GetClientGroupDCSUnit() - self:F2() - - local ClientGroup = self:GetDCSGroup() - - if ClientGroup and ClientGroup:isExist() then - return ClientGroup:getUnit(1) - else - return self.ClientGroupUnit - 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() - - 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 - - ---- Returns the position of the CLIENT in @{DCSTypes#Vec3} format. --- @param #CLIENT self --- @return DCSTypes#Vec3 -function CLIENT:ClientPosition() - self:F() - - 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() - - 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 --- @return #boolean true is a transport. -function CLIENT:IsTransport() - self:F() - return self.ClientTransport -end - ---- Shows the @{Cargo#CARGO} contained within the CLIENT to the player as a message. --- The @{Cargo#CARGO} is shown using the @{Message#MESSAGE} distribution system. --- @param #CLIENT self -function CLIENT:ShowCargo() - self:F() - - local CargoMsg = "" - - for CargoName, Cargo in pairs( CARGOS ) do - if self == Cargo:IsLoadedInClient() then - CargoMsg = CargoMsg .. Cargo.CargoName .. " Type:" .. Cargo.CargoType .. " Weight: " .. Cargo.CargoWeight .. "\n" - end - end - - if CargoMsg == "" then - CargoMsg = "empty" - end - - self:Message( CargoMsg, 15, self.ClientName .. "/Cargo", "Co-Pilot: Cargo Status", 30 ) - -end - --- TODO (1) I urgently need to revise this. ---- A local function called by the DCS World Menu system to switch off messages. -function CLIENT.SwitchMessages( PrmTable ) - PrmTable[1].MessageSwitch = PrmTable[2] -end - ---- The main message driver for the CLIENT. --- This function displays various messages to the Player logged into the CLIENT through the DCS World Messaging system. --- @param #CLIENT self --- @param #string Message is the text describing the message. --- @param #number MessageDuration is the duration in seconds that the Message should be displayed. --- @param #string MessageId is a text identifying the Message in the MessageQueue. The Message system overwrites Messages with the same MessageId --- @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() - - if not self.MenuMessages then - if self:GetClientGroupID() then - self.MenuMessages = MENU_CLIENT:New( self, 'Messages' ) - self.MenuRouteMessageOn = MENU_CLIENT_COMMAND:New( self, 'Messages On', self.MenuMessages, CLIENT.SwitchMessages, { self, true } ) - self.MenuRouteMessageOff = MENU_CLIENT_COMMAND:New( self,'Messages Off', self.MenuMessages, CLIENT.SwitchMessages, { self, false } ) - end - end - - if self.MessageSwitch == true then - if MessageCategory == nil then - MessageCategory = "Messages" - end - if self.Messages[MessageId] == nil then - self.Messages[MessageId] = {} - self.Messages[MessageId].MessageId = MessageId - self.Messages[MessageId].MessageTime = timer.getTime() - self.Messages[MessageId].MessageDuration = MessageDuration - if MessageInterval == nil then - self.Messages[MessageId].MessageInterval = 600 - else - self.Messages[MessageId].MessageInterval = MessageInterval - end - MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) - else - if self:GetClientGroupDCSUnit() and not self:GetClientGroupDCSUnit():inAir() then - if timer.getTime() - self.Messages[MessageId].MessageTime >= self.Messages[MessageId].MessageDuration + 10 then - MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) - self.Messages[MessageId].MessageTime = timer.getTime() - end - else - if timer.getTime() - self.Messages[MessageId].MessageTime >= self.Messages[MessageId].MessageDuration + self.Messages[MessageId].MessageInterval then - MESSAGE:New( Message, MessageCategory, MessageDuration, MessageId ):ToClient( self ) - self.Messages[MessageId].MessageTime = timer.getTime() - end - end - end - end -end --- Message System to display Messages for Clients and Coalitions or All. -- Messages are grouped on the display panel per Category to improve readability for the players. -- Messages are shown on the display panel for an amount of seconds, and will then disappear. @@ -13156,7 +13455,7 @@ function SPAWN:_GetTemplate( SpawnTemplatePrefix ) local SpawnTemplate = nil - SpawnTemplate = routines.utils.deepCopy( _DATABASE.Groups[SpawnTemplatePrefix].Template ) + SpawnTemplate = routines.utils.deepCopy( _DATABASE.Templates.Groups[SpawnTemplatePrefix].Template ) if SpawnTemplate == nil then error( 'No Template returned for SpawnTemplatePrefix = ' .. SpawnTemplatePrefix ) @@ -13660,7 +13959,7 @@ function SEAD:EventShot( Event ) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroupName = _targetMimgroup:getName() local _targetMimcont= _targetMimgroup:getController() - local _targetskill = _DATABASE.Units[_targetMimname].Template.skill + local _targetskill = _DATABASE.Templates.Units[_targetMimname].Template.skill self:T( self.SEADGroupPrefixes ) self:T( _targetMimgroupName ) local SEADGroupFound = false @@ -14976,6 +15275,71 @@ function ESCORT:_ReportTargetsScheduler() end end --- Provides missile training functions. +-- +-- @{#MISSILETRAINER} class +-- ======================== +-- The @{#MISSILETRAINER} class uses the DCS world messaging system to be alerted of any missiles fired, and when a missile would hit your aircraft, +-- the class will destroy the missile within a certain range, to avoid damage to your aircraft. +-- It suports the following functionality: +-- +-- * Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes. +-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range … +-- * Provide alerts when a missile would have killed your aircraft. +-- * Provide alerts when the missile self destructs. +-- * Enable / Disable and Configure the Missile Trainer using the various menu options. +-- +-- When running a mission where MISSILETRAINER is used, the following radio menu structure ( 'Radio Menu' -> 'Other (F10)' -> 'MissileTrainer' ) options are available for the players: +-- +-- * **Messages**: Menu to configure all messages. +-- * **Messages On**: Show all messages. +-- * **Messages Off**: Disable all messages. +-- * **Tracking**: Menu to configure missile tracking messages. +-- * **To All**: Shows missile tracking messages to all players. +-- * **To Target**: Shows missile tracking messages only to the player where the missile is targetted at. +-- * **Tracking On**: Show missile tracking messages. +-- * **Tracking Off**: Disable missile tracking messages. +-- * **Alerts**: Menu to configure alert messages. +-- * **To All**: Shows alert messages to all players. +-- * **To Target**: Shows alter messages only to the player where the missile is (was) targetted at. +-- * **Hits On**: Show missile hit alert messages. +-- * **Hits Off**: Disable missile hit altert messages. +-- * **Launches On**: Show missile launch messages. +-- * **Launches Off**: Disable missile launch messages. +-- * **Details**: Menu to configure message details. +-- * **Range On**: Shows range information when a missile is fired to a target. +-- * **Range Off**: Disable range information when a missile is fired to a target. +-- * **Bearing On**: Shows bearing information when a missile is fired to a target. +-- * **Bearing Off**: Disable bearing information when a missile is fired to a target. +-- * **Distance**: Menu to configure the distance when a missile needs to be destroyed when near to a player, during tracking. +-- This will improve/influence hit calculation accuracy, but has the risk of damaging the aircraft when the missile reaches the aircraft before the distance is measured. +-- * **50 meter**: Destroys the missile when the distance to the aircraft is below or equal to 50 meter. +-- * **100 meter**: Destroys the missile when the distance to the aircraft is below or equal to 100 meter. +-- * **150 meter**: Destroys the missile when the distance to the aircraft is below or equal to 150 meter. +-- * **200 meter**: Destroys the missile when the distance to the aircraft is below or equal to 200 meter. +-- +-- +-- MISSILETRAINER construction methods: +-- ==================================== +-- Create a new MISSILETRAINER object with the @{#MISSILETRAINER.New} method: +-- +-- * @{#MISSILETRAINER.New}: Creates a new MISSILETRAINER object taking the maximum distance to your aircraft to evaluate when a missile needs to be destroyed. +-- +-- MISSILETRAINER will collect each unit declared in the mission with a skill level "Client" and "Player", and will monitor the missiles shot at those. +-- +-- MISSILETRAINER initialization methods: +-- ====================================== +-- A MISSILETRAINER object will behave differently based on the usage of initialization methods: +-- +-- * @{#MISSILETRAINER.InitMessagesOnOff}: Sets by default the display of any message to be ON or OFF. +-- * @{#MISSILETRAINER.InitTrackingToAll}: Sets by default the missile tracking report for all players or only for those missiles targetted to you. +-- * @{#MISSILETRAINER.InitTrackingOnOff}: Sets by default the display of missile tracking report to be ON or OFF. +-- * @{#MISSILETRAINER.InitAlertsToAll}: Sets by default the display of alerts to be shown to all players or only to you. +-- * @{#MISSILETRAINER.InitAlertsHitsOnOff}: Sets by default the display of hit alerts ON or OFF. +-- * @{#MISSILETRAINER.InitAlertsLaunchesOnOff}: Sets by default the display of launch alerts ON or OFF. +-- * @{#MISSILETRAINER.InitRangeOnOff}: Sets by default the display of range information of missiles ON of OFF. +-- * @{#MISSILETRAINER.InitBearingOnOff}: Sets by default the display of bearing information of missiles ON of OFF. +-- * @{#MISSILETRAINER.InitMenusOnOff}: Allows to configure the options through the radio menu. +-- -- @module MissileTrainer -- @author FlightControl @@ -14986,7 +15350,7 @@ Include.File( "Scheduler" ) -- @type MISSILETRAINER -- @extends Base#BASE MISSILETRAINER = { - ClassName = "MISSILETRAINER", + ClassName = "MISSILETRAINER", } --- Creates the main object which is handling missile tracking. @@ -14995,64 +15359,534 @@ MISSILETRAINER = { -- @param #number Distance The distance in meters when a tracked missile needs to be destroyed when close to a player. -- @return #MISSILETRAINER function MISSILETRAINER:New( Distance ) - local self = BASE:Inherit( self, BASE:New() ) - self:F( Distance ) - - self.Schedulers = {} - self.SchedulerID = 0 - - self.Distance = Distance + local self = BASE:Inherit( self, BASE:New() ) + self:F( Distance ) + + self.Schedulers = {} + self.SchedulerID = 0 + + self.MessageInterval = 2 + self.MessageLastTime = timer.getTime() + + self.Distance = Distance / 1000 + + _EVENTDISPATCHER:OnShot( self._EventShot, self ) + + self.DB = DATABASE:New():FilterStart() + self.DBClients = self.DB.Clients + self.DBUnits = self.DB.Units + + for ClientID, Client in pairs( self.DBClients ) do + + local function _Alive( Client ) + + Client:Message( "Hello trainee, welcome to the Missile Trainer.\nGood luck!", 15, "HELLO WORLD", "Trainer" ) + + + + if self.MenusOnOff == true then + Client:Message( "Use the 'Radio Menu' -> 'Other (F10)' -> 'Missile Trainer' menu options to change the Missile Trainer settings (for all players).", 15, "MENU", "Trainer" ) + + Client.MainMenu = MENU_CLIENT:New( Client, "Missile Trainer", nil ) -- Menu#MENU_CLIENT + + Client.MenuMessages = MENU_CLIENT:New( Client, "Messages", Client.MainMenu ) + Client.MenuOn = MENU_CLIENT_COMMAND:New( Client, "Messages On", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = true } ) + Client.MenuOff = MENU_CLIENT_COMMAND:New( Client, "Messages Off", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = false } ) + + Client.MenuTracking = MENU_CLIENT:New( Client, "Tracking", Client.MainMenu ) + Client.MenuTrackingToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = true } ) + Client.MenuTrackingToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = false } ) + Client.MenuTrackOn = MENU_CLIENT_COMMAND:New( Client, "Tracking On", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = true } ) + Client.MenuTrackOff = MENU_CLIENT_COMMAND:New( Client, "Tracking Off", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = false } ) + + Client.MenuAlerts = MENU_CLIENT:New( Client, "Alerts", Client.MainMenu ) + Client.MenuAlertsToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = true } ) + Client.MenuAlertsToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = false } ) + Client.MenuHitsOn = MENU_CLIENT_COMMAND:New( Client, "Hits On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = true } ) + Client.MenuHitsOff = MENU_CLIENT_COMMAND:New( Client, "Hits Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = false } ) + Client.MenuLaunchesOn = MENU_CLIENT_COMMAND:New( Client, "Launches On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = true } ) + Client.MenuLaunchesOff = MENU_CLIENT_COMMAND:New( Client, "Launches Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = false } ) + + Client.MenuDetails = MENU_CLIENT:New( Client, "Details", Client.MainMenu ) + Client.MenuDetailsDistanceOn = MENU_CLIENT_COMMAND:New( Client, "Range On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = true } ) + Client.MenuDetailsDistanceOff = MENU_CLIENT_COMMAND:New( Client, "Range Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = false } ) + Client.MenuDetailsBearingOn = MENU_CLIENT_COMMAND:New( Client, "Bearing On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = true } ) + Client.MenuDetailsBearingOff = MENU_CLIENT_COMMAND:New( Client, "Bearing Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = false } ) + + Client.MenuDistance = MENU_CLIENT:New( Client, "Set distance to plane", Client.MainMenu ) + Client.MenuDistance50 = MENU_CLIENT_COMMAND:New( Client, "50 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 50 / 1000 } ) + Client.MenuDistance100 = MENU_CLIENT_COMMAND:New( Client, "100 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 100 / 1000 } ) + Client.MenuDistance150 = MENU_CLIENT_COMMAND:New( Client, "150 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 150 / 1000 } ) + Client.MenuDistance200 = MENU_CLIENT_COMMAND:New( Client, "200 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 200 / 1000 } ) + else + if Client.MainMenu then + Client.MainMenu:Remove() + end + end + + + local ClientID = Client:GetID() + self:T( ClientID ) + if not self.TrackingMissiles[ClientID] then + self.TrackingMissiles[ClientID] = {} + end + self.TrackingMissiles[ClientID].Client = Client + if not self.TrackingMissiles[ClientID].MissileData then + self.TrackingMissiles[ClientID].MissileData = {} + end + end + + Client:Alive( _Alive ) + + end + +-- self.DB:ForEachClient( +-- --- @param Client#CLIENT Client +-- function( Client ) +-- +-- ... actions ... +-- +-- end +-- ) + + self.MessagesOnOff = true + + self.TrackingToAll = false + self.TrackingOnOff = true + + self.AlertsToAll = true + self.AlertsHitsOnOff = true + self.AlertsLaunchesOnOff = true + + self.DetailsRangeOnOff = true + self.DetailsBearingOnOff = true + + self.MenusOnOff = true + + self.TrackingMissiles = {} + + self.TrackingScheduler = SCHEDULER:New( self, self._TrackMissiles, {}, 0.5, 0.05, 0 ) + + return self +end + +-- Initialization methods. + + +--- Sets by default the display of any message to be ON or OFF. +-- @param #MISSILETRAINER self +-- @param #boolean MessagesOnOff true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitMessagesOnOff( MessagesOnOff ) + self:F( MessagesOnOff ) + + self.MessagesOnOff = MessagesOnOff + if self.MessagesOnOff == true then + MESSAGE:New( "Messages ON", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Messages OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Sets by default the missile tracking report for all players or only for those missiles targetted to you. +-- @param #MISSILETRAINER self +-- @param #boolean TrackingToAll true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitTrackingToAll( TrackingToAll ) + self:F( TrackingToAll ) + + self.TrackingToAll = TrackingToAll + if self.TrackingToAll == true then + MESSAGE:New( "Missile tracking to all players ON", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Missile tracking to all players OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Sets by default the display of missile tracking report to be ON or OFF. +-- @param #MISSILETRAINER self +-- @param #boolean TrackingOnOff true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitTrackingOnOff( TrackingOnOff ) + self:F( TrackingOnOff ) + + self.TrackingOnOff = TrackingOnOff + if self.TrackingOnOff == true then + MESSAGE:New( "Missile tracking ON", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Missile tracking OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Sets by default the display of alerts to be shown to all players or only to you. +-- @param #MISSILETRAINER self +-- @param #boolean AlertsToAll true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitAlertsToAll( AlertsToAll ) + self:F( AlertsToAll ) + + self.AlertsToAll = AlertsToAll + if self.AlertsToAll == true then + MESSAGE:New( "Alerts to all players ON", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Alerts to all players OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Sets by default the display of hit alerts ON or OFF. +-- @param #MISSILETRAINER self +-- @param #boolean AlertsHitsOnOff true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitAlertsHitsOnOff( AlertsHitsOnOff ) + self:F( AlertsHitsOnOff ) + + self.AlertsHitsOnOff = AlertsHitsOnOff + if self.AlertsHitsOnOff == true then + MESSAGE:New( "Alerts Hits ON", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Alerts Hits OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Sets by default the display of launch alerts ON or OFF. +-- @param #MISSILETRAINER self +-- @param #boolean AlertsLaunchesOnOff true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitAlertsLaunchesOnOff( AlertsLaunchesOnOff ) + self:F( AlertsLaunchesOnOff ) + + self.AlertsLaunchesOnOff = AlertsLaunchesOnOff + if self.AlertsLaunchesOnOff == true then + MESSAGE:New( "Alerts Launches ON", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Alerts Launches OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Sets by default the display of range information of missiles ON of OFF. +-- @param #MISSILETRAINER self +-- @param #boolean DetailsRangeOnOff true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitRangeOnOff( DetailsRangeOnOff ) + self:F( DetailsRangeOnOff ) + + self.DetailsRangeOnOff = DetailsRangeOnOff + if self.DetailsRangeOnOff == true then + MESSAGE:New( "Range display ON", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Range display OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Sets by default the display of bearing information of missiles ON of OFF. +-- @param #MISSILETRAINER self +-- @param #boolean DetailsBearingOnOff true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitBearingOnOff( DetailsBearingOnOff ) + self:F( DetailsBearingOnOff ) + + self.DetailsBearingOnOff = DetailsBearingOnOff + if self.DetailsBearingOnOff == true then + MESSAGE:New( "Bearing display OFF", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Bearing display OFF", "Menu", 15, "ID" ):ToAll() + end + + return self +end + +--- Enables / Disables the menus. +-- @param #MISSILETRAINER self +-- @param #boolean MenusOnOff true or false +-- @return #MISSILETRAINER self +function MISSILETRAINER:InitMenusOnOff( MenusOnOff ) + self:F( MenusOnOff ) + + self.MenusOnOff = MenusOnOff + if self.MenusOnOff == true then + MESSAGE:New( "Menus are ENABLED (only when a player rejoins a slot)", "Menu", 15, "ID" ):ToAll() + else + MESSAGE:New( "Menus are DISABLED", "Menu", 15, "ID" ):ToAll() + end + + return self +end + + +-- Menu functions + +function MISSILETRAINER._MenuMessages( MenuParameters ) + + local self = MenuParameters.MenuSelf + + if MenuParameters.MessagesOnOff ~= nil then + self:InitMessagesOnOff( MenuParameters.MessagesOnOff ) + end + + if MenuParameters.TrackingToAll ~= nil then + self:InitTrackingToAll( MenuParameters.TrackingToAll ) + end + + if MenuParameters.TrackingOnOff ~= nil then + self:InitTrackingOnOff( MenuParameters.TrackingOnOff ) + end + + if MenuParameters.AlertsToAll ~= nil then + self:InitAlertsToAll( MenuParameters.AlertsToAll ) + end + + if MenuParameters.AlertsHitsOnOff ~= nil then + self:InitAlertsHitsOnOff( MenuParameters.AlertsHitsOnOff ) + end + + if MenuParameters.AlertsLaunchesOnOff ~= nil then + self:InitAlertsLaunchesOnOff( MenuParameters.AlertsLaunchesOnOff ) + end + + if MenuParameters.DetailsRangeOnOff ~= nil then + self:InitRangeOnOff( MenuParameters.DetailsRangeOnOff ) + end + + if MenuParameters.DetailsBearingOnOff ~= nil then + self:InitBearingOnOff( MenuParameters.DetailsBearingOnOff ) + end + + if MenuParameters.Distance ~= nil then + self.Distance = MenuParameters.Distance + MESSAGE:New( "Hit detection distance set to " .. self.Distance .. " meters", "Menu", 15, "ID" ):ToAll() + end - _EVENTDISPATCHER:OnShot( self._EventShot, self ) - - return self end --- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME. --- @see MISSILETRAINER +-- @param #MISSILETRAINER self +-- @param Event#EVENTDATA Event function MISSILETRAINER:_EventShot( Event ) - self:F( { Event } ) + self:F( { Event } ) - local TrainerSourceDCSUnit = Event.IniDCSUnit - local TrainerSourceDCSUnitName = Event.IniDCSUnitName - local TrainerWeapon = Event.Weapon -- Identify the weapon fired - local TrainerWeaponName = Event.WeaponName -- return weapon type + local TrainerSourceDCSUnit = Event.IniDCSUnit + local TrainerSourceDCSUnitName = Event.IniDCSUnitName + local TrainerWeapon = Event.Weapon -- Identify the weapon fired + local TrainerWeaponName = Event.WeaponName -- return weapon type - self:T( "Missile Launched = " .. TrainerWeaponName ) + self:T( "Missile Launched = " .. TrainerWeaponName ) - local TrainerTargetDCSUnit = TrainerWeapon:getTarget() -- Identify target - local TrainerTargetDCSUnitName = Unit.getName( TrainerTargetDCSUnit ) - local TrainerTargetDCSGroup = TrainerTargetDCSUnit:getGroup() - local TrainerTargetDCSGroupName = TrainerTargetDCSGroup:getName() - local TrainerTargetSkill = _DATABASE.Units[TrainerTargetDCSUnitName].Template.skill + local TrainerTargetDCSUnit = TrainerWeapon:getTarget() -- Identify target + local TrainerTargetDCSUnitName = Unit.getName( TrainerTargetDCSUnit ) + local TrainerTargetSkill = _DATABASE.Templates.Units[TrainerTargetDCSUnitName].Template.skill - self:T( TrainerTargetSkill ) - - if TrainerTargetSkill == "Client" or TrainerTargetSkill == "Player" then - self.Schedulers[#self.Schedulers+1] = SCHEDULER:New( self, self._FollowMissile, { TrainerSourceDCSUnit, TrainerWeapon, TrainerTargetDCSUnit }, 0.5, 0.05, 0 ) - end + self:T(TrainerTargetDCSUnitName ) + + local Client = self.DBClients[TrainerTargetDCSUnitName] + if Client then + + local TrainerSourceUnit = UNIT:New(TrainerSourceDCSUnit) + local TrainerTargetUnit = UNIT:New(TrainerTargetDCSUnit) + + if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then + + local Message = MESSAGE:New( + string.format( "%s launched a %s", + TrainerSourceUnit:GetTypeName(), + TrainerWeaponName + ) .. self:_AddRange( Client, TrainerWeapon ) .. self:_AddBearing( Client, TrainerWeapon ),"Launch Alert", 5, "ID" ) + + if self.AlertsToAll then + Message:ToAll() + else + Message:ToClient( Client ) + end + end + + local ClientID = Client:GetID() + local MissileData = {} + MissileData.TrainerSourceUnit = TrainerSourceUnit + MissileData.TrainerWeapon = TrainerWeapon + MissileData.TrainerTargetUnit = TrainerTargetUnit + MissileData.TrainerWeaponTypeName = TrainerWeapon:getTypeName() + MissileData.TrainerWeaponLaunched = true + table.insert( self.TrackingMissiles[ClientID].MissileData, MissileData ) + --self:T( self.TrackingMissiles ) + end end -function MISSILETRAINER:_FollowMissile( TrainerSourceDCSUnit, TrainerWeapon, TrainerTargetDCSUnit ) - self:F( { TrainerSourceDCSUnit, TrainerWeapon, TrainerTargetDCSUnit } ) - - local TrainerSourceUnit = UNIT:New( TrainerSourceDCSUnit ) - local TrainerTargetUnit = UNIT:New( TrainerTargetDCSUnit ) +function MISSILETRAINER:_AddRange( Client, TrainerWeapon ) - local PositionMissile = TrainerWeapon:getPoint() - local PositionTarget = TrainerTargetUnit:GetPositionVec3() - - local Distance = ( ( PositionMissile.x - PositionTarget.x )^2 + - ( PositionMissile.y - PositionTarget.y )^2 + - ( PositionMissile.z - PositionTarget.z )^2 - ) ^ 0.5 + local RangeText = "" + + if self.DetailsRangeOnOff then + + local PositionMissile = TrainerWeapon:getPoint() + local PositionTarget = Client:GetPositionVec3() + + local Range = ( ( PositionMissile.x - PositionTarget.x )^2 + + ( PositionMissile.y - PositionTarget.y )^2 + + ( PositionMissile.z - PositionTarget.z )^2 + ) ^ 0.5 / 1000 + + RangeText = string.format( ", at %4.2fkm", Range ) + end + + return RangeText +end + +function MISSILETRAINER:_AddBearing( Client, TrainerWeapon ) + + local BearingText = "" + + if self.DetailsBearingOnOff then + + local PositionMissile = TrainerWeapon:getPoint() + local PositionTarget = Client:GetPositionVec3() + + self:T2( { PositionTarget, PositionMissile }) + + local DirectionVector = { x = PositionMissile.x - PositionTarget.x, y = PositionMissile.y - PositionTarget.y, z = PositionMissile.z - PositionTarget.z } + local DirectionRadians = math.atan2( DirectionVector.z, DirectionVector.x ) + --DirectionRadians = DirectionRadians + routines.getNorthCorrection( PositionTarget ) + if DirectionRadians < 0 then + DirectionRadians = DirectionRadians + 2 * math.pi + end + local DirectionDegrees = DirectionRadians * 180 / math.pi + + BearingText = string.format( ", %d degrees", DirectionDegrees ) + end + + return BearingText +end + + +--- +-- @param #MISSILETRAINER self +function MISSILETRAINER:_TrackMissiles() + self:F2() + + + local ShowMessages = false + if self.MessagesOnOff and self.MessageLastTime + 3 <= timer.getTime() then + self.MessageLastTime = timer.getTime() + ShowMessages = true + end + + for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do + + local Client = ClientData.Client + self:T2( { Client:GetName() } ) + + + ClientData.MessageToClient = "" + ClientData.MessageToAll = "" + + for TrackingDataID, TrackingData in pairs( self.TrackingMissiles ) do + + for MissileDataID, MissileData in pairs( TrackingData.MissileData ) do + self:T3( MissileDataID ) + + local TrainerSourceUnit = MissileData.TrainerSourceUnit + local TrainerWeapon = MissileData.TrainerWeapon + local TrainerTargetUnit = MissileData.TrainerTargetUnit + local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName + local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched + + if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then + local PositionMissile = TrainerWeapon:getPosition().p + local PositionTarget = Client:GetPositionVec3() + + local Distance = ( ( PositionMissile.x - PositionTarget.x )^2 + + ( PositionMissile.y - PositionTarget.y )^2 + + ( PositionMissile.z - PositionTarget.z )^2 + ) ^ 0.5 / 1000 + + if Distance <= self.Distance then + -- Hit alert + TrainerWeapon:destroy() + if self.MessagesOnOff == true and self.AlertsHitsOnOff == true then + + self:T( "killed" ) + + local Message = MESSAGE:New( + string.format( "%s launched by %s killed %s", + TrainerWeapon:getTypeName(), + TrainerSourceUnit:GetTypeName(), + TrainerTargetUnit:GetPlayerName() + ),"Hit Alert", 15, "ID" ) + + if self.AlertsToAll == true then + Message:ToAll() + else + Message:ToClient( Client ) + end + + MissileData = nil + table.remove( TrackingData.MissileData, MissileDataID ) + self:T(TrackingData.MissileData) + end + else + if ShowMessages == true then + local TrackingTo + TrackingTo = string.format( " -> %s", + TrainerWeaponTypeName + ) + + if ClientDataID == TrackingDataID then + if ClientData.MessageToClient == "" then + ClientData.MessageToClient = "Missiles to You:\n" + end + ClientData.MessageToClient = ClientData.MessageToClient .. TrackingTo .. self:_AddRange( ClientData.Client, TrainerWeapon ) .. self:_AddBearing( ClientData.Client, TrainerWeapon ) .. "\n" + else + if self.TrackingToAll == true then + if ClientData.MessageToAll == "" then + ClientData.MessageToAll = "Missiles to other Players:\n" + end + ClientData.MessageToAll = ClientData.MessageToAll .. TrackingTo .. self:_AddRange( ClientData.Client, TrainerWeapon ) .. self:_AddBearing( ClientData.Client, TrainerWeapon ) .. " ( " .. TrainerTargetUnit:GetPlayerName() .. " )\n" + end + end + end + end + else + if not ( TrainerWeapon and TrainerWeapon:isExist() ) then + if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then + -- Weapon does not exist anymore. Delete from Table + local Message = MESSAGE:New( + string.format( "%s launched by %s self destructed!", + TrainerWeaponTypeName, + TrainerSourceUnit:GetTypeName() + ),"Tracking", 5, "ID" ) + + if self.AlertsToAll == true then + Message:ToAll() + else + Message:ToClient( Client ) + end + end + MissileData = nil + table.remove( TrackingData.MissileData, MissileDataID ) + self:T(TrackingData.MissileData) + end + end + end + end + + if self.MessagesOnOff == true and self.TrackingOnOff == true and ShowMessages == true then + if ClientData.MessageToClient ~= "" or ClientData.MessageToAll ~= "" then + local Message = MESSAGE:New( ClientData.MessageToClient .. ClientData.MessageToAll, "Tracking", 1, "ID" ):ToClient( Client ) + end + end - MESSAGE:New( "Distance Missle = " .. Distance, nil, 0.2, "/Missile" ):ToAll() - - if Distance <= self.Distance then - TrainerWeapon:destroy() - MESSAGE:New( "Missle Destroyed", nil, 5, "/Missile" ):ToAll() - return false end return true diff --git a/Loaders/Moose_Load_Embedded.lua b/Loaders/Moose_Load_Embedded.lua index 3aa464d98..87ccd7151 100644 --- a/Loaders/Moose_Load_Embedded.lua +++ b/Loaders/Moose_Load_Embedded.lua @@ -1,4 +1,3 @@ - local base = _G env.info("Loading MOOSE " .. base.timer.getAbsTime() ) diff --git a/Maths/Bearing calculation.ggb b/Maths/Bearing calculation.ggb new file mode 100644 index 000000000..affc37c06 Binary files /dev/null and b/Maths/Bearing calculation.ggb differ diff --git a/Moose/Client.lua b/Moose/Client.lua index bc444e5c5..f608e8673 100644 --- a/Moose/Client.lua +++ b/Moose/Client.lua @@ -1,6 +1,18 @@ --- The CLIENT models client units in multi player missions. --- Clients are those groups defined within the Mission Editor that have the skillset defined as "Client" or "Player". --- Note that clients are NOT the same as groups, they are NOT necessarily alive. +-- +-- @{#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. +-- +-- 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. +-- -- @module Client -- @author FlightControl @@ -33,9 +45,9 @@ CLIENT = { } ---- Use this method to register new Clients within the MOF. +--- Use this method to register new Clients within a mission. -- @param #CLIENT self --- @param #string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client. +-- @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 @@ -51,7 +63,7 @@ function CLIENT:New( ClientName, ClientBriefing ) local self = BASE:Inherit( self, BASE:New() ) self:F( ClientName, ClientBriefing ) - self.ClientName = ClientName + self.ClientName = ClientName self:AddBriefing( ClientBriefing ) self.MessageSwitch = true @@ -132,9 +144,9 @@ end function CLIENT:IsAlive() self:F( self.ClientName ) - local ClientDCSGroup = self:GetDCSGroup() + local ClientUnit = Unit.getByName( self.ClientName ) - if ClientDCSGroup then + if ClientUnit and ClientUnit:isExist() then self:T("true") return true end @@ -176,6 +188,8 @@ function CLIENT:GetDCSGroup() -- return nil -- end + local ClientUnit = Unit.getByName( self.ClientName ) + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } for CoalitionId, CoalitionData in pairs( CoalitionsData ) do self:T3( { "CoalitionData:", CoalitionData } ) @@ -183,49 +197,49 @@ function CLIENT:GetDCSGroup() self:T3( { "UnitData:", UnitData } ) if UnitData and UnitData:isExist() then - local ClientGroup = Group.getByName( self.ClientName ) - if ClientGroup then - self:T3( "ClientGroup = " .. self.ClientName ) - if ClientGroup:isExist() then - if ClientGroup:getID() == UnitData:getGroup():getID() then - self:T3( "Normal logic" ) - self:T3( self.ClientName .. " : group found!" ) - return ClientGroup - end - else - -- Now we need to resolve the bugs in DCS 1.5 ... - -- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil) - self:T3( "Bug 1.5 logic" ) - local ClientUnits = _DATABASE.Groups[self.ClientName].Units - self:T3( { ClientUnits[1].name, env.getValueDictByKey(ClientUnits[1].name) } ) - for ClientUnitID, ClientUnitData in pairs( ClientUnits ) do - self:T3( { tonumber(UnitData:getID()), ClientUnitData.unitId } ) - if tonumber(UnitData:getID()) == ClientUnitData.unitId then - local ClientGroupTemplate = _DATABASE.Groups[self.ClientName].Template - self.ClientID = ClientGroupTemplate.groupId - self.ClientGroupUnit = UnitData - self:T3( self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) - return ClientGroup - end - end - end --- else --- error( "Client " .. self.ClientName .. " not found!" ) - end + --self:E(self.ClientName) + if ClientUnit then + local ClientGroup = ClientUnit:getGroup() + if ClientGroup then + self:T3( "ClientGroup = " .. self.ClientName ) + if ClientGroup:isExist() and UnitData:getGroup():isExist() then + if ClientGroup:getID() == UnitData:getGroup():getID() then + self:T3( "Normal logic" ) + self:T3( self.ClientName .. " : group found!" ) + self.ClientGroupID = ClientGroup:getID() + self.ClientGroupName = ClientGroup:getName() + return ClientGroup + end + else + -- Now we need to resolve the bugs in DCS 1.5 ... + -- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil) + self:T3( "Bug 1.5 logic" ) + local ClientGroupTemplate = _DATABASE.Templates.Units[self.ClientName].GroupTemplate + self.ClientGroupID = ClientGroupTemplate.groupId + self.ClientGroupName = _DATABASE.Templates.Units[self.ClientName].GroupName + self:T3( self.ClientName .. " : group found in bug 1.5 resolvement logic!" ) + return ClientGroup + end + -- else + -- error( "Client " .. self.ClientName .. " not found!" ) + end + end end end end -- For non player clients - local ClientGroup = Group.getByName( self.ClientName ) - if ClientGroup then - self:T3( "ClientGroup = " .. self.ClientName ) - if ClientGroup:isExist() then - self:T3( "Normal logic" ) - self:T3( self.ClientName .. " : group found!" ) - return ClientGroup - end - end + if ClientUnit then + local ClientGroup = ClientUnit:getGroup() + if ClientGroup then + self:T3( "ClientGroup = " .. self.ClientName ) + if ClientGroup:isExist() then + self:T3( "Normal logic" ) + self:T3( self.ClientName .. " : group found!" ) + return ClientGroup + end + end + end self.ClientGroupID = nil self.ClientGroupUnit = nil @@ -240,16 +254,9 @@ end -- @return DCSTypes#Group.ID function CLIENT:GetClientGroupID() - if not self.ClientGroupID then - local ClientGroup = self:GetDCSGroup() - if ClientGroup and ClientGroup:isExist() then - self.ClientGroupID = ClientGroup:getID() - else - self.ClientGroupID = self.ClientID - end - end + local ClientGroup = self:GetDCSGroup() - self:T( self.ClientGroupID ) + --self:E( self.ClientGroupID ) -- Determined in GetDCSGroup() return self.ClientGroupID end @@ -259,16 +266,9 @@ end -- @return #string function CLIENT:GetClientGroupName() - if not self.ClientGroupName then - local ClientGroup = self:GetDCSGroup() - if ClientGroup and ClientGroup:isExist() then - self.ClientGroupName = ClientGroup:getName() - else - self.ClientGroupName = self.ClientName - end - end + local ClientGroup = self:GetDCSGroup() - self:T( self.ClientGroupName ) + self:T( self.ClientGroupName ) -- Determined in GetDCSGroup() return self.ClientGroupName end @@ -276,14 +276,15 @@ end -- @param #CLIENT self -- @return Unit#UNIT function CLIENT:GetClientGroupUnit() - self:F() + self:F2() - local ClientGroup = self:GetDCSGroup() - - if ClientGroup and ClientGroup:isExist() then - return UNIT:New( ClientGroup:getUnit(1) ) - else - return UNIT:New( self.ClientGroupUnit ) + local ClientDCSUnit = Unit.getByName( self.ClientName ) + + self:T( self.ClientDCSUnit ) + if ClientDCSUnit and ClientDCSUnit:isExist() then + local ClientUnit = _DATABASE.Units[ self.ClientName ] + self:T2( ClientUnit ) + return ClientUnit end end @@ -293,12 +294,11 @@ end function CLIENT:GetClientGroupDCSUnit() self:F2() - local ClientGroup = self:GetDCSGroup() + local ClientDCSUnit = Unit.getByName( self.ClientName ) - if ClientGroup and ClientGroup:isExist() then - return ClientGroup:getUnit(1) - else - return self.ClientGroupUnit + if ClientDCSUnit and ClientDCSUnit:isExist() then + self:T2( ClientDCSUnit ) + return ClientDCSUnit end end @@ -315,7 +315,7 @@ end function CLIENT:GetPointVec2() self:F() - ClientGroupUnit = self:GetClientGroupDCSUnit() + local ClientGroupUnit = self:GetClientGroupDCSUnit() if ClientGroupUnit then if ClientGroupUnit:isExist() then @@ -331,6 +331,44 @@ function CLIENT:GetPointVec2() return nil end +function CLIENT:GetPositionVec3() + self:F( self.ClientName ) + + local DCSUnit = Unit.getByName( self.ClientName ) + local UnitPos = DCSUnit:getPosition().p + + self:T( UnitPos ) + return UnitPos +end + +function CLIENT:GetID() + self:F( self.ClientName ) + + local DCSUnit = Unit.getByName( self.ClientName ) + local UnitID = DCSUnit:getID() + + self:T( UnitID ) + return UnitID +end + +function CLIENT:GetName() + self:F( self.ClientName ) + + self:T( self.ClientName ) + return self.ClientName +end + +function CLIENT:GetTypeName() + self:F( self.ClientName ) + + local DCSUnit = Unit.getByName( self.ClientName ) + local TypeName = DCSUnit:getTypeName() + + self:T( TypeName ) + return TypeName +end + + --- Returns the position of the CLIENT in @{DCSTypes#Vec3} format. -- @param #CLIENT self @@ -338,7 +376,7 @@ end function CLIENT:ClientPosition() self:F() - ClientGroupUnit = self:GetClientGroupDCSUnit() + local ClientGroupUnit = self:GetClientGroupDCSUnit() if ClientGroupUnit then if ClientGroupUnit:isExist() then @@ -355,7 +393,7 @@ end function CLIENT:GetAltitude() self:F() - ClientGroupUnit = self:GetClientGroupDCSUnit() + local ClientGroupUnit = self:GetClientGroupDCSUnit() if ClientGroupUnit then if ClientGroupUnit:isExist() then diff --git a/Moose/Database.lua b/Moose/Database.lua index 631bd665b..bca8306b1 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -66,25 +66,35 @@ Include.File( "Routines" ) Include.File( "Base" ) Include.File( "Menu" ) Include.File( "Group" ) +Include.File( "Unit" ) Include.File( "Event" ) +Include.File( "Client" ) --- DATABASE class -- @type DATABASE -- @extends Base#BASE DATABASE = { ClassName = "DATABASE", + Templates = { + Units = {}, + Groups = {}, + ClientsByName = {}, + ClientsByID = {}, + }, DCSUnits = {}, DCSUnitsAlive = {}, - Units = {}, - Groups = {}, DCSGroups = {}, DCSGroupsAlive = {}, + Units = {}, + UnitsAlive = {}, + Groups = {}, + GroupsAlive = {}, NavPoints = {}, Statics = {}, Players = {}, - AlivePlayers = {}, - ClientsByName = {}, - ClientsByID = {}, + PlayersAlive = {}, + Clients = {}, + ClientsAlive = {}, Filter = { Coalitions = nil, Categories = nil, @@ -140,6 +150,14 @@ function DATABASE:New() _EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self ) _EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self ) + + -- Add database with registered clients and already alive players + + -- Follow alive players and clients + _EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self ) + _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self ) + + return self end @@ -260,16 +278,43 @@ function DATABASE:FilterStart() -- OK, we have a _DATABASE -- Now use the different filters to build the set. -- We first take ALL of the Units of the _DATABASE. - for UnitRegistrationID, UnitRegistration in pairs( _DATABASE.Units ) do - self:T( UnitRegistration ) - local DCSUnit = Unit.getByName( UnitRegistration.UnitName ) + + self:E( { "Adding Database Datapoints with filters" } ) + for DCSUnitName, DCSUnit in pairs( _DATABASE.DCSUnits ) do + if self:_IsIncludeDCSUnit( DCSUnit ) then - self.DCSUnits[DCSUnit:getName()] = DCSUnit - end - if self:_IsAliveDCSUnit( DCSUnit ) then - self.DCSUnitsAlive[DCSUnit:getName()] = DCSUnit + + 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 @@ -318,7 +363,7 @@ end function DATABASE:SetStatusGroup( GroupName, Status ) self:F( Status ) - self.Groups[GroupName].Status = Status + self.Templates.Groups[GroupName].Status = Status end @@ -326,8 +371,8 @@ end function DATABASE:GetStatusGroup( GroupName ) self:F( Status ) - if self.Groups[GroupName] then - return self.Groups[GroupName].Status + if self.Templates.Groups[GroupName] then + return self.Templates.Groups[GroupName].Status else return "" end @@ -341,9 +386,9 @@ function DATABASE:_RegisterGroup( GroupTemplate ) local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name) - if not self.Groups[GroupTemplateName] then - self.Groups[GroupTemplateName] = {} - self.Groups[GroupTemplateName].Status = nil + if not self.Templates.Groups[GroupTemplateName] then + self.Templates.Groups[GroupTemplateName] = {} + self.Templates.Groups[GroupTemplateName].Status = nil end -- Delete the spans from the route, it is not needed and takes memory. @@ -351,31 +396,102 @@ function DATABASE:_RegisterGroup( GroupTemplate ) GroupTemplate.route.spans = nil end - self.Groups[GroupTemplateName].GroupName = GroupTemplateName - self.Groups[GroupTemplateName].Template = GroupTemplate - self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId - self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units - self.Groups[GroupTemplateName].Units = GroupTemplate.units + self.Templates.Groups[GroupTemplateName].GroupName = GroupTemplateName + self.Templates.Groups[GroupTemplateName].Template = GroupTemplate + self.Templates.Groups[GroupTemplateName].groupId = GroupTemplate.groupId + self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units + self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units - self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } ) + self:T( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } ) - for unit_num, UnitTemplate in pairs(GroupTemplate.units) do + for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name) - self.Units[UnitTemplateName] = {} - self.Units[UnitTemplateName].UnitName = UnitTemplateName - self.Units[UnitTemplateName].Template = UnitTemplate - self.Units[UnitTemplateName].GroupName = GroupTemplateName - self.Units[UnitTemplateName].GroupTemplate = GroupTemplate - self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId + self.Templates.Units[UnitTemplateName] = {} + self.Templates.Units[UnitTemplateName].UnitName = UnitTemplateName + self.Templates.Units[UnitTemplateName].Template = UnitTemplate + self.Templates.Units[UnitTemplateName].GroupName = GroupTemplateName + self.Templates.Units[UnitTemplateName].GroupTemplate = GroupTemplate + self.Templates.Units[UnitTemplateName].GroupId = GroupTemplate.groupId + self:E( {"skill",UnitTemplate.skill}) if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then - self.ClientsByName[UnitTemplateName] = UnitTemplate - self.ClientsByID[UnitTemplate.unitId] = UnitTemplate + self.Templates.ClientsByName[UnitTemplateName] = UnitTemplate + self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate end - self:E( { "Unit", self.Units[UnitTemplateName].UnitName } ) + self:E( { "Unit", self.Templates.Units[UnitTemplateName].UnitName } ) end end +--- Private method that registers all alive players in the mission. +-- @param #DATABASE self +-- @return #DATABASE self +function DATABASE:_RegisterPlayers() + + local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for UnitId, UnitData in pairs( CoalitionData ) do + self:T3( { "UnitData:", UnitData } ) + if UnitData and UnitData:isExist() then + local UnitName = UnitData:getName() + if not self.PlayersAlive[UnitName] then + self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } ) + self.PlayersAlive[UnitName] = UnitData:getPlayerName() + end + end + end + end + + return self +end + +--- Private method that registers all datapoints within in the mission. +-- @param #DATABASE self +-- @return #DATABASE self +function DATABASE:_RegisterDatabase() + + local CoalitionsData = { AlivePlayersRed = coalition.getGroups( coalition.side.RED ), AlivePlayersBlue = coalition.getGroups( coalition.side.BLUE ) } + for CoalitionId, CoalitionData in pairs( CoalitionsData ) do + for DCSGroupId, DCSGroup in pairs( CoalitionData ) do + + local DCSGroupName = DCSGroup:getName() + + self:E( { "Register Group:", DCSGroup, DCSGroupName } ) + self.DCSGroups[DCSGroupName] = DCSGroup + self.Groups[DCSGroupName] = GROUP:New( DCSGroup ) + + if self:_IsAliveDCSGroup(DCSGroup) then + self:E( { "Register Alive Group:", DCSGroup, DCSGroupName } ) + self.DCSGroupsAlive[DCSGroupName] = DCSGroup + self.GroupsAlive[DCSGroupName] = self.Groups[DCSGroupName] + end + + for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do + + local DCSUnitName = DCSUnit:getName() + self:E( { "Register Unit:", DCSUnit, DCSUnitName } ) + + self.DCSUnits[DCSUnitName] = DCSUnit + self.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 + end + + for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do + self.Clients[ClientName] = CLIENT:New( ClientName ) + end + end + end + + return self +end + + +--- Events + --- Handles the OnBirth event for the alive units set. -- @param #DATABASE self -- @param Event#EVENTDATA Event @@ -385,7 +501,15 @@ 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.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:_EventOnPlayerEnterUnit( Event ) end end end @@ -404,18 +528,54 @@ function DATABASE:_EventOnDeadOrCrash( Event ) end end ---- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied). -- @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. +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnPlayerEnterUnit( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then + if not self.PlayersAlive[Event.IniDCSUnitName] then + self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) + self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName() + self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ] + end + end + end +end + +--- Handles the OnPlayerLeaveUnit event to clean the active players table. +-- @param #DATABASE self +-- @param Event#EVENTDATA Event +function DATABASE:_EventOnPlayerLeaveUnit( Event ) + self:F( { Event } ) + + if Event.IniDCSUnit then + if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then + if self.PlayersAlive[Event.IniDCSUnitName] then + self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } ) + self.PlayersAlive[Event.IniDCSUnitName] = nil + self.ClientsAlive[Event.IniDCSUnitName] = nil + end + end + end +end + +--- Iterators + +--- Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. -- @return #DATABASE self -function DATABASE:ForEachAliveUnit( IteratorFunction, ... ) +function DATABASE:ForEach( IteratorFunction, arg, Set ) self:F( arg ) local function CoRoutine() local Count = 0 - for DCSUnitID, DCSUnit in pairs( self.DCSUnitsAlive ) do - self:T2( DCSUnit ) - IteratorFunction( DCSUnit, unpack( arg ) ) + for ObjectID, Object in pairs( Set ) do + self:T2( Object ) + IteratorFunction( Object, unpack( arg ) ) Count = Count + 1 if Count % 10 == 0 then coroutine.yield( false ) @@ -435,15 +595,56 @@ function DATABASE:ForEachAliveUnit( IteratorFunction, ... ) error( res ) end if res == false then - timer.scheduleFunction( Schedule, {}, timer.getTime() + 0.001 ) + return true -- resume next time the loop end + + return false end - timer.scheduleFunction( Schedule, {}, timer.getTime() + 1 ) + local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 ) return self end + +--- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters. +-- @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, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive ) + + return self +end + +--- Interate the DATABASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter. +-- @return #DATABASE self +function DATABASE:ForEachPlayer( IteratorFunction, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.PlayersAlive ) + + return self +end + + +--- Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters. +-- @param #DATABASE self +-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter. +-- @return #DATABASE self +function DATABASE:ForEachClient( IteratorFunction, ... ) + self:F( arg ) + + self:ForEach( IteratorFunction, arg, self.Clients ) + + return self +end + + function DATABASE:ScanEnvironment() self:F() @@ -507,6 +708,9 @@ function DATABASE:ScanEnvironment() end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then end --for coa_name, coa_data in pairs(mission.coalition) do + self:_RegisterDatabase() + self:_RegisterPlayers() + return self end @@ -594,6 +798,22 @@ function DATABASE:_IsAliveDCSUnit( DCSUnit ) return DCSUnitAlive end +--- +-- @param #DATABASE self +-- @param DCSGroup#Group DCSGroup +-- @return #DATABASE self +function DATABASE:_IsAliveDCSGroup( DCSGroup ) + self:F( DCSGroup ) + local DCSGroupAlive = false + if DCSGroup and DCSGroup:isExist() then + if self.DCSGroups[DCSGroup:getName()] then + DCSGroupAlive = true + end + end + self:T( DCSGroupAlive ) + return DCSGroupAlive +end + --- Traces the current database contents in the log ... (for debug reasons). -- @param #DATABASE self diff --git a/Moose/Event.lua b/Moose/Event.lua index a18d4d22b..f7c2a0649 100644 --- a/Moose/Event.lua +++ b/Moose/Event.lua @@ -437,6 +437,32 @@ function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf ) return self end +--- Set a new listener for an S_EVENT_PLAYER_ENTER_UNIT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnPlayerEnterUnit( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_ENTER_UNIT ) + + return self +end + +--- Set a new listener for an S_EVENT_PLAYER_LEAVE_UNIT event. +-- @param #EVENT self +-- @param #function EventFunction The function to be called when the event occurs for the unit. +-- @param Base#BASE EventSelf The self instance of the class for which the event is. +-- @return #EVENT +function EVENT:OnPlayerLeaveUnit( EventFunction, EventSelf ) + self:F() + + self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_LEAVE_UNIT ) + + return self +end + function EVENT:onEvent( Event ) @@ -468,6 +494,7 @@ function EVENT:onEvent( Event ) Event.WeaponName = Event.Weapon:getTypeName() --Event.WeaponTgtDCSUnit = Event.Weapon:getTarget() end + self:E( { _EVENTCODES[Event.id], Event } ) for ClassName, EventData in pairs( self.Events[Event.id] ) do if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then self:T2( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } ) diff --git a/Moose/Group.lua b/Moose/Group.lua index e93f50b69..a886d75b3 100644 --- a/Moose/Group.lua +++ b/Moose/Group.lua @@ -1084,7 +1084,7 @@ end function GROUP:GetTaskMission() self:F( self.GroupName ) - return routines.utils.deepCopy( _DATABASE.Groups[self.GroupName].Template ) + return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template ) end --- Return the mission route of the group. @@ -1093,7 +1093,7 @@ end function GROUP:GetTaskRoute() self:F( self.GroupName ) - return routines.utils.deepCopy( _DATABASE.Groups[self.GroupName].Template.route.points ) + return routines.utils.deepCopy( _DATABASE.Templates.Groups[self.GroupName].Template.route.points ) end --- Return the route of a group by using the @{Database#DATABASE} class. @@ -1117,7 +1117,7 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius ) self:T( { GroupName } ) - local Template = _DATABASE.Groups[GroupName].Template + local Template = _DATABASE.Templates.Groups[GroupName].Template if Template then if not Begin then diff --git a/Moose/Routines.lua b/Moose/Routines.lua index 059f60544..834d2d5b3 100644 --- a/Moose/Routines.lua +++ b/Moose/Routines.lua @@ -1737,7 +1737,7 @@ function routines.getGroupRoute(groupIdent, task) -- same as getGroupPoints bu -- refactor to search by groupId and allow groupId and groupName as inputs local gpId = groupIdent if type(groupIdent) == 'string' and not tonumber(groupIdent) then - gpId = _DATABASE.Groups[groupIdent].groupId + gpId = _DATABASE.Templates.Groups[groupIdent].groupId end for coa_name, coa_data in pairs(env.mission.coalition) do diff --git a/Moose/Sead.lua b/Moose/Sead.lua index d89c47cf0..dd47ff2e5 100644 --- a/Moose/Sead.lua +++ b/Moose/Sead.lua @@ -67,7 +67,7 @@ function SEAD:EventShot( Event ) local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon)) local _targetMimgroupName = _targetMimgroup:getName() local _targetMimcont= _targetMimgroup:getController() - local _targetskill = _DATABASE.Units[_targetMimname].Template.skill + local _targetskill = _DATABASE.Templates.Units[_targetMimname].Template.skill self:T( self.SEADGroupPrefixes ) self:T( _targetMimgroupName ) local SEADGroupFound = false diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index 364fad3f9..afe13cae3 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -954,7 +954,7 @@ function SPAWN:_GetTemplate( SpawnTemplatePrefix ) local SpawnTemplate = nil - SpawnTemplate = routines.utils.deepCopy( _DATABASE.Groups[SpawnTemplatePrefix].Template ) + SpawnTemplate = routines.utils.deepCopy( _DATABASE.Templates.Groups[SpawnTemplatePrefix].Template ) if SpawnTemplate == nil then error( 'No Template returned for SpawnTemplatePrefix = ' .. SpawnTemplatePrefix ) diff --git a/Moose/Unit.lua b/Moose/Unit.lua index a6091a77c..fcd99cdd4 100644 --- a/Moose/Unit.lua +++ b/Moose/Unit.lua @@ -56,11 +56,13 @@ UNIT = { -- @return Unit#UNIT function UNIT:New( DCSUnit ) local self = BASE:Inherit( self, BASE:New() ) - self:F( DCSUnit:getName() ) + self:F( DCSUnit ) self.DCSUnit = DCSUnit - self.UnitName = DCSUnit:getName() - self.UnitID = DCSUnit:getID() + if DCSUnit then + self.UnitName = DCSUnit:getName() + self.UnitID = DCSUnit:getID() + end return self end @@ -91,6 +93,18 @@ function UNIT:GetName() 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 = "" + end + + return PlayerName +end function UNIT:GetTypeName() self:F( self.UnitName ) diff --git a/Tools and Installation/DCS World - MOOSE - Development - Part 1 - Tools and Installation.pptx b/Presentations/DCS World - MOOSE - Development - Part 1 - Tools and Installation.pptx similarity index 100% rename from Tools and Installation/DCS World - MOOSE - Development - Part 1 - Tools and Installation.pptx rename to Presentations/DCS World - MOOSE - Development - Part 1 - Tools and Installation.pptx diff --git a/Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE - Copy.pptx b/Presentations/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE - Copy.pptx similarity index 100% rename from Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE - Copy.pptx rename to Presentations/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE - Copy.pptx diff --git a/Tools and Installation/DCS World - MOOSE - Escorting - Part 2 - APIs.pptx b/Presentations/DCS World - MOOSE - Escorting - Part 2 - APIs.pptx similarity index 100% rename from Tools and Installation/DCS World - MOOSE - Escorting - Part 2 - APIs.pptx rename to Presentations/DCS World - MOOSE - Escorting - Part 2 - APIs.pptx diff --git a/Presentations/DCS World - MOOSE - Missile Trainer.pptx b/Presentations/DCS World - MOOSE - Missile Trainer.pptx new file mode 100644 index 000000000..e894e5374 Binary files /dev/null and b/Presentations/DCS World - MOOSE - Missile Trainer.pptx differ diff --git a/Tools and Installation/DCS World - MOOSE - Spawning - Part 2 - APIs.pptx b/Presentations/DCS World - MOOSE - Spawning - Part 2 - APIs.pptx similarity index 100% rename from Tools and Installation/DCS World - MOOSE - Spawning - Part 2 - APIs.pptx rename to Presentations/DCS World - MOOSE - Spawning - Part 2 - APIs.pptx diff --git a/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.lua b/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.lua index 2aaabf1ff..03d19e4ec 100644 --- a/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.lua +++ b/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.lua @@ -1,6 +1,20 @@ - -Include.File("Moose") +-- Only use Include.File when developing new MOOSE classes. +-- When using Moose.lua in the DO SCIPTS FILE initialization box, +-- these Include.File statements are not needed, because all classes within Moose will be loaded. Include.File("MissileTrainer") -local Trainer = MISSILETRAINER:New( 200 ) \ No newline at end of file +-- This is an example of a global +local Trainer = MISSILETRAINER + :New( 200 ) + :InitMessagesOnOff(true) + :InitAlertsToAll(true) -- I'll correct it below ... + :InitAlertsHitsOnOff(true) + :InitAlertsLaunchesOnOff(false) + :InitBearingOnOff(true) + :InitRangeOnOff(true) + :InitTrackingOnOff(true) + :InitTrackingToAll(true) + :InitMenusOnOff(false) + +--Trainer:InitAlertsToAll(true) -- Now alerts are also on diff --git a/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz b/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz index b1b93909d..1b10c6b63 100644 Binary files a/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz and b/Test Missions/Moose_Test_MISSILETRAINER/Moose_Test_MISSILETRAINER.miz differ
    SPAWN.AliveFactor - -
    SPAWN:Array(SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY)

    Makes the groups visible before start (like a batallion).

    @@ -182,7 +164,7 @@ Check the SPAWN.CleanUp for further info.

    SPAWN.CleanUpFunctionSPAWN.CleanUpScheduler SPAWN:GetSpawnIndexFromGroup(SpawnGroup)

    Get the index from a given group.

    +
    SPAWN:InitRepeat() +

    For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.

    +
    SPAWN:InitRepeatOnEngineShutDown() +

    Respawn after landing when its engines have shut down.

    +
    SPAWN:InitRepeatOnLanding() +

    Respawn group after landing.

    SPAWN:Repeat()SPAWN.Repeat -

    For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.

    +
    SPAWN.SpawnCleanUpTimeStamps -
    SPAWN.SpawnCurrentTimer -
    SPAWN:SpawnGroupName(SpawnIndex)

    Will return the SpawnGroupName either with with a specific count number or without any count.

    -
    SPAWN.SpawnHighTimer -
    SPAWN:SpawnInZone(Zone, ZoneRandomize, SpawnIndex)

    Will spawn a Group within a given Zone#ZONE.

    -
    SPAWN.SpawnLowTimer -
    SPAWN.SpawnRandomizeTemplate -
    SPAWN.SpawnRepeat -
    SPAWN:SpawnScheduleStart() -

    Will start the spawning scheduler.

    +

    Will re-start the spawning scheduler.

    SPAWN.SpawnSetTimerSPAWN.SpawnScheduler
    SPAWN:_RandomizeRoute(SpawnIndex) -

    Internal function randomizing the routes.

    +

    Private method randomizing the routes.

    SPAWN:_RandomizeTemplate(SpawnIndex) - +

    Private method that randomizes the template of the group.

    UNIT:GetName() +
    UNIT:GetPlayerName() +
    ZONE:GetPointVec2() +
    ZONE:GetPointVec3(Height) +
    Client

    The CLIENT models client units in multi player missions.

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

    Message System to display Messages for Clients and Coalitions or All.

    +
    MissileTrainer +

    Provides missile training functions.

    STAGE

    Stages within a TASK within a MISSION.

    +
    Scheduler +

    Models time events calling event handing functions.

    Spawn

    Dynamic spawning of groups (and units).

    -
    StaticObject -
    Zone

    ZONE Classes

    -
    env - -
    land -