diff --git a/.gitignore b/.gitignore index 00c7e867e..22e90135a 100644 --- a/.gitignore +++ b/.gitignore @@ -220,3 +220,7 @@ pip-log.txt #Goodsync _gsdata_/ + +#GITHUB +.gitattributes +.gitignore diff --git a/Documentation/Base.html b/Documentation/Base.html index 88242a92c..acc2db22f 100644 --- a/Documentation/Base.html +++ b/Documentation/Base.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -204,6 +205,24 @@ BASE:T3(Arguments)

    Trace a function logic level 3.

    + + + + BASE:TraceClass(Class) + +

    Set tracing for a class

    + + + + BASE:TraceClassMethod(Class, Method) + +

    Set tracing for a specific method of class

    + + + + BASE:TraceLevel(Level) + +

    Set trace level

    @@ -747,6 +766,74 @@ A #table or any field.

    + +BASE:TraceClass(Class) + +
    +
    + +

    Set tracing for a class

    + +

    Parameter

    + +
    +
    +
    +
    + + +BASE:TraceClassMethod(Class, Method) + +
    +
    + +

    Set tracing for a specific method of class

    + +

    Parameters

    + +
    +
    +
    +
    + + +BASE:TraceLevel(Level) + +
    +
    + +

    Set trace level

    + +

    Parameter

    + +
    +
    +
    +
    + BASE:onEvent(event) diff --git a/Documentation/CARGO.html b/Documentation/CARGO.html index 73e58971e..d8ed385dc 100644 --- a/Documentation/CARGO.html +++ b/Documentation/CARGO.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/CLEANUP.html b/Documentation/CLEANUP.html index 84a097643..38ddbe76b 100644 --- a/Documentation/CLEANUP.html +++ b/Documentation/CLEANUP.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/Client.html b/Documentation/Client.html index 43173e2ec..267f2232c 100644 --- a/Documentation/Client.html +++ b/Documentation/Client.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -229,9 +230,15 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. - CLIENT:IsAlive(Returns) + CLIENT:IsAlive()

    Checks if client is alive and returns true or false.

    + + + + CLIENT:IsMultiSeated() + +

    Checks if the CLIENT is a multi-seated UNIT.

    @@ -764,22 +771,31 @@ Function.

    -CLIENT:IsAlive(Returns) +CLIENT:IsAlive()

    Checks if client is alive and returns true or false.

    -

    Parameter

    -
    +
    +
    +
    + + +CLIENT:IsMultiSeated() + +
    +
    + +

    Checks if the CLIENT is a multi-seated UNIT.

    + +

    Return value

    + +

    #boolean: +true if multi-seated.

    - -
    diff --git a/Documentation/DCSAirbase.html b/Documentation/DCSAirbase.html index 3c3d51fdf..06def6538 100644 --- a/Documentation/DCSAirbase.html +++ b/Documentation/DCSAirbase.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DCSCoalitionObject.html b/Documentation/DCSCoalitionObject.html index 922893968..620eb80ef 100644 --- a/Documentation/DCSCoalitionObject.html +++ b/Documentation/DCSCoalitionObject.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DCSCommand.html b/Documentation/DCSCommand.html new file mode 100644 index 000000000..3e3bda254 --- /dev/null +++ b/Documentation/DCSCommand.html @@ -0,0 +1,122 @@ + + + + + + +
    +
    + +
    +
    +
    +
    + +
    +

    Module DCSCommand

    + + + +

    Type Command

    + + + + + + + + + +
    Command.id + +
    Command.params + +
    + +

    Type DCSCommand

    + +

    Type Command

    +

    Field(s)

    +
    +
    + + #string + +Command.id + +
    +
    + + + +
    +
    +
    +
    + + #Command.params + +Command.params + +
    +
    + + + +
    +
    + +

    Type Command.params

    + +
    + +
    + + diff --git a/Documentation/DCSController.html b/Documentation/DCSController.html index 4d0e88f83..c82205e73 100644 --- a/Documentation/DCSController.html +++ b/Documentation/DCSController.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DCSGroup.html b/Documentation/DCSGroup.html index 9ac8ca12d..95570211c 100644 --- a/Documentation/DCSGroup.html +++ b/Documentation/DCSGroup.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DCSObject.html b/Documentation/DCSObject.html index aeaa3f67b..e91080656 100644 --- a/Documentation/DCSObject.html +++ b/Documentation/DCSObject.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DCSTask.html b/Documentation/DCSTask.html index f0c28141d..f61a7da26 100644 --- a/Documentation/DCSTask.html +++ b/Documentation/DCSTask.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -63,16 +64,16 @@ -

    Type DCSTask

    - +

    Type Task

    +
    - + - + @@ -80,13 +81,15 @@
    DCSTask.idTask.id
    DCSTask.paramTask.param

    Type DCSTask

    -

    Field(s)

    + +

    Type Task

    +

    Field(s)

    #string - -DCSTask.id + +Task.id
    @@ -98,9 +101,9 @@
    - #DCSTask.param - -DCSTask.param + #Task.param + +Task.param
    @@ -110,7 +113,7 @@
    -

    Type DCSTask.param

    +

    Type Task.param

    diff --git a/Documentation/DCSTypes.html b/Documentation/DCSTypes.html index 23d2a95b7..65ec9e2d2 100644 --- a/Documentation/DCSTypes.html +++ b/Documentation/DCSTypes.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DCSUnit.html b/Documentation/DCSUnit.html index 7289a6392..36e77d5a5 100644 --- a/Documentation/DCSUnit.html +++ b/Documentation/DCSUnit.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DCStimer.html b/Documentation/DCStimer.html index 3367d7451..f0d1c0309 100644 --- a/Documentation/DCStimer.html +++ b/Documentation/DCStimer.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DEPLOYTASK.html b/Documentation/DEPLOYTASK.html index 3c9ada1c3..ca255eb58 100644 --- a/Documentation/DEPLOYTASK.html +++ b/Documentation/DEPLOYTASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DESTROYBASETASK.html b/Documentation/DESTROYBASETASK.html index 681bd7965..acfceb720 100644 --- a/Documentation/DESTROYBASETASK.html +++ b/Documentation/DESTROYBASETASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DESTROYGROUPSTASK.html b/Documentation/DESTROYGROUPSTASK.html index e10a4caf2..dd4fc57c6 100644 --- a/Documentation/DESTROYGROUPSTASK.html +++ b/Documentation/DESTROYGROUPSTASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DESTROYRADARSTASK.html b/Documentation/DESTROYRADARSTASK.html index 5721c8b34..d95a35e7d 100644 --- a/Documentation/DESTROYRADARSTASK.html +++ b/Documentation/DESTROYRADARSTASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/DESTROYUNITTYPESTASK.html b/Documentation/DESTROYUNITTYPESTASK.html index e6ceb3cd2..77cd3064d 100644 --- a/Documentation/DESTROYUNITTYPESTASK.html +++ b/Documentation/DESTROYUNITTYPESTASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/Database.html b/Documentation/Database.html index 7d8383029..e66bf3247 100644 --- a/Documentation/Database.html +++ b/Documentation/Database.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/Escort.html b/Documentation/Escort.html index 18148dfc7..5a5ed26f5 100644 --- a/Documentation/Escort.html +++ b/Documentation/Escort.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -64,7 +65,81 @@

    Taking the lead of AI escorting your flight.

    -

    The ESCORT class allows you to interact with escoring AI on your flight and take the lead.

    +

    The ESCORT class allows you to interact with escorting AI on your flight and take the lead. +Each escorting group can be commanded with a whole set of radio commands (radio menu in your flight, and then F10).

    + +

    The radio commands will vary according the category of the group. The richest set of commands are with Helicopters and AirPlanes. +Ships and Ground troops will have a more limited set, but they can provide support through the bombing of targets designated by the other escorts.

    + +

    Find a summary below of the current available commands:

    + +

    1. Navigation ...: Escort group navigation functions:

    + + + +

    2. Report targets ...: Report targets will make the escort group to report any target that it identifies within a 8km range. Any detected target can be attacked using the 4. Attack nearby targets function. (see below).

    + + + +

    3. Scan targets ...: Menu items to pop-up the escort group for target scanning. After scanning, the escort group will resume with the mission or defined task.

    + + + +

    4. Attack targets ...: This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed.

    + +

    5. Request assistance from ...: This menu item will list all detected targets within a 15km range, as with the menu item Attack Targets. +This menu item allows to request attack support from other escorts supporting the current client group. +eg. the function allows a player to request support from the Ship escort to attack a target identified by the Plane escort with its Tomahawk missiles. +eg. the function allows a player to request support from other Planes escorting to bomb the unit with illumination missiles or bombs, so that the main plane escort can attack the area.

    + +

    6. ROE ...: Defines the Rules of Engagement of the escort group when in flight.

    + + + +

    7. Evasion ...: Will define the evasion techniques that the escort group will perform during flight or combat.

    + + + +

    8. Resume Mission ...: Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint. +Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission.

    + +

    9. Abort Current Task: Cancel the current task and rejoin formation.

    + +
      +
    1. ESCORT object construction methods.

      +

      Create a new SPAWN object with the ESCORT.New method:

    2. +
    3. ESCORT.New: Creates a new ESCORT object from a Group#GROUP for a Client#CLIENT, with an optional briefing text.

    4. +
    5. ESCORT object initialization methods.

      +

      None.

    6. +
    + +

    Global(s)

    @@ -93,6 +168,12 @@ + + + + @@ -108,7 +189,13 @@ - + + + + + @@ -128,25 +215,49 @@ + + + + + + + + + + + + + + + + @@ -174,55 +285,19 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -230,7 +305,7 @@ @@ -240,13 +315,19 @@ - + - + + + + + @@ -259,6 +340,18 @@ + + + + + + + + @@ -333,6 +426,20 @@ + + +
    +
    + + Menu#MENU_CLIENT + +ESCORT.EscortMenuResumeMission + +
    +
    + + +
    @@ -366,8 +473,39 @@
    + +ESCORT:JoinUpAndFollow(EscortGroup, EscortClient, Distance) + +
    +
    + +

    JoinsUp and Follows a CLIENT.

    + +

    Parameters

    + +
    +
    +
    +
    + -ESCORT:New(EscortClient, EscortGroup, EscortName) +ESCORT:New(EscortClient, EscortGroup, EscortName, EscortBriefing)
    @@ -393,6 +531,11 @@ The group AI escorting the EscortClient.

    #string EscortName : Name of the escort.

    + +
  • + +

    EscortBriefing :

    +
  • Return value

    @@ -439,6 +582,11 @@ self

    +

    Registers the waypoints

    + +

    Return value

    + +

    #table:

    @@ -455,6 +603,19 @@ self

    If true, nearby targets are reported.

    + +
    +
    +
    + + +ESCORT.ReportTargetsScheduler + +
    +
    + + +
    @@ -469,6 +630,41 @@ self

    + +
    +
    +
    + + + +ESCORT.TaskPoints + +
    +
    + + + +
    +
    +
    +
    + + +ESCORT._AssistTarget(MenuParam) + +
    +
    + + + +

    Parameter

    +
    @@ -482,6 +678,27 @@ self

    +

    Parameter

    + + +
    +
    +
    + + +ESCORT._Flare(MenuParam) + +
    +
    + + +

    Parameter

    +
    +
    +
    + + +ESCORT._SwitchReportNearbyTargets(MenuParam) + +
    +
    + + + +

    Parameter

    +
      +
    • + +

      MenuParam :

      + +
    • +
    +

    Type MENUPARAM

    @@ -859,6 +971,34 @@ self

    + +
    +
    +
    + + #function + +MENUPARAM.ParamFunction + +
    +
    + + + +
    +
    +
    +
    + + #string + +MENUPARAM.ParamMessage + +
    +
    + + +
    diff --git a/Documentation/GOHOMETASK.html b/Documentation/GOHOMETASK.html index 2469b633c..fdacc71a3 100644 --- a/Documentation/GOHOMETASK.html +++ b/Documentation/GOHOMETASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/Group.html b/Documentation/Group.html index 0cb74ca82..91a991562 100644 --- a/Documentation/Group.html +++ b/Documentation/Group.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -103,6 +104,12 @@
    + + + + @@ -140,6 +147,12 @@ Note that this destroy method also raises a destroy event at run-time.

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

    + + + + @@ -242,12 +261,36 @@ Note that this destroy method also raises a destroy event at run-time.

    + + + + + + + + + + + + + + + + @@ -308,48 +351,96 @@ Note that this destroy method also raises a destroy event at run-time.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -359,15 +450,9 @@ Note that this destroy method also raises a destroy event at run-time.

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

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

    + + + + @@ -410,6 +501,18 @@ Note that this destroy method also raises a destroy event at run-time.

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

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

    - - - - @@ -470,6 +567,42 @@ Note that this destroy method also raises a destroy event at run-time.

    + + + + + + + + + + + + + + + + + + + + + + + + @@ -513,6 +646,8 @@ Note that this destroy method also raises a destroy event at run-time.

    Type Group

    +

    Type DCSCommand

    +

    Type DCSGroup

    A DCSGroup

    @@ -534,8 +669,6 @@ Note that this destroy method also raises a destroy event at run-time.

    Type DCSStopCondition

    -

    Type DCSTask

    -

    Type Duration

    Type GROUP

    @@ -589,6 +722,32 @@ All units on the ground result.

    + + +
    +
    + + +GROUP:CommandDoScript(DoScript) + +
    +
    + +

    Do Script command

    + +

    Parameter

    +
      +
    • + +

      #string DoScript :

      + +
    • +
    +

    Return value

    + +

    #DCSCommand:

    + +
    @@ -732,6 +891,24 @@ The callsign of the first unit of the group.

    + +GROUP:GetCategoryName() + +
    +
    + +

    Returns the category name of the group.

    + +

    Return value

    + +

    #string: +Category name = Helicopter, Airplane, Ground Unit, Ship

    + +
    +
    +
    +
    + GROUP:GetDCSGroup() @@ -742,7 +919,7 @@ The callsign of the first unit of the group.

    Return value

    -

    #Group: +

    DCSGroup#Group: The DCSGroup.

    @@ -777,6 +954,24 @@ The DCS Unit.

    + +GROUP:GetDCSUnits() + +
    +
    + +

    Gets the DCSUnits of the GROUP.

    + +

    Return value

    + +

    #table: +The DCSUnits.

    + +
    +
    +
    +
    + GROUP:GetDetectedTargets() @@ -1055,6 +1250,24 @@ Air category evaluation result.

    + +GROUP:IsAirPlane() + +
    +
    + +

    Returns if the GROUP are AirPlanes.

    + +

    Return value

    + +

    #boolean: +true if GROUP are AirPlanes.

    + +
    +
    +
    +
    + GROUP:IsAlive() @@ -1076,6 +1289,60 @@ Alive result.

    + +GROUP:IsGround() + +
    +
    + +

    Returns if the GROUP are Ground troops.

    + +

    Return value

    + +

    #boolean: +true if GROUP are Ground troops.

    + +
    +
    +
    +
    + + +GROUP:IsHelicopter() + +
    +
    + +

    Returns if the GROUP is a Helicopter.

    + +

    Return value

    + +

    #boolean: +true if GROUP are Helicopters.

    + +
    +
    +
    +
    + + +GROUP:IsShip() + +
    +
    + +

    Returns if the GROUP are Ships.

    + +

    Return value

    + +

    #boolean: +true if GROUP are Ships.

    + +
    +
    +
    +
    + GROUP:IsTargetDetected(DCSObject) @@ -1351,9 +1618,27 @@ self

    Return value

    -

    #GROUP: +

    Group#GROUP: self

    + +
    +
    +
    + + +GROUP:OptionROEHoldFirePossible() + +
    +
    + +

    Can the GROUP hold their weapons?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1372,6 +1657,24 @@ self

    #GROUP: self

    + +
    +
    +
    + + +GROUP:OptionROEOpenFirePossible() + +
    +
    + +

    Can the GROUP attack designated targets?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1390,6 +1693,24 @@ self

    #GROUP: self

    + +
    +
    +
    + + +GROUP:OptionROEReturnFirePossible() + +
    +
    + +

    Can the GROUP attack returning on enemy fire?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1408,6 +1729,24 @@ self

    #GROUP: self

    + +
    +
    +
    + + +GROUP:OptionROEWeaponFreePossible() + +
    +
    + +

    Can the GROUP attack targets of opportunity?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1419,13 +1758,31 @@ self

    -

    Evade fire.

    +

    Evade on fire.

    Return value

    #GROUP: self

    +
    +
    +
    +
    + + +GROUP:OptionROTEvadeFirePossible() + +
    +
    + +

    Can the GROUP evade on enemy fire?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1444,6 +1801,24 @@ self

    #GROUP: self

    + +
    +
    +
    + + +GROUP:OptionROTNoReactionPossible() + +
    +
    + +

    Can the GROUP ignore enemy fire?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1462,6 +1837,24 @@ self

    #GROUP: self

    + +
    +
    +
    + + +GROUP:OptionROTPassiveDefensePossible() + +
    +
    + +

    Can the GROUP evade using passive defenses?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1473,13 +1866,31 @@ self

    -

    Vertical manoeuvres.

    +

    Evade on fire using vertical manoeuvres.

    Return value

    #GROUP: self

    +
    +
    +
    +
    + + +GROUP:OptionROTVerticalPossible() + +
    +
    + +

    Can the GROUP evade on fire using vertical manoeuvres?

    + +

    Return value

    + +

    #boolean:

    + +
    @@ -1504,19 +1915,24 @@ self

    -GROUP:PushTask(DCSTask) +GROUP:PushTask(DCSTask, WaitTime)

    Pushing Task on the queue from the group.

    -

    Parameter

    +

    Parameters

    • DCSTask :

      +
    • +
    • + +

      WaitTime :

      +

    Return value

    @@ -1529,27 +1945,6 @@ self

    - -GROUP:RegisterWayPoint(WayPoint) - -
    -
    - - - -

    Parameter

    -
      -
    • - -

      WayPoint :

      - -
    • -
    -
    -
    -
    -
    - GROUP:Route(GoPoints) @@ -1578,19 +1973,24 @@ self

    -GROUP:SetTask(DCSTask) +GROUP:SetTask(DCSTask, WaitTime)

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

    -

    Parameter

    +

    Parameters

    • DCSTask :

      +
    • +
    • + +

      WaitTime :

      +

    Return value

    @@ -1627,9 +2027,41 @@ unit.

    Return value

    -

    #DCSTask: +

    DCSTask#Task: The DCS task structure.

    +
    +
    +
    +
    + + +GROUP:TaskCombo(<, DCSTasks) + +
    +
    + +

    Return a Combo Task taking an array of Tasks

    + +

    Parameters

    +
      +
    • + +

      #list < : +CSTask#Task> DCSTasks

      + +
    • +
    • + +

      DCSTasks :

      + +
    • +
    +

    Return value

    + +

    DCSTask#Task:

    + +
    @@ -1674,7 +2106,7 @@ The DCS task structure.

    #number lastWayPoint :

    -

    return #DCSTask

    +

    return DCSTask#Task

    @@ -1695,7 +2127,7 @@ The DCS task structure.

    Return value

    -

    #DCSTask:

    +

    DCSTask#Task:

    @@ -1739,7 +2171,7 @@ The radius of the embarking zone around the Point.

    Return value

    -

    #DCSTask: +

    DCSTask#Task: The DCS task structure.

    @@ -1778,7 +2210,7 @@ The group to be embarked.

    Return value

    -

    #DCSTask: +

    DCSTask#Task: The DCS task structure

    @@ -1786,6 +2218,80 @@ The DCS task structure

    + +GROUP:TaskFireAtPoint(The, Radius, PointVec2) + +
    +
    + +

    Fires at a VEC2 point.

    + +

    Parameters

    +
      +
    • + +

      DCSTypes#Vec2 The : +point to fire at.

      + +
    • +
    • + +

      DCSTypes#Distance Radius : +The radius of the zone to deploy the fire at.

      + +
    • +
    • + +

      PointVec2 :

      + +
    • +
    +

    Return value

    + +

    DCSTask#Task: +The DCS task structure.

    + +
    +
    +
    +
    + + +GROUP:TaskFunction(WayPoint, WayPointIndex, FunctionString, FunctionArguments) + +
    +
    + + + +

    Parameters

    +
      +
    • + +

      WayPoint :

      + +
    • +
    • + +

      WayPointIndex :

      + +
    • +
    • + +

      FunctionString :

      + +
    • +
    • + +

      FunctionArguments :

      + +
    • +
    +
    +
    +
    +
    + GROUP:TaskHoldPosition(Duration) @@ -1847,7 +2353,7 @@ self

    -GROUP:TaskLandAtZone(Zone, Duration) +GROUP:TaskLandAtZone(Zone, Duration, RandomPoint)
    @@ -1867,6 +2373,11 @@ The zone where to land.

    #number Duration : The duration in seconds to stay on the ground.

    + +
  • + +

    RandomPoint :

    +
  • Return value

    @@ -1898,7 +2409,7 @@ A table containing the mission task.

    Return value

    -

    #DCSTask:

    +

    DCSTask#Task:

    @@ -1978,27 +2489,6 @@ self

    - -GROUP:TaskRegisterWayPoint(WayPoint) - -
    -
    - - - -

    Parameter

    -
      -
    • - -

      WayPoint :

      - -
    • -
    -
    -
    -
    -
    - GROUP:TaskRoute(Points) @@ -2018,7 +2508,7 @@ A table of route points.

    Return value

    -

    #DCSTask:

    +

    DCSTask#Task:

    @@ -2099,6 +2589,182 @@ The formation string.

    + +
    +
    +
    + + +GROUP:TaskWrappedAction(DCSCommand, Index) + +
    +
    + +

    Return a WrappedAction Task taking a Command

    + +

    Parameters

    + +

    Return value

    + +

    DCSTask#Task:

    + + +
    +
    +
    +
    + + +GROUP:WayPointExecute(WayPoint, The, WaitTime) + +
    +
    + +

    Executes the WayPoint plan.

    + + +

    The function gets a WayPoint parameter, that you can use to restart the mission at a specific WayPoint. +Note that when the WayPoint parameter is used, the new start mission waypoint of the group will be 1!

    + +

    Parameters

    +
      +
    • + +

      #number WayPoint : +The WayPoint from where to execute the mission.

      + +
    • +
    • + +

      #WaitTime The : +amount seconds to wait before initiating the mission.

      + +
    • +
    • + +

      WaitTime :

      + +
    • +
    +

    Return value

    + +

    #GROUP:

    + + +
    +
    +
    +
    + + +GROUP:WayPointFunction(WayPoint, WayPointIndex, WayPointFunction, ...) + +
    +
    + +

    Registers a waypoint function that will be executed when the group moves over the WayPoint.

    + +

    Parameters

    +
      +
    • + +

      #number WayPoint : +The waypoint number. Note that the start waypoint on the route is WayPoint 1!

      + +
    • +
    • + +

      #number WayPointIndex : +When defining multiple WayPoint functions for one WayPoint, use WayPointIndex to set the sequence of actions.

      + +
    • +
    • + +

      #function WayPointFunction : +The waypoint function to be called when the group moves over the waypoint. The waypoint function takes variable parameters.

      + +
    • +
    • + +

      ... :

      + +
    • +
    +

    Return value

    + +

    #GROUP:

    + + +
    +
    +
    +
    + + + +GROUP.WayPointFunctions + +
    +
    + + + +
    +
    +
    +
    + + +GROUP:WayPointInitialize(WayPoint) + +
    +
    + +

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

    + + +

    Use the method Group#GROUP to define the hook functions for specific waypoints. + Use the method @{Group@GROUP:WayPointExecute) to start the execution of the new mission plan. + Note that when WayPointInitialize is called, the Mission of the group is RESTARTED!

    + +

    Parameter

    +
      +
    • + +

      #number WayPoint :

      + +
    • +
    +

    Return value

    + +

    #GROUP:

    + + +
    +
    +
    +
    + + + +GROUP.WayPoints + +
    +
    + + +
    @@ -2157,6 +2823,10 @@ The formation string.

    +

    Type WaitTime

    + +

    Type list

    + diff --git a/Documentation/MISSION.html b/Documentation/MISSION.html index 0409a6c26..de9f3738d 100644 --- a/Documentation/MISSION.html +++ b/Documentation/MISSION.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/MOVEMENT.html b/Documentation/MOVEMENT.html index 3775b9683..6441a29d3 100644 --- a/Documentation/MOVEMENT.html +++ b/Documentation/MOVEMENT.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/Menu.html b/Documentation/Menu.html index b70a9d4d1..533f237b1 100644 --- a/Documentation/Menu.html +++ b/Documentation/Menu.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -170,6 +171,18 @@
    + + + + + + + +
    ESCORT.EscortGroup +
    ESCORT.EscortMenuResumeMission +
    ESCORT:New(EscortClient, EscortGroup, EscortName)ESCORT:JoinUpAndFollow(EscortGroup, EscortClient, Distance) +

    JoinsUp and Follows a CLIENT.

    +
    ESCORT:New(EscortClient, EscortGroup, EscortName, EscortBriefing)

    ESCORT class constructor for an AI group

    ESCORT:RegisterRoute() - +

    Registers the waypoints

    ESCORT.ReportTargets

    If true, nearby targets are reported.

    +
    ESCORT.ReportTargetsScheduler +
    ESCORT.Targets +
    ESCORT.TaskPoints + +
    ESCORT._AssistTarget(MenuParam) +
    ESCORT._AttackTarget(MenuParam) +
    ESCORT._Flare(MenuParam) +
    ESCORT._OptionROTEvadeFire(MenuParam)ESCORT._ROE(MenuParam)
    ESCORT._OptionROTNoReaction(MenuParam)ESCORT._ROT(MenuParam)
    ESCORT._OptionROTPassiveDefense(MenuParam) - -
    ESCORT._OptionROTVertical(MenuParam) - -
    ESCORT._ROEHoldFire(MenuParam) - -
    ESCORT._ROEOpenFire(MenuParam) - -
    ESCORT._ROEReturnFire(MenuParam) - -
    ESCORT._ROEWeaponFree(MenuParam) - -
    ESCORT._ReportNearbyTargets(MenuParam)ESCORT._ReportNearbyTargetsNow(MenuParam)
    ESCORT:_ReportTargetsScheduler() - +

    Report Targets Scheduler.

    ESCORT._ScanTargets30Seconds(MenuParam)ESCORT._ScanTargets(MenuParam)
    ESCORT._ScanTargets60Seconds(MenuParam)ESCORT._Smoke(MenuParam) + +
    ESCORT._SwitchReportNearbyTargets(MenuParam) MENUPARAM.ParamDistance +
    MENUPARAM.ParamFunction + +
    MENUPARAM.ParamMessage +
    GROUP.ClassName +
    GROUP:CommandDoScript(DoScript) +

    Do Script command

    GROUP:GetCallsign()

    Gets the callsign of the fist unit of the group.

    +
    GROUP:GetCategoryName() +

    Returns the category name of the group.

    GROUP:GetDCSUnit(UnitNumber)

    Gets the DCS Unit of the GROUP.

    +
    GROUP:GetDCSUnits() +

    Gets the DCSUnits of the GROUP.

    GROUP:IsAir()

    Returns if the group is of an air category.

    +
    GROUP:IsAirPlane() +

    Returns if the GROUP are AirPlanes.

    GROUP:IsAlive()

    Returns if the group is alive.

    +
    GROUP:IsGround() +

    Returns if the GROUP are Ground troops.

    +
    GROUP:IsHelicopter() +

    Returns if the GROUP is a Helicopter.

    +
    GROUP:IsShip() +

    Returns if the GROUP are Ships.

    GROUP:OptionROEHoldFire()

    Holding weapons.

    +
    GROUP:OptionROEHoldFirePossible() +

    Can the GROUP hold their weapons?

    GROUP:OptionROEOpenFire()

    Openfire.

    +
    GROUP:OptionROEOpenFirePossible() +

    Can the GROUP attack designated targets?

    GROUP:OptionROEReturnFire()

    Return fire.

    +
    GROUP:OptionROEReturnFirePossible() +

    Can the GROUP attack returning on enemy fire?

    GROUP:OptionROEWeaponFree()

    Weapon free.

    +
    GROUP:OptionROEWeaponFreePossible() +

    Can the GROUP attack targets of opportunity?

    GROUP:OptionROTEvadeFire() -

    Evade fire.

    +

    Evade on fire.

    +
    GROUP:OptionROTEvadeFirePossible() +

    Can the GROUP evade on enemy fire?

    GROUP:OptionROTNoReaction()

    No evasion on enemy threats.

    +
    GROUP:OptionROTNoReactionPossible() +

    Can the GROUP ignore enemy fire?

    GROUP:OptionROTPassiveDefense()

    Evasion passive defense.

    +
    GROUP:OptionROTPassiveDefensePossible() +

    Can the GROUP evade using passive defenses?

    GROUP:OptionROTVertical() -

    Vertical manoeuvres.

    +

    Evade on fire using vertical manoeuvres.

    +
    GROUP:OptionROTVerticalPossible() +

    Can the GROUP evade on fire using vertical manoeuvres?

    GROUP:PushTask(DCSTask)GROUP:PushTask(DCSTask, WaitTime)

    Pushing Task on the queue from the group.

    -
    GROUP:RegisterWayPoint(WayPoint) -
    GROUP:SetTask(DCSTask)GROUP:SetTask(DCSTask, WaitTime)

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

    GROUP:TaskAttackUnit(The, AttackUnit)

    Attack the Unit.

    +
    GROUP:TaskCombo(<, DCSTasks) +

    Return a Combo Task taking an array of Tasks

    GROUP:TaskEmbarkingAtVec2(Point, Duration, EmbarkingGroup)

    Move the group to a Vec2 Point, wait for a defined duration and embark a group.

    +
    GROUP:TaskFireAtPoint(The, Radius, PointVec2) +

    Fires at a VEC2 point.

    +
    GROUP:TaskFunction(WayPoint, WayPointIndex, FunctionString, FunctionArguments) +
    GROUP:TaskLandAtZone(Zone, Duration)GROUP:TaskLandAtZone(Zone, Duration, RandomPoint)

    Land the group at a @{Zone#ZONE).

    GROUP:TaskOrbitCircleAtVec2(Point, Altitude, Speed)

    Orbit at a specified position at a specified alititude during a specified duration with a specified speed.

    -
    GROUP:TaskRegisterWayPoint(WayPoint) -
    GROUP:TaskRouteToZone(Zone, Randomize, Speed, Formation)

    Route the group to a given zone.

    +
    GROUP:TaskWrappedAction(DCSCommand, Index) +

    Return a WrappedAction Task taking a Command

    +
    GROUP:WayPointExecute(WayPoint, The, WaitTime) +

    Executes the WayPoint plan.

    +
    GROUP:WayPointFunction(WayPoint, WayPointIndex, WayPointFunction, ...) +

    Registers a waypoint function that will be executed when the group moves over the WayPoint.

    +
    GROUP.WayPointFunctions + +
    GROUP:WayPointInitialize(WayPoint) +

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

    +
    GROUP.WayPoints +
    MENU_CLIENT:New(MenuClient, MenuText, ParentMenu)

    Creates a new menu item for a group

    +
    MENU_CLIENT:Remove() +

    Removes the sub menus recursively of this MENU_CLIENT.

    +
    MENU_CLIENT:RemoveSubMenus() +

    Removes the sub menus recursively of this MENU_CLIENT.

    @@ -509,6 +522,42 @@ The parent menu.

    #MENU_CLIENT: self

    + +
    +
    +
    + + +MENU_CLIENT:Remove() + +
    +
    + +

    Removes the sub menus recursively of this MENU_CLIENT.

    + +

    Return value

    + +

    #MENU_CLIENT: +self

    + +
    +
    +
    +
    + + +MENU_CLIENT:RemoveSubMenus() + +
    +
    + +

    Removes the sub menus recursively of this MENU_CLIENT.

    + +

    Return value

    + +

    #MENU_CLIENT: +self

    +
    diff --git a/Documentation/Message.html b/Documentation/Message.html index 61e9193e8..fa82240cd 100644 --- a/Documentation/Message.html +++ b/Documentation/Message.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/NOTASK.html b/Documentation/NOTASK.html index 84e032385..d75b1a592 100644 --- a/Documentation/NOTASK.html +++ b/Documentation/NOTASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/PICKUPTASK.html b/Documentation/PICKUPTASK.html index 39dd2c00e..c16da51ec 100644 --- a/Documentation/PICKUPTASK.html +++ b/Documentation/PICKUPTASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/ROUTETASK.html b/Documentation/ROUTETASK.html index e08a215d9..da4d521b2 100644 --- a/Documentation/ROUTETASK.html +++ b/Documentation/ROUTETASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/STAGE.html b/Documentation/STAGE.html index 5d4076854..fd863de03 100644 --- a/Documentation/STAGE.html +++ b/Documentation/STAGE.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -800,6 +801,14 @@ +

    Type STAGEARRIVE

    + +

    Type STAGELANDING

    + +

    Type STAGEROUTE

    + +

    Type STAGEUNLOAD

    + diff --git a/Documentation/Sead.html b/Documentation/Sead.html index f1b58ff7f..d11fc919f 100644 --- a/Documentation/Sead.html +++ b/Documentation/Sead.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/Spawn.html b/Documentation/Spawn.html index 0b36e3397..e2427bf1a 100644 --- a/Documentation/Spawn.html +++ b/Documentation/Spawn.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -145,6 +146,12 @@ You can use the GROUP object to do further actions with

    Type SPAWN

    + + + + + + + + @@ -235,13 +248,13 @@ You can use the GROUP object to do further actions with - + - + @@ -249,25 +262,127 @@ You can use the GROUP object to do further actions with + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -286,6 +401,30 @@ You can use the GROUP object to do further actions with + + + + + + + + + + + + + + + + @@ -370,6 +509,12 @@ You can use the GROUP object to do further actions with + + + + @@ -447,6 +592,20 @@ You can use the GROUP object to do further actions with
    + #number + +SPAWN.AliveFactor + +
    +
    + + + +
    +
    +
    +
    + SPAWN:Array(SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY) @@ -544,6 +703,20 @@ self

    Usage:

    Spawn_Helicopter:CleanUp( 20 )  -- CleanUp the spawning of the helicopters every 20 seconds when they become inactive.
    + +
    +
    +
    + + + +SPAWN.CleanUpFunction + +
    +
    + + +
    @@ -570,7 +743,7 @@ A number holding the index from where to find the first group from.

    1. -

      GROUP#GROUP, #number: +

      Group#GROUP, #number: The group found, the new index where the group was found.

    2. @@ -609,7 +782,7 @@ The index of the group to return.

      Return value

      -

      GROUP#GROUP:

      +

      Group#GROUP:

      @@ -651,7 +824,7 @@ A number holding the last found previous index.

      1. -

        GROUP#GROUP, #number: +

        Group#GROUP, #number: The group found, the new index where the group was found.

      2. @@ -930,7 +1103,7 @@ The index of the group to be spawned.

        Return value

        -

        GROUP#GROUP: +

        Group#GROUP: The group that was spawned. You can use this group for further actions.

        @@ -967,26 +1140,23 @@ SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2,
        + #boolean -SPAWN:RepeatOnEngineShutDown() +SPAWN.RepeatOnEngineShutDown
        -

        Same as the @{#SPAWN.Repeat) method, but now the Group will respawn after its engines have shut down.

        -

        Return value

        - - -

        SPAWN

        + #boolean -SPAWN:RepeatOnLanding() +SPAWN.RepeatOnLanding
        @@ -1004,16 +1174,75 @@ SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2,
        -

        Will re-spawn a group based on a given index.

        +

        Will spawn a group based on the internal index.

        Note: Uses DATABASE module defined in MOOSE.

        Return value

        -

        GROUP#GROUP: +

        Group#GROUP: The group that was spawned. You can use this group for further actions.

        +
        +
        +
        +
        + + #string + +SPAWN.SpawnAliasPrefix + +
        +
        + + + +
        +
        +
        +
        + + + +SPAWN.SpawnCleanUpInterval + +
        +
        + + + +
        +
        +
        +
        + + + +SPAWN.SpawnCleanUpTimeStamps + +
        +
        + + + +
        +
        +
        +
        + + #number + +SPAWN.SpawnCurrentTimer + +
        +
        + + + + +

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

        +
        @@ -1074,6 +1303,76 @@ Nothing was spawned.

      + +
    +
    +
    + + +SPAWN:SpawnFunction(SpawnFunctionHook, SpawnFunctionArguments, ...) + +
    +
    + +

    Allows to place a CallFunction hook when a new group spawns.

    + + +

    The provided function will be called when a new group is spawned, including its given parameters. +The first parameter of the SpawnFunction is the Group#GROUP that was spawned.

    + +

    Parameters

    + +

    Return value

    + +

    #SPAWN:

    + + +
    +
    +
    +
    + + + +SPAWN.SpawnFunctionArguments + +
    +
    + + + +
    +
    +
    +
    + + + +SPAWN.SpawnFunctionHook + +
    +
    + + +
    @@ -1098,8 +1397,22 @@ Is the number of the Group that is to be spawned.

    Return value

    +

    #string: +SpawnGroupName

    + + +
    +
    +
    + + #number + +SPAWN.SpawnHighTimer + +
    +
    + -

    string SpawnGroupName

    @@ -1133,7 +1446,7 @@ The zone where the group is to be spawned.

    1. -

      GROUP#GROUP: +

      Group#GROUP: that was spawned.

    2. @@ -1144,6 +1457,138 @@ when nothing was spawned.

    + + +
    +
    + + #number + +SPAWN.SpawnLowTimer + +
    +
    + + + +
    +
    +
    +
    + + + +SPAWN.SpawnMaxGroups + +
    +
    + + + + +

    The maximum amount of groups that can be spawned.

    + +
    +
    +
    +
    + + + +SPAWN.SpawnMaxUnitsAlive + +
    +
    + + + + +

    The maximum amount of groups that can be alive of SpawnTemplatePrefix at the same time.

    + +
    +
    +
    +
    + + #boolean + +SPAWN.SpawnRandomizeRoute + +
    +
    + + + +
    +
    +
    +
    + + + +SPAWN.SpawnRandomizeRouteEndPoint + +
    +
    + + + +
    +
    +
    +
    + + + +SPAWN.SpawnRandomizeRouteRadius + +
    +
    + + + +
    +
    +
    +
    + + + +SPAWN.SpawnRandomizeRouteStartPoint + +
    +
    + + + +
    +
    +
    +
    + + #boolean + +SPAWN.SpawnRandomizeTemplate + +
    +
    + + + +
    +
    +
    +
    + + #boolean + +SPAWN.SpawnRepeat + +
    +
    + + +
    @@ -1220,6 +1665,68 @@ self

    -- Between these two values, a random amount of seconds will be choosen for each new spawn of the helicopters. Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 ) + +
    +
    +
    + + #number + +SPAWN.SpawnSetTimer + +
    +
    + + + + +

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

    + +
    +
    +
    +
    + + #string + +SPAWN.SpawnTemplatePrefix + +
    +
    + + + +
    +
    +
    +
    + + + +SPAWN.SpawnTemplatePrefixTable + +
    +
    + + + +
    +
    +
    +
    + + #boolean + +SPAWN.SpawnVisible + +
    +
    + + + + +

    When the first Spawn executes, all the Groups need to be made visible before start.

    +
    @@ -1246,7 +1753,7 @@ Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )

    Return value

    -

    GROUP#GROUP: +

    Group#GROUP: The group that was spawned. You can use this group for further actions.

    @@ -1568,6 +2075,31 @@ Nothing found

    + +SPAWN:_OnEngineShutDown(event) + +
    +
    + +

    Will detect AIR Units shutting down their engines ...

    + + +

    When the event takes place, and the method RepeatOnEngineShutDown was called, the spawned Group will Re-SPAWN. +But only when the Unit was registered to have landed.

    + +

    Parameter

    +
      +
    • + +

      event :

      + +
    • +
    +
    +
    +
    +
    + SPAWN:_OnLand(event) diff --git a/Documentation/StaticObject.html b/Documentation/StaticObject.html index 26462272a..b5f1e3915 100644 --- a/Documentation/StaticObject.html +++ b/Documentation/StaticObject.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/TASK.html b/Documentation/TASK.html index 4c7cb44fb..12c34a734 100644 --- a/Documentation/TASK.html +++ b/Documentation/TASK.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/Unit.html b/Documentation/Unit.html index 1c464f0d0..0f36031dd 100644 --- a/Documentation/Unit.html +++ b/Documentation/Unit.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -84,6 +85,42 @@
    + + + + + + + + + + + + + + + + + + + + + + + + @@ -138,6 +175,12 @@ + + + + @@ -149,13 +192,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SPAWN.AliveFactor + +
    SPAWN:Array(SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY)

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

    @@ -160,6 +167,12 @@ You can use the GROUP object to do further actions with
    SPAWN:CleanUp(SpawnCleanUpInterval)

    CleanUp groups when they are still alive, but inactive.

    +
    SPAWN.CleanUpFunction +
    SPAWN:RepeatOnEngineShutDown()SPAWN.RepeatOnEngineShutDown -

    Same as the @{#SPAWN.Repeat) method, but now the Group will respawn after its engines have shut down.

    +
    SPAWN:RepeatOnLanding()SPAWN.RepeatOnLanding
    SPAWN:Spawn() -

    Will re-spawn a group based on a given index.

    +

    Will spawn a group based on the internal index.

    +
    SPAWN.SpawnAliasPrefix + +
    SPAWN.SpawnCleanUpInterval + +
    SPAWN.SpawnCleanUpTimeStamps + +
    SPAWN.SpawnCurrentTimer +
    SPAWN:SpawnFromUnit(HostUnit, OuterRadius, InnerRadius, SpawnIndex)

    Will spawn a group from a hosting unit.

    +
    SPAWN:SpawnFunction(SpawnFunctionHook, SpawnFunctionArguments, ...) +

    Allows to place a CallFunction hook when a new group spawns.

    +
    SPAWN.SpawnFunctionArguments + +
    SPAWN.SpawnFunctionHook +
    SPAWN:SpawnGroupName(SpawnIndex)

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

    +
    SPAWN.SpawnHighTimer +
    SPAWN:SpawnInZone(Zone, SpawnIndex)

    Will spawn a Group within a given ZONE.

    +
    SPAWN.SpawnLowTimer + +
    SPAWN.SpawnMaxGroups + +
    SPAWN.SpawnMaxUnitsAlive + +
    SPAWN.SpawnRandomizeRoute + +
    SPAWN.SpawnRandomizeRouteEndPoint + +
    SPAWN.SpawnRandomizeRouteRadius + +
    SPAWN.SpawnRandomizeRouteStartPoint + +
    SPAWN.SpawnRandomizeTemplate + +
    SPAWN.SpawnRepeat +
    SPAWN:SpawnScheduled(SpawnTime, SpawnTimeVariation)

    Spawns new groups at varying time intervals.

    +
    SPAWN.SpawnSetTimer + +
    SPAWN.SpawnTemplatePrefix + +
    SPAWN.SpawnTemplatePrefixTable + +
    SPAWN.SpawnVisible +
    SPAWN:_OnDeadOrCrash(event)

    Obscolete

    +
    SPAWN:_OnEngineShutDown(event) +

    Will detect AIR Units shutting down their engines ...

    UNIT.ClassName +
    UNIT:Flare(FlareColor) +

    Signal a flare at the position of the UNIT.

    +
    UNIT.FlareColor + +
    UNIT:FlareGreen() +

    Signal a green flare at the position of the UNIT.

    +
    UNIT:FlareRed() +

    Signal a red flare at the position of the UNIT.

    +
    UNIT:FlareWhite() +

    Signal a white flare at the position of the UNIT.

    +
    UNIT:FlareYellow() +

    Signal a yellow flare at the position of the UNIT.

    UNIT:GetTypeName() +
    UNIT:IsAir() +

    Returns if the unit is of an air category.

    UNIT:New(DCSUnit) - +

    Create a new UNIT from DCSUnit.

    UNIT:OtherUnitInRadius(AwaitUnit, Radius) +
    UNIT:Smoke(SmokeColor) +

    Smoke the UNIT.

    +
    UNIT:SmokeBlue() +

    Smoke the UNIT Blue.

    +
    UNIT.SmokeColor + +
    UNIT:SmokeGreen() +

    Smoke the UNIT Green.

    +
    UNIT:SmokeOrange() +

    Smoke the UNIT Orange.

    +
    UNIT:SmokeRed() +

    Smoke the UNIT Red.

    +
    UNIT:SmokeWhite() +

    Smoke the UNIT White.

    +
    + +

    Type UNIT.FlareColor

    + + + + + + + + + + + + + + + + + +
    UNIT.FlareColor.Green + +
    UNIT.FlareColor.Red + +
    UNIT.FlareColor.White + +
    UNIT.FlareColor.Yellow + +
    + +

    Type UNIT.SmokeColor

    + + + + + + + + + + + + + + + + + + + +
    UNIT.SmokeColor.Blue + +
    UNIT.SmokeColor.Green + +
    UNIT.SmokeColor.Orange + +
    UNIT.SmokeColor.Red + +
    UNIT.SmokeColor.White +
    @@ -208,6 +355,93 @@ + + +
    +
    + + +UNIT:Flare(FlareColor) + +
    +
    + +

    Signal a flare at the position of the UNIT.

    + +

    Parameter

    + +
    +
    +
    +
    + + #UNIT.FlareColor + +UNIT.FlareColor + +
    +
    + + + +
    +
    +
    +
    + + +UNIT:FlareGreen() + +
    +
    + +

    Signal a green flare at the position of the UNIT.

    + +
    +
    +
    +
    + + +UNIT:FlareRed() + +
    +
    + +

    Signal a red flare at the position of the UNIT.

    + +
    +
    +
    +
    + + +UNIT:FlareWhite() + +
    +
    + +

    Signal a white flare at the position of the UNIT.

    + +
    +
    +
    +
    + + +UNIT:FlareYellow() + +
    +
    + +

    Signal a yellow flare at the position of the UNIT.

    +
    @@ -325,6 +559,27 @@ + +
    +
    +
    + + +UNIT:IsAir() + +
    +
    + +

    Returns if the unit is of an air category.

    + + +

    If the unit is a helicopter or a plane, then this method will return true, otherwise false.

    + +

    Return value

    + +

    #boolean: +Air category evaluation result.

    +
    @@ -349,16 +604,21 @@
    - +

    Create a new UNIT from DCSUnit.

    Parameter

    +

    Return value

    + +

    Unit#UNIT:

    + +
    @@ -385,6 +645,235 @@ + +
    +
    +
    + + +UNIT:Smoke(SmokeColor) + +
    +
    + +

    Smoke the UNIT.

    + +

    Parameter

    + +
    +
    +
    +
    + + +UNIT:SmokeBlue() + +
    +
    + +

    Smoke the UNIT Blue.

    + +
    +
    +
    +
    + + #UNIT.SmokeColor + +UNIT.SmokeColor + +
    +
    + + + +
    +
    +
    +
    + + +UNIT:SmokeGreen() + +
    +
    + +

    Smoke the UNIT Green.

    + +
    +
    +
    +
    + + +UNIT:SmokeOrange() + +
    +
    + +

    Smoke the UNIT Orange.

    + +
    +
    +
    +
    + + +UNIT:SmokeRed() + +
    +
    + +

    Smoke the UNIT Red.

    + +
    +
    +
    +
    + + +UNIT:SmokeWhite() + +
    +
    + +

    Smoke the UNIT White.

    + +
    +
    + +

    Type UNIT.FlareColor

    + +

    FlareColor

    + +

    Field(s)

    +
    +
    + + +UNIT.FlareColor.Green + +
    +
    + + + +
    +
    +
    +
    + + +UNIT.FlareColor.Red + +
    +
    + + + +
    +
    +
    +
    + + +UNIT.FlareColor.White + +
    +
    + + + +
    +
    +
    +
    + + +UNIT.FlareColor.Yellow + +
    +
    + + + +
    +
    + +

    Type UNIT.SmokeColor

    + +

    SmokeColor

    + +

    Field(s)

    +
    +
    + + +UNIT.SmokeColor.Blue + +
    +
    + + + +
    +
    +
    +
    + + +UNIT.SmokeColor.Green + +
    +
    + + + +
    +
    +
    +
    + + +UNIT.SmokeColor.Orange + +
    +
    + + + +
    +
    +
    +
    + + +UNIT.SmokeColor.Red + +
    +
    + + + +
    +
    +
    +
    + + +UNIT.SmokeColor.White + +
    +
    + + +
    diff --git a/Documentation/Zone.html b/Documentation/Zone.html index a08526d95..10d8c170a 100644 --- a/Documentation/Zone.html +++ b/Documentation/Zone.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -93,7 +94,7 @@ - ZONE:GetRandomPoint() + ZONE:GetRandomPointVec2() @@ -171,8 +172,8 @@
    - -ZONE:GetRandomPoint() + +ZONE:GetRandomPointVec2()
    diff --git a/Documentation/env.html b/Documentation/env.html index a8444fa5f..665f4519f 100644 --- a/Documentation/env.html +++ b/Documentation/env.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/index.html b/Documentation/index.html index 161d8ecc6..63942937d 100644 --- a/Documentation/index.html +++ b/Documentation/index.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -95,6 +96,12 @@ DCSCoalitionObject + + + + DCSCommand + + diff --git a/Documentation/land.html b/Documentation/land.html index 2eac36dc5..630ebb3b9 100644 --- a/Documentation/land.html +++ b/Documentation/land.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • diff --git a/Documentation/routines.html b/Documentation/routines.html index 060aa99dd..1125b647e 100644 --- a/Documentation/routines.html +++ b/Documentation/routines.html @@ -23,6 +23,7 @@
  • Client
  • DCSAirbase
  • DCSCoalitionObject
  • +
  • DCSCommand
  • DCSController
  • DCSGroup
  • DCSObject
  • @@ -1193,6 +1194,8 @@

    Type routines

    +

    Type Time

    + diff --git a/Embedded/Moose_Embedded.lua b/Embedded/Moose_Embedded.lua index e063d0741..5f2fa13cb 100644 --- a/Embedded/Moose_Embedded.lua +++ b/Embedded/Moose_Embedded.lua @@ -473,6 +473,13 @@ do rep - time between repetitions of this function (OPTIONAL) st - time when repetitions of this function will stop automatically (OPTIONAL) ]] + + --- Schedule a function + -- @param #function f + -- @param #table parameters + -- @param #Time t + -- @param #Time rep seconds + -- @param #Time st routines.scheduleFunction = function(f, vars, t, rep, st) --verify correct types assert(type(f) == 'function', 'variable 1, expected function, got ' .. type(f)) @@ -2874,6 +2881,10 @@ end -- @param #string Class -- @param #string Method function BASE:TraceClassMethod( Class, Method ) + if not _TraceClassMethod[Class] then + _TraceClassMethod[Class] = {} + _TraceClassMethod[Class].Method = {} + end _TraceClassMethod[Class].Method[Method] = true end @@ -3104,6 +3115,9 @@ function MENU_CLIENT:New( MenuClient, MenuText, ParentMenu ) self.MenuClientGroupID = MenuClient:GetClientGroupID() self.MenuParentPath = MenuParentPath self.MenuText = MenuText + self.ParentMenu = ParentMenu + + self.Menus = {} if not _MENUCLIENTS[self.MenuClientGroupID] then _MENUCLIENTS[self.MenuClientGroupID] = {} @@ -3113,16 +3127,57 @@ function MENU_CLIENT:New( MenuClient, MenuText, ParentMenu ) self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } ) - if not MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] then - self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath ) - MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] = self.MenuPath - else - self.MenuPath = MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] + local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText + if MenuPath[MenuPathID] then + missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] ) end + self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath ) + MenuPath[MenuPathID] = self.MenuPath + + self:T( { MenuClient:GetClientGroupName(), self.MenuPath } ) + + if ParentMenu and ParentMenu.Menus then + ParentMenu.Menus[self.MenuPath] = self + end return self end +--- Removes the sub menus recursively of this MENU_CLIENT. +-- @param #MENU_CLIENT self +-- @return #MENU_CLIENT self +function MENU_CLIENT:RemoveSubMenus() + self:F( self.MenuPath ) + + for MenuID, Menu in pairs( self.Menus ) do + Menu:Remove() + end + +end + +--- Removes the sub menus recursively of this MENU_CLIENT. +-- @param #MENU_CLIENT self +-- @return #MENU_CLIENT self +function MENU_CLIENT:Remove() + self:F( self.MenuPath ) + + self:RemoveSubMenus() + + if not _MENUCLIENTS[self.MenuClientGroupID] then + _MENUCLIENTS[self.MenuClientGroupID] = {} + end + + local MenuPath = _MENUCLIENTS[self.MenuClientGroupID] + + if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then + MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil + end + + missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath ) + self.ParentMenu.Menus[self.MenuPath] = nil + return nil +end + --- The MENU_CLIENT_COMMAND class -- @type MENU_CLIENT_COMMAND @@ -3154,6 +3209,7 @@ function MENU_CLIENT_COMMAND:New( MenuClient, MenuText, ParentMenu, CommandMenuF self.MenuClientGroupID = MenuClient:GetClientGroupID() self.MenuParentPath = MenuParentPath self.MenuText = MenuText + self.ParentMenu = ParentMenu if not _MENUCLIENTS[self.MenuClientGroupID] then _MENUCLIENTS[self.MenuClientGroupID] = {} @@ -3163,19 +3219,24 @@ function MENU_CLIENT_COMMAND:New( MenuClient, MenuText, ParentMenu, CommandMenuF self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, CommandMenuArgument } ) - if not MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] then - self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument ) - MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] = self.MenuPath - else - self.MenuPath = MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] + local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText + if MenuPath[MenuPathID] then + missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] ) end - + + self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument ) + MenuPath[MenuPathID] = self.MenuPath + self.CommandMenuFunction = CommandMenuFunction self.CommandMenuArgument = CommandMenuArgument + + ParentMenu.Menus[self.MenuPath] = self + return self end function MENU_CLIENT_COMMAND:Remove() + self:F( self.MenuPath ) if not _MENUCLIENTS[self.MenuClientGroupID] then _MENUCLIENTS[self.MenuClientGroupID] = {} @@ -3186,7 +3247,9 @@ function MENU_CLIENT_COMMAND:Remove() if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil end + missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath ) + self.ParentMenu.Menus[self.MenuPath] = nil return nil end --- A GROUP class abstraction of a DCSGroup class. @@ -3211,6 +3274,7 @@ GROUP = { GroupID = 0, Controller = nil, DCSGroup = nil, + WayPointFunctions = {}, } --- A DCSGroup @@ -3282,6 +3346,85 @@ function GROUP:NewFromDCSUnit( DCSUnit ) return self end +--- Retrieve the group mission and allow to place function hooks within the mission waypoint plan. +-- Use the method @{Group#GROUP:WayPointFunction} to define the hook functions for specific waypoints. +-- Use the method @{Group@GROUP:WayPointExecute) to start the execution of the new mission plan. +-- Note that when WayPointInitialize is called, the Mission of the group is RESTARTED! +-- @param #GROUP self +-- @param #number WayPoint +-- @return #GROUP +function GROUP:WayPointInitialize() + + self.WayPoints = self:GetTaskRoute() + + return self +end + + +--- Registers a waypoint function that will be executed when the group moves over the WayPoint. +-- @param #GROUP self +-- @param #number WayPoint The waypoint number. Note that the start waypoint on the route is WayPoint 1! +-- @param #number WayPointIndex When defining multiple WayPoint functions for one WayPoint, use WayPointIndex to set the sequence of actions. +-- @param #function WayPointFunction The waypoint function to be called when the group moves over the waypoint. The waypoint function takes variable parameters. +-- @return #GROUP +function GROUP:WayPointFunction( WayPoint, WayPointIndex, WayPointFunction, ... ) + self:F( { WayPoint, WayPointIndex, WayPointFunction } ) + + table.insert( self.WayPoints[WayPoint].task.params.tasks, WayPointIndex ) + self.WayPoints[WayPoint].task.params.tasks[WayPointIndex] = self:TaskFunction( WayPoint, WayPointIndex, WayPointFunction, arg ) + return self +end + + +function GROUP:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionArguments ) + + local DCSTask + + local DCSScript = {} + DCSScript[#DCSScript+1] = "local MissionGroup = GROUP.FindGroup( ... ) " + DCSScript[#DCSScript+1] = FunctionString .. "( MissionGroup, " .. table.concat( FunctionArguments, "," ) .. ")" + + DCSTask = self:TaskWrappedAction( + self:CommandDoScript( + table.concat( DCSScript ) + ), WayPointIndex + ) + + self:T( DCSTask ) + + return DCSTask + +end + + + +--- Executes the WayPoint plan. +-- The function gets a WayPoint parameter, that you can use to restart the mission at a specific WayPoint. +-- Note that when the WayPoint parameter is used, the new start mission waypoint of the group will be 1! +-- @param #GROUP self +-- @param #number WayPoint The WayPoint from where to execute the mission. +-- @param #WaitTime The amount seconds to wait before initiating the mission. +-- @return #GROUP +function GROUP:WayPointExecute( WayPoint, WaitTime ) + + if not WayPoint then + WayPoint = 1 + end + + -- When starting the mission from a certain point, the TaskPoints need to be deleted before the given WayPoint. + for TaskPointID = 1, WayPoint - 1 do + table.remove( self.WayPoints, 1 ) + end + + self:T( self.WayPoints ) + + self:SetTask( self:TaskRoute( self.WayPoints ), WaitTime ) + + return self +end + + + --- Gets the DCSGroup of the GROUP. -- @param #GROUP self -- @return DCSGroup#Group The DCSGroup. @@ -3396,6 +3539,7 @@ function GROUP:Destroy() end self.DCSGroup:destroy() + self.DCSGroup = nil end --- Gets the DCS Unit. @@ -3576,12 +3720,20 @@ end --- Pushing Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self -function GROUP:PushTask( DCSTask ) +function GROUP:PushTask( DCSTask, WaitTime ) self:F() local Controller = self:_GetController() - Controller:pushTask( DCSTask ) + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller:pushTask( DCSTask ) + + if not WaitTime then + Controller:pushTask( DCSTask ) + else + routines.scheduleFunction( Controller.pushTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + end return self end @@ -3589,13 +3741,20 @@ end --- Clearing the Task Queue and Setting the Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self -function GROUP:SetTask( DCSTask ) - self:F() +function GROUP:SetTask( DCSTask, WaitTime ) + self:F( { DCSTask } ) local Controller = self:_GetController() - Controller:setTask( DCSTask ) + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller.setTask( Controller, DCSTask ) + if not WaitTime then + WaitTime = 1 + end + routines.scheduleFunction( Controller.setTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + return self end @@ -3608,7 +3767,7 @@ end -- @param #string condition -- @param #Time duration -- @param #number lastWayPoint --- return #DCSTask +-- return DCSTask#Task function GROUP:TaskCondition( time, userFlag, userFlagValue, condition, duration, lastWayPoint ) self:F( { time, userFlag, userFlagValue, condition, duration, lastWayPoint } ) @@ -3626,9 +3785,9 @@ end --- Return a Controlled Task taking a Task and a TaskCondition -- @param #GROUP self --- @param #DCSTask DCSTask +-- @param DCSTask#Task DCSTask -- @param #DCSStopCondition DCSStopCondition --- @return #DCSTask +-- @return DCSTask#Task function GROUP:TaskControlled( DCSTask, DCSStopCondition ) self:F( { DCSTask, DCSStopCondition } ) @@ -3638,7 +3797,7 @@ function GROUP:TaskControlled( DCSTask, DCSStopCondition ) id = 'ControlledTask', params = { task = DCSTask, - stopCondition = DCSStopCondition, + stopCondition = DCSStopCondition } } @@ -3646,6 +3805,49 @@ function GROUP:TaskControlled( DCSTask, DCSStopCondition ) return DCSTaskControlled end +--- Return a Combo Task taking an array of Tasks +-- @param #GROUP self +-- @param #list DCSTasks +-- @return DCSTask#Task +function GROUP:TaskCombo( DCSTasks ) + self:F( { DCSTasks } ) + + local DCSTaskCombo + + DCSTaskCombo = { + id = 'ComboTask', + params = { + tasks = DCSTasks + } + } + + self:T( { DCSTaskCombo } ) + return DCSTaskCombo +end + +--- Return a WrappedAction Task taking a Command +-- @param #GROUP self +-- @param DCSCommand#Command DCSCommand +-- @return DCSTask#Task +function GROUP:TaskWrappedAction( DCSCommand, Index ) + self:F( { DCSCommand } ) + + local DCSTaskWrappedAction + + DCSTaskWrappedAction = { + id = "WrappedAction", + enabled = true, + number = Index, + auto = false, + params = { + action = DCSCommand, + }, + } + + self:T( { DCSTaskWrappedAction } ) + return DCSTaskWrappedAction +end + --- Orbit at a specified position at a specified alititude during a specified duration with a specified speed. -- @param #GROUP self -- @param #Vec2 Point The point to hold the position. @@ -3742,10 +3944,15 @@ end -- @param Zone#ZONE Zone The zone where to land. -- @param #number Duration The duration in seconds to stay on the ground. -- @return #GROUP self -function GROUP:TaskLandAtZone( Zone, Duration ) - self:F( { self.GroupName, Zone, Duration } ) +function GROUP:TaskLandAtZone( Zone, Duration, RandomPoint ) + self:F( { self.GroupName, Zone, Duration, RandomPoint } ) - local Point = Zone:GetPointVec2() + local Point + if RandomPoint then + Point = Zone:GetRandomPointVec2() + else + Point = Zone:GetPointVec2() + end local DCSTask = self:TaskLandAtVec2( Point, Duration ) @@ -3757,7 +3964,7 @@ end --- Attack the Unit. -- @param #GROUP self -- @param Unit#UNIT The unit. --- @return #DCSTask The DCS task structure. +-- @return DCSTask#Task The DCS task structure. function GROUP:TaskAttackUnit( AttackUnit ) self:F( { self.GroupName, AttackUnit } ) @@ -3786,6 +3993,33 @@ function GROUP:TaskAttackUnit( AttackUnit ) return DCSTask end +--- Fires at a VEC2 point. +-- @param #GROUP self +-- @param DCSTypes#Vec2 The point to fire at. +-- @param DCSTypes#Distance Radius The radius of the zone to deploy the fire at. +-- @return DCSTask#Task The DCS task structure. +function GROUP:TaskFireAtPoint( PointVec2, Radius ) + self:F( { self.GroupName, PointVec2, Radius } ) + +-- FireAtPoint = { +-- id = 'FireAtPoint', +-- params = { +-- point = Vec2, +-- radius = Distance, +-- } +-- } + + local DCSTask + DCSTask = { id = 'FireAtPoint', + params = { point = PointVec2, + radius = Radius, + } + } + + self:T( { DCSTask } ) + return DCSTask +end + --- Move the group to a Vec2 Point, wait for a defined duration and embark a group. @@ -3793,7 +4027,7 @@ end -- @param #Vec2 Point The point where to wait. -- @param #number Duration The duration in seconds to wait. -- @param #GROUP EmbarkingGroup The group to be embarked. --- @return #DCSTask The DCS task structure +-- @return DCSTask#Task The DCS task structure function GROUP:TaskEmbarkingAtVec2( Point, Duration, EmbarkingGroup ) self:F( { self.GroupName, Point, Duration, EmbarkingGroup.DCSGroup } ) @@ -3817,11 +4051,11 @@ end -- @param #GROUP self -- @param #Vec2 Point The point where to wait. -- @param #number Radius The radius of the embarking zone around the Point. --- @return #DCSTask The DCS task structure. +-- @return DCSTask#Task The DCS task structure. function GROUP:TaskEmbarkToTransportAtVec2( Point, Radius ) self:F( { self.GroupName, Point, Radius } ) - local DCSTask --#DCSTask + local DCSTask --DCSTask#Task DCSTask = { id = 'EmbarkToTransport', params = { x = Point.x, y = Point.y, @@ -3836,7 +4070,7 @@ end --- Return a Misson task from a mission template. -- @param #GROUP self -- @param #table TaskMission A table containing the mission task. --- @return #DCSTask +-- @return DCSTask#Task function GROUP:TaskMission( TaskMission ) self:F( Points ) @@ -3850,7 +4084,7 @@ end --- Return a Misson task to follow a given route defined by Points. -- @param #GROUP self -- @param #table Points A table of route points. --- @return #DCSTask +-- @return DCSTask#Task function GROUP:TaskRoute( Points ) self:F( Points ) @@ -3875,15 +4109,37 @@ function GROUP:TaskRouteToVec3( Point, Speed ) PointFrom.x = GroupPoint.x PointFrom.y = GroupPoint.z PointFrom.alt = GroupPoint.y + PointFrom.alt_type = "BARO" PointFrom.type = "Turning Point" + PointFrom.action = "Turning Point" + PointFrom.speed = Speed + PointFrom.speed_locked = true + PointFrom.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + local PointTo = {} PointTo.x = Point.x PointTo.y = Point.z - PointTo.alt = Point.y + PointTo.alt = Point.y + PointTo.alt_type = "BARO" PointTo.type = "Turning Point" + PointTo.action = "Fly Over Point" PointTo.speed = Speed PointTo.speed_locked = true + PointTo.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + local Points = { PointFrom, PointTo } @@ -3913,32 +4169,7 @@ function GROUP:Route( GoPoints ) return self end -function GROUP:TaskRegisterWayPoint( WayPoint ) - local DCSTask - - DCSTask = { id = "WrappedAction", - enabled = true, - auto = false, - number = 1, - params = - { - action = - { - id = "Script", - params = - { - command = "local MissionGroup = GROUP.FindGroup( ... ) " .. - "env.info( MissionGroup:GetName() ) " .. - "MissionGroup:RegisterWayPoint ( " .. WayPoint .. " )", - }, -- end of ["params"] - }, -- end of ["action"] - }, -- end of ["params"] - } - self:T( DCSTask ) - - return DCSTask -end --- Route the group to a given zone. -- The group final destination point can be randomized. @@ -3966,7 +4197,7 @@ function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) local ZonePoint if Randomize then - ZonePoint = Zone:GetRandomPoint() + ZonePoint = Zone:GetRandomPointVec2() else ZonePoint = Zone:GetPointVec2() end @@ -3996,6 +4227,26 @@ function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) return self end +-- Commands + +--- Do Script command +-- @param #GROUP self +-- @param #string DoScript +-- @return #DCSCommand +function GROUP:CommandDoScript( DoScript ) + + local DCSDoScript = { + id = "Script", + params = { + command = DoScript, + }, + } + + self:T( DCSDoScript ) + return DCSDoScript +end + + --- Return the mission template of the group. -- @param #GROUP self -- @return #table The MissionTemplate @@ -4082,7 +4333,14 @@ end function GROUP:IsTargetDetected( DCSObject ) local TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity - = self:_GetController():isTargetDetected( DCSObject ) + = self:_GetController().isTargetDetected( self:_GetController(), DCSObject, + Controller.Detection.VISUAL, + Controller.Detection.OPTIC, + Controller.Detection.RADAR, + Controller.Detection.IRST, + Controller.Detection.RWR, + Controller.Detection.DLINK + ) return TargetIsDetected, TargetIsVisible, TargetLastTime, TargetKnowType, TargetKnowDistance, TargetLastPos, TargetLastVelocity @@ -4104,8 +4362,8 @@ function GROUP:OptionROEHoldFirePossible() end --- Holding weapons. --- @param #GROUP self --- @return #GROUP self +-- @param Group#GROUP self +-- @return Group#GROUP self function GROUP:OptionROEHoldFire() self:F( { self.GroupName } ) @@ -4339,7 +4597,7 @@ end function GROUP:Message( Message, Duration ) self:F( { Message, Duration } ) - return MESSAGE:New( Message, self:GetCallsign() .. "(" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) + return MESSAGE:New( Message, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) end --- Send a message to all coalitions. @@ -4387,12 +4645,6 @@ function GROUP:MessageToClient( Message, Duration, Client ) self:Message( Message, Duration ):ToClient( Client ) end -function GROUP:RegisterWayPoint( WayPoint ) - - self:Message( "Moving over wayPoint " .. WayPoint, 20 ):ToAll() - self.WayPoint = WayPoint -end - @@ -4460,6 +4712,11 @@ UNIT = { -- @field Orange -- @field Blue + +--- Create a new UNIT from DCSUnit. +-- @param #UNIT self +-- @param DCSUnit#Unit DCSUnit +-- @return Unit#UNIT function UNIT:New( DCSUnit ) local self = BASE:Inherit( self, BASE:New() ) self:F( DCSUnit:getName() ) @@ -4642,6 +4899,23 @@ function UNIT:SmokeBlue() trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Blue ) end +-- Is methods + +--- Returns if the unit is of an air category. +-- If the unit is a helicopter or a plane, then this method will return true, otherwise false. +-- @param #UNIT self +-- @return #boolean Air category evaluation result. +function UNIT:IsAir() + self:F() + + local UnitDescriptor = self.DCSUnit:getDesc() + self:T( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } ) + + local IsAirResult = ( UnitDescriptor.category == Unit.Category.AIRPLANE ) or ( UnitDescriptor.category == Unit.Category.HELICOPTER ) + + self:T( IsAirResult ) + return IsAirResult +end --- ZONE Classes -- @module Zone @@ -4685,7 +4959,7 @@ function ZONE:GetPointVec2() return Point end -function ZONE:GetRandomPoint() +function ZONE:GetRandomPointVec2() self:F( self.ZoneName ) local Point = {} @@ -5648,7 +5922,7 @@ function LogClose() end end -_Database = DATABASE:New() +_Database = DATABASE:New() -- Database#DATABASE _Database:ScoreOpen() --- CARGO Classes @@ -10732,12 +11006,15 @@ function SPAWN:ReSpawn( SpawnIndex ) SpawnIndex = 1 end - local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) - local SpawnDCSGroup = SpawnGroup:GetDCSGroup() - if SpawnDCSGroup then - SpawnGroup:Destroy() - end - +-- TODO: This logic makes DCS crash and i don't know why (yet). +-- local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) +-- if SpawnGroup then +-- local SpawnDCSGroup = SpawnGroup:GetDCSGroup() +-- if SpawnDCSGroup then +-- SpawnGroup:Destroy() +-- end +-- end + return self:SpawnWithIndex( SpawnIndex ) end @@ -10755,6 +11032,12 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) else self:T( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) self.SpawnGroups[self.SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) + + -- If there is a SpawnFunction hook defined, call it. + if self.SpawnFunctionHook then + self.SpawnFunctionHook( self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments ) ) + end + -- TODO: Need to fix this by putting an "R" in the name of the group when the group repeats. --if self.SpawnRepeat then -- _Database:SetStatusGroup( SpawnTemplate.name, "ReSpawn" ) --end @@ -10793,7 +11076,7 @@ function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation ) self.AliveFactor = 1 -- self.SpawnLowTimer = 0 self.SpawnHighTimer = 0 - + if SpawnTime ~= nil and SpawnTimeVariation ~= nil then self.SpawnLowTimer = SpawnTime - SpawnTime / 2 * SpawnTimeVariation self.SpawnHighTimer = SpawnTime + SpawnTime / 2 * SpawnTimeVariation @@ -10805,6 +11088,25 @@ function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation ) return self end +--- Allows to place a CallFunction hook when a new group spawns. +-- The provided function will be called when a new group is spawned, including its given parameters. +-- The first parameter of the SpawnFunction is the @{Group#GROUP} that was spawned. +-- @param #SPAWN self +-- @param #function SpawnFunctionHook The function to be called when a group spawns. +-- @param SpawnFunctionArguments A random amount of arguments to be provided to the function when the group spawns. +-- @return #SPAWN +function SPAWN:SpawnFunction( SpawnFunctionHook, ... ) + self:F( SpawnFunction ) + + self.SpawnFunctionHook = SpawnFunctionHook + self.SpawnFunctionArguments = {} + if arg then + self.SpawnFunctionArguments = arg + end + + return self +end + --- Will start the spawning scheduler. @@ -10948,7 +11250,7 @@ function SPAWN:SpawnInZone( Zone, SpawnIndex ) self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y ) end - local SpawnPos = Zone:GetRandomPoint() + local SpawnPos = Zone:GetRandomPointVec2() local Point = {} Point.type = "Turning Point" Point.x = SpawnPos.x @@ -11076,12 +11378,15 @@ end function SPAWN:GetGroupFromIndex( SpawnIndex ) self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } ) - if SpawnIndex then + if not SpawnIndex then + SpawnIndex = 1 + end + + if self.SpawnGroups and self.SpawnGroups[SpawnIndex] then local SpawnGroup = self.SpawnGroups[SpawnIndex].Group return SpawnGroup else - local SpawnGroup = self.SpawnGroups[1].Group - return SpawnGroup + return nil end end @@ -11524,8 +11829,8 @@ function SPAWN:_SpawnCleanUpScheduler() while SpawnGroup do if SpawnGroup:AllOnGround() and SpawnGroup:GetMaxVelocity() < 1 then - if not self.SpanUwnCleanUpTimeStamps[SpawnGroup:GetName()] then - self.SpawnCleapTimeStamps[SpawnGroup:GetName()] = timer.getTime() + if not self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] then + self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] = timer.getTime() else if self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] + self.SpawnCleanUpInterval < timer.getTime() then self:T( { "CleanUp Scheduler:", "Cleaning:", SpawnGroup } ) @@ -11843,23 +12148,31 @@ end -- * **"Scan targets 30 seconds":** Scan 30 seconds for targets. -- * **"Scan targets 60 seconds":** Scan 60 seconds for targets. -- --- **4. Attack nearby targets ...:** This menu item will list all detected targets within an 8km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed. +-- **4. Attack targets ...:** This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed. -- --- **5. ROE ...:** Defines the Rules of Engagement of the escort group when in flight. +-- **5. Request assistance from ...:** This menu item will list all detected targets within a 15km range, as with the menu item **Attack Targets**. +-- This menu item allows to request attack support from other escorts supporting the current client group. +-- eg. the function allows a player to request support from the Ship escort to attack a target identified by the Plane escort with its Tomahawk missiles. +-- eg. the function allows a player to request support from other Planes escorting to bomb the unit with illumination missiles or bombs, so that the main plane escort can attack the area. +-- +-- **6. ROE ...:** Defines the Rules of Engagement of the escort group when in flight. -- -- * **"Hold Fire":** The escort group will hold fire. -- * **"Return Fire":** The escort group will return fire. -- * **"Open Fire":** The escort group will open fire on designated targets. -- * **"Weapon Free":** The escort group will engage with any target. -- --- **6. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat. +-- **7. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat. -- -- * **"Fight until death":** The escort group will have no reaction to threats. -- * **"Use flares, chaff and jammers":** The escort group will use passive defense using flares and jammers. No evasive manoeuvres are executed. -- * **"Evade enemy fire":** The rescort group will evade enemy fire before firing. -- * **"Go below radar and evade fire":** The escort group will perform evasive vertical manoeuvres. -- --- **7. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint. Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission. +-- **8. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint. +-- Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission. +-- +-- **9. Abort Current Task:** Cancel the current task and rejoin formation. -- -- 1. ESCORT object construction methods. -- -------------------------------------- @@ -11881,6 +12194,7 @@ Include.File( "Database" ) Include.File( "Group" ) Include.File( "Zone" ) + --- ESCORT class -- @type ESCORT -- @extends Base#BASE @@ -11891,6 +12205,7 @@ Include.File( "Zone" ) -- @field #boolean ReportTargets If true, nearby targets are reported. -- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup. -- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the EscortGroup. +-- @field Menu#MENU_CLIENT EscortMenuResumeMission ESCORT = { ClassName = "ESCORT", EscortName = nil, -- The Escort Name @@ -11900,7 +12215,8 @@ ESCORT = { FollowScheduler = nil, ReportTargets = true, OptionROE = AI.Option.Air.val.ROE.OPEN_FIRE, - OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION + OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION, + TaskPoints = {} } --- MENUPARAM type @@ -11911,7 +12227,7 @@ ESCORT = { -- @field #string ParamMessage --- ESCORT class constructor for an AI group --- @param self +-- @param #ESCORT self -- @param Client#CLIENT EscortClient The client escorted by the EscortGroup. -- @param Group#GROUP EscortGroup The group AI escorting the EscortClient. -- @param #string EscortName Name of the escort. @@ -11924,7 +12240,23 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) self.EscortGroup = EscortGroup -- Group#GROUP self.EscortName = EscortName self.EscortBriefing = EscortBriefing + + self:T( EscortGroup:GetClassNameAndID() ) + + -- Set EscortGroup known at EscortClient. + if not self.EscortClient._EscortGroups then + self.EscortClient._EscortGroups = {} + end + if not self.EscortClient._EscortGroups[EscortGroup:GetName()] then + self.EscortClient._EscortGroups[EscortGroup:GetName()] = {} + self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup + self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName + self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {} + + end + + self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName ) self.EscortMenuReportNavigation = MENU_CLIENT:New( self.EscortClient, "Navigation", self.EscortMenu ) @@ -11968,9 +12300,12 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) end -- Attack Targets - self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack nearby targets", self.EscortMenu ) - self.EscortMenuAttackTargets = {} - self.Targets = {} + self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu ) + + -- Request assistance from other escorts. + -- This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane... + self.EscortMenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, "Request assistance from", self.EscortMenu ) + -- Rules of Engagement self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu ) @@ -12002,28 +12337,22 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) self.EscortMenuOptionEvasionVertical = MENU_CLIENT_COMMAND:New( self.EscortClient, "Go below radar and evade fire", self.EscortMenuEvasion, ESCORT._ROT, { ParamSelf = self, ParamFunction = EscortGroup:OptionROTVertical(), ParamMessage = "Evading on enemy fire with vertical manoeuvres!" } ) end - -- Cancel current Task - self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume Mission", self.EscortMenu ) - self.EscortMenuResumeWayPoints = {} - local TaskPoints = self:RegisterRoute() - for WayPointID, WayPoint in pairs( TaskPoints ) do - self.EscortMenuResumeWayPoints[WayPointID] = MENU_CLIENT_COMMAND:New( self.EscortClient, "Resume from waypoint " .. WayPointID, self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } ) - end - + -- Mission Resume Menu Root + self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume the escort mission", self.EscortMenu ) + -- Initialize the EscortGroup - EscortGroup:OptionROTVertical() - EscortGroup:OptionROEOpenFire() + self.EscortGroup:WayPointInitialize(1) + + self.EscortGroup:OptionROTVertical() + self.EscortGroup:OptionROEOpenFire() - EscortGroup:SetTask( EscortGroup:TaskRoute( TaskPoints ) ) self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, 30 ) EscortGroup:MessageToClient( EscortGroup:GetCategoryName() .. " '" .. EscortName .. "' (" .. EscortGroup:GetCallsign() .. ") reporting! " .. "We're escorting your flight. " .. - "You can communicate with us through the radio menu. " .. - "Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n" .. - "We are continuing our way, but you can request to join-up your flight under the Navigation menu\n", + "Use the Radio Menu and F10 and use the options under + " .. EscortName .. "\n", 60, EscortClient ) end @@ -12088,13 +12417,27 @@ function ESCORT._JoinUpAndFollow( MenuParam ) local Distance = MenuParam.ParamDistance + self:JoinUpAndFollow( EscortGroup, EscortClient, Distance ) +end + +--- JoinsUp and Follows a CLIENT. +-- @param Escort#ESCORT self +-- @param Group#GROUP EscortGroup +-- @param Client#CLIENT EscortClient +-- @param DCSTypes#Distance Distance +function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance ) + self:F( { EscortGroup, EscortClient, Distance } ) + if self.FollowScheduler then routines.removeFunction( self.FollowScheduler ) end + EscortGroup:OptionROEHoldFire() + EscortGroup:OptionROTPassiveDefense() + self.CT1 = 0 self.GT1 = 0 - self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, 1 ) + self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, .5 ) EscortGroup:MessageToClient( "Rejoining and Following at " .. Distance .. "!", 30, EscortClient ) end @@ -12165,16 +12508,40 @@ function ESCORT._ScanTargets( MenuParam ) local ScanDuration = MenuParam.ParamScanDuration - routines.removeFunction( self.FollowScheduler ) - self.FollowScheduler = nil - - EscortGroup:PushTask( - EscortGroup:TaskControlled( - EscortGroup:TaskOrbitCircle( 200, 20 ), - EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil ) - ) - ) + if self.FollowScheduler then + routines.removeFunction( self.FollowScheduler ) + end + + self:T( { "FollowScheduler after removefunction: ", self.FollowScheduler } ) + + if EscortGroup:IsHelicopter() then + routines.scheduleFunction( EscortGroup.PushTask, + { EscortGroup, + EscortGroup:TaskControlled( + EscortGroup:TaskOrbitCircle( 200, 20 ), + EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil ) + ) + }, + timer.getTime() + 1 + ) + elseif EscortGroup:IsAirPlane() then + routines.scheduleFunction( EscortGroup.PushTask, + { EscortGroup, + EscortGroup:TaskControlled( + EscortGroup:TaskOrbitCircle( 1000, 500 ), + EscortGroup:TaskCondition( nil, nil, nil, nil, ScanDuration, nil ) + ) + }, + timer.getTime() + 1 + ) + end + EscortGroup:MessageToClient( "Scanning targets for " .. ScanDuration .. " seconds.", ScanDuration, EscortClient ) + + if self.FollowScheduler then + self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 ) + end + end --- @param #MENUPARAM MenuParam @@ -12183,18 +12550,89 @@ function ESCORT._AttackTarget( MenuParam ) local self = MenuParam.ParamSelf local EscortGroup = self.EscortGroup local EscortClient = self.EscortClient - local AttackUnit = MenuParam.ParamUnit + local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT - routines.removeFunction( self.FollowScheduler ) - self.FollowScheduler = nil - - EscortGroup:OptionROEOpenFire() - EscortGroup:OptionROTVertical() + if self.FollowScheduler then + routines.removeFunction( self.FollowScheduler ) + end self:T( AttackUnit ) - EscortGroup:PushTask( EscortGroup:TaskAttackUnit( AttackUnit ) ) + if EscortGroup:IsAir() then + EscortGroup:OptionROEOpenFire() + EscortGroup:OptionROTVertical() + routines.scheduleFunction( + EscortGroup.PushTask, + { EscortGroup, + EscortGroup:TaskCombo( + { EscortGroup:TaskAttackUnit( AttackUnit ), + EscortGroup:TaskOrbitCircle( 500, 350 ) + } + ) + }, timer.getTime() + 10 + ) + else + routines.scheduleFunction( + EscortGroup.PushTask, + { EscortGroup, + EscortGroup:TaskCombo( + { EscortGroup:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 ) + } + ) + }, timer.getTime() + 10 + ) + end EscortGroup:MessageToClient( "Engaging Designated Unit!", 10, EscortClient ) + + + if self.FollowScheduler then + self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 ) + end + +end + +--- @param #MENUPARAM MenuParam +function ESCORT._AssistTarget( MenuParam ) + + local self = MenuParam.ParamSelf + local EscortGroup = self.EscortGroup + local EscortClient = self.EscortClient + local EscortGroupAttack = MenuParam.ParamEscortGroup + local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT + + if self.FollowScheduler then + routines.removeFunction( self.FollowScheduler ) + end + + + self:T( AttackUnit ) + + if EscortGroupAttack:IsAir() then + EscortGroupAttack:OptionROEOpenFire() + EscortGroupAttack:OptionROTVertical() + routines.scheduleFunction( + EscortGroupAttack.PushTask, + { EscortGroupAttack, + EscortGroupAttack:TaskCombo( + { EscortGroupAttack:TaskAttackUnit( AttackUnit ), + EscortGroupAttack:TaskOrbitCircle( 500, 350 ) + } + ) + }, timer.getTime() + 10 + ) + else + routines.scheduleFunction( + EscortGroupAttack.PushTask, + { EscortGroupAttack, + EscortGroupAttack:TaskCombo( + { EscortGroupAttack:TaskFireAtPoint( AttackUnit:GetPointVec2(), 50 ) + } + ) + }, timer.getTime() + 10 + ) + end + EscortGroupAttack:MessageToClient( "Assisting with the destroying the enemy unit!", 10, EscortClient ) + end --- @param #MENUPARAM MenuParam @@ -12244,22 +12682,20 @@ function ESCORT._ResumeMission( MenuParam ) table.remove( WayPoints, 1 ) end - EscortGroup:SetTask( EscortGroup:TaskRoute( WayPoints ) ) + routines.scheduleFunction( EscortGroup.SetTask, {EscortGroup, EscortGroup:TaskRoute( WayPoints ) }, timer.getTime() + 1 ) + EscortGroup:MessageToClient( "Resuming mission from waypoint " .. WayPoint .. ".", 10, EscortClient ) end +--- Registers the waypoints +-- @param #ESCORT self +-- @return #table function ESCORT:RegisterRoute() + self:F() local EscortGroup = self.EscortGroup -- Group#GROUP local TaskPoints = EscortGroup:GetTaskRoute() - self:T( TaskPoints ) - - for TaskPointID, TaskPoint in pairs( TaskPoints ) do - self:T( TaskPointID ) - TaskPoint.task.params.tasks[#TaskPoint.task.params.tasks+1] = EscortGroup:TaskRegisterWayPoint( TaskPointID ) - self:T( TaskPoint.task.params.tasks[#TaskPoint.task.params.tasks] ) - end self:T( TaskPoints ) @@ -12334,7 +12770,7 @@ function ESCORT:_FollowScheduler( FollowDistance ) local DVu = { x = DV.x / FollowDistance, y = DV.y / FollowDistance, z = DV.z / FollowDistance } -- Now we can calculate the group destination vector GDV. - local GDV = { x = DVu.x * CS * 2 + CVI.x, y = CVI.y, z = DVu.z * CS * 2 + CVI.z } + local GDV = { x = DVu.x * CS * 8 + CVI.x, y = CVI.y, z = DVu.z * CS * 8 + CVI.z } self:T2( { "CV2:", CV2 } ) self:T2( { "CVI:", CVI } ) self:T2( { "GDV:", GDV } ) @@ -12344,8 +12780,8 @@ function ESCORT:_FollowScheduler( FollowDistance ) -- The calculation of the Speed would simulate that the group would take 30 seconds to overcome -- the requested Distance). - local Time = 30 - local CatchUpSpeed = ( CatchUpDistance - ( CS * 2 ) ) / Time + local Time = 10 + local CatchUpSpeed = ( CatchUpDistance - ( CS * 8.4 ) ) / Time local Speed = CS + CatchUpSpeed if Speed < 0 then @@ -12367,112 +12803,169 @@ end --- Report Targets Scheduler. -- @param #ESCORT self function ESCORT:_ReportTargetsScheduler() - self:F() + self:F( self.EscortGroup:GetName() ) - self.Targets = {} - - if self.EscortGroup:IsAlive() then + if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then + local EscortGroupName = self.EscortGroup:GetName() local EscortTargets = self.EscortGroup:GetDetectedTargets() + local ClientEscortTargets = self.EscortClient._EscortGroups[EscortGroupName].Targets + local EscortTargetMessages = "" for EscortTargetID, EscortTarget in pairs( EscortTargets ) do local EscortObject = EscortTarget.object self:T( EscortObject ) if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then - local EscortTargetMessage = "" - local EscortTargetUnit = UNIT:New( EscortObject ) - - local EscortTargetCategoryName = EscortTargetUnit:GetCategoryName() - local EscortTargetCategoryType = EscortTargetUnit:GetTypeName() + local EscortTargetUnitName = EscortTargetUnit:GetName() - -- local EscortTargetIsDetected, - -- EscortTargetIsVisible, - -- EscortTargetLastTime, - -- EscortTargetKnowType, - -- EscortTargetKnowDistance, - -- EscortTargetLastPos, - -- EscortTargetLastVelocity - -- = self.EscortGroup:IsTargetDetected( EscortObject ) - -- - -- self:T( { EscortTargetIsDetected, - -- EscortTargetIsVisible, - -- EscortTargetLastTime, - -- EscortTargetKnowType, - -- EscortTargetKnowDistance, - -- EscortTargetLastPos, - -- EscortTargetLastVelocity } ) - if EscortTarget.distance then - local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3() - local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() - local Distance = routines.utils.get3DDist( EscortTargetUnitPositionVec3, EscortPositionVec3 ) / 1000 - self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget.visible } ) +-- local EscortTargetIsDetected, +-- EscortTargetIsVisible, +-- EscortTargetLastTime, +-- EscortTargetKnowType, +-- EscortTargetKnowDistance, +-- EscortTargetLastPos, +-- EscortTargetLastVelocity +-- = self.EscortGroup:IsTargetDetected( EscortObject ) +-- +-- self:T( { EscortTargetIsDetected, +-- EscortTargetIsVisible, +-- EscortTargetLastTime, +-- EscortTargetKnowType, +-- EscortTargetKnowDistance, +-- EscortTargetLastPos, +-- EscortTargetLastVelocity } ) + - if Distance <= 8 then + local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3() + local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 + ) ^ 0.5 / 1000 - if EscortTarget.type then - EscortTargetMessage = EscortTargetMessage .. " - " .. EscortTargetCategoryName .. " (" .. EscortTargetCategoryType .. ") at " - else - EscortTargetMessage = EscortTargetMessage .. " - Unknown target at " - end + self:T( { self.EscortGroup:GetName(), EscortTargetUnit:GetName(), Distance, EscortTarget } ) - EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " km" + if Distance <= 15 then - if EscortTarget.visible then - EscortTargetMessage = EscortTargetMessage .. ", visual" - end + if not ClientEscortTargets[EscortTargetUnitName] then + ClientEscortTargets[EscortTargetUnitName] = {} + end + ClientEscortTargets[EscortTargetUnitName].AttackUnit = EscortTargetUnit + ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible + ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type + ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance + else + if ClientEscortTargets[EscortTargetUnitName] then + ClientEscortTargets[EscortTargetUnitName] = nil + end + end + end + end + + self:T( { "Sorting Targets Table:", ClientEscortTargets } ) + table.sort( ClientEscortTargets, function( a, b ) return a.Distance < b.Distance end ) + self:T( { "Sorted Targets Table:", ClientEscortTargets } ) - local TargetIndex = Distance*1000 - self.Targets[TargetIndex] = {} - self.Targets[TargetIndex].AttackMessage = EscortTargetMessage - self.Targets[TargetIndex].AttackUnit = EscortTargetUnit + -- Remove the sub menus of the Attack menu of the Escort for the EscortGroup. + self.EscortMenuAttackNearbyTargets:RemoveSubMenus() + self.EscortMenuTargetAssistance:RemoveSubMenus() + + --for MenuIndex = 1, #self.EscortMenuAttackTargets do + -- self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } ) + -- self.EscortMenuAttackTargets[MenuIndex] = self.EscortMenuAttackTargets[MenuIndex]:Remove() + --end + + + if ClientEscortTargets then + for ClientEscortTargetUnitName, ClientEscortTargetData in pairs( ClientEscortTargets ) do + + for ClientEscortGroupName, EscortGroupData in pairs( self.EscortClient._EscortGroups ) do + + if ClientEscortTargetData and ClientEscortTargetData.AttackUnit:IsAlive() then + + local EscortTargetMessage = "" + local EscortTargetCategoryName = ClientEscortTargetData.AttackUnit:GetCategoryName() + local EscortTargetCategoryType = ClientEscortTargetData.AttackUnit:GetTypeName() + if ClientEscortTargetData.type then + EscortTargetMessage = EscortTargetMessage .. EscortTargetCategoryName .. " (" .. EscortTargetCategoryType .. ") at " + else + EscortTargetMessage = EscortTargetMessage .. "Unknown target at " end - end + + local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPositionVec3() + local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 + + ( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 + + ( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2 + ) ^ 0.5 / 1000 - if EscortTargetMessage ~= "" then - EscortTargetMessages = EscortTargetMessages .. EscortTargetMessage .. "\n" + self:T( { self.EscortGroup:GetName(), ClientEscortTargetData.AttackUnit:GetName(), Distance, ClientEscortTargetData.AttackUnit } ) + if ClientEscortTargetData.visible == false then + EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " estimated km" + else + EscortTargetMessage = EscortTargetMessage .. string.format( "%.2f", Distance ) .. " km" + end + + if ClientEscortTargetData.visible then + EscortTargetMessage = EscortTargetMessage .. ", visual" + end + + if ClientEscortGroupName == EscortGroupName then + + MENU_CLIENT_COMMAND:New( self.EscortClient, + EscortTargetMessage, + self.EscortMenuAttackNearbyTargets, + ESCORT._AttackTarget, + { ParamSelf = self, + ParamUnit = ClientEscortTargetData.AttackUnit + } + ) + EscortTargetMessages = EscortTargetMessages .. "\n - " .. EscortTargetMessage + else + local MenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, EscortGroupData.EscortName, self.EscortMenuTargetAssistance ) + MENU_CLIENT_COMMAND:New( self.EscortClient, + EscortTargetMessage, + MenuTargetAssistance, + ESCORT._AssistTarget, + { ParamSelf = self, + ParamEscortGroup = EscortGroupData.EscortGroup, + ParamUnit = ClientEscortTargetData.AttackUnit + } + ) + end + else + ClientEscortTargetData = nil end + end + end + + if EscortTargetMessages ~= "" and self.ReportTargets == true then + self.EscortGroup:MessageToClient( "Detected targets within 15 km range:" .. EscortTargetMessages:gsub("\n$",""), 20, self.EscortClient ) + else + self.EscortGroup:MessageToClient( "No targets detected!", 20, self.EscortClient ) end - end - - if EscortTargetMessages ~= "" and self.ReportTargets == true then - self.EscortGroup:MessageToClient( EscortTargetMessages:gsub("\n$",""), 20, self.EscortClient ) - else - self.EscortGroup:MessageToClient( "No targets detected!", 20, self.EscortClient ) end - self:T() - - self:T( { "Sorting Targets Table:", self.Targets } ) - table.sort( self.Targets ) - self:T( { "Sorted Targets Table:", self.Targets } ) + self.EscortMenuResumeMission:RemoveSubMenus() - for MenuIndex = 1, #self.EscortMenuAttackTargets do - self:T( { "Remove Menu:", self.EscortMenuAttackTargets[MenuIndex] } ) - self.EscortMenuAttackTargets[MenuIndex] = self.EscortMenuAttackTargets[MenuIndex]:Remove() - end - - local MenuIndex = 1 - for TargetID, TargetData in pairs( self.Targets ) do - self:T( { "Adding menu:", TargetID, "for Unit", self.Targets[TargetID].AttackUnit } ) - if MenuIndex <= 10 then - self.EscortMenuAttackTargets[MenuIndex] = - MENU_CLIENT_COMMAND:New( self.EscortClient, - self.Targets[TargetID].AttackMessage, - self.EscortMenuAttackNearbyTargets, - ESCORT._AttackTarget, - { ParamSelf = self, - ParamUnit = self.Targets[TargetID].AttackUnit - } - ) - self:T( { "New Menu:", self.EscortMenuAttackTargets[TargetID] } ) - MenuIndex = MenuIndex + 1 - else - break - end +-- if self.EscortMenuResumeWayPoints then +-- for MenuIndex = 1, #self.EscortMenuResumeWayPoints do +-- self:T( { "Remove Menu:", self.EscortMenuResumeWayPoints[MenuIndex] } ) +-- self.EscortMenuResumeWayPoints[MenuIndex] = self.EscortMenuResumeWayPoints[MenuIndex]:Remove() +-- end +-- end + + local TaskPoints = self:RegisterRoute() + for WayPointID, WayPoint in pairs( TaskPoints ) do + local EscortPositionVec3 = self.EscortGroup:GetPositionVec3() + local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 + + ( WayPoint.y - EscortPositionVec3.z )^2 + ) ^ 0.5 / 1000 + MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } ) end else diff --git a/Maths/MOOSE - ESCORT - Velocity and Direction Vector Calculation.ggb b/Maths/MOOSE - ESCORT - Velocity and Direction Vector Calculation.ggb new file mode 100644 index 000000000..89cb1efed Binary files /dev/null and b/Maths/MOOSE - ESCORT - Velocity and Direction Vector Calculation.ggb differ diff --git a/Moose/Base.lua b/Moose/Base.lua index 1d54ac663..f806d0c2e 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -331,7 +331,7 @@ function BASE:F( Arguments ) if DebugInfoFrom then LineFrom = DebugInfoFrom.currentline end - env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "F", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end end end @@ -379,7 +379,7 @@ function BASE:T( Arguments ) if DebugInfoFrom then LineFrom = DebugInfoFrom.currentline end - env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s" , LineCurrent, LineFrom, "T", self.ClassName, self.ClassID, routines.utils.oneLineSerialize( Arguments ) ) ) end end end @@ -422,7 +422,7 @@ function BASE:E( Arguments ) local LineCurrent = DebugInfoCurrent.currentline local LineFrom = DebugInfoFrom.currentline - env.info( string.format( "%6d\(%6d\)/%1s:%20s%05d.%s\(%s\)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) + env.info( string.format( "%6d(%6d)/%1s:%20s%05d.%s(%s)" , LineCurrent, LineFrom, "E", self.ClassName, self.ClassID, Function, routines.utils.oneLineSerialize( Arguments ) ) ) end diff --git a/Moose/Database.lua b/Moose/Database.lua index b1ac948de..eef7fb002 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -863,7 +863,7 @@ function DATABASE:ScoreOpen() if not self.StatFile then error( "Error: Cannot open 'Player Scores.csv' file in " .. lfs.writedir() ) end - self.StatFile:write( '"RunID";"Time";"PlayerName";"ScoreType";"PlayerUnitCoaltion";"PlayerUnitCategory";"PlayerUnitType";"PlayerUnitName";"TargetUnitCoalition";"TargetUnitCategory";"TargetUnitType";"TargetUnitName";"Times";"Score"\n' ) + self.StatFile:write( '"RunID","Time","PlayerName","ScoreType","PlayerUnitCoaltion","PlayerUnitCategory","PlayerUnitType","PlayerUnitName","TargetUnitCoalition","TargetUnitCategory","TargetUnitType","TargetUnitName","Times","Score"\n' ) self.RunID = os.date("%y-%m-%d_%H-%M-%S") end @@ -921,10 +921,23 @@ function DATABASE:ScoreAdd( PlayerName, ScoreType, ScoreTimes, ScoreAmount, Play end if lfs then - self.StatFile:write( '"' .. self.RunID .. '";' .. ScoreTime .. ';"' .. PlayerName .. '";"' .. ScoreType .. '";"' .. - PlayerUnitCoalition .. '";"' .. PlayerUnitCategory .. '";"' .. PlayerUnitType .. '";"' .. PlayerUnitName .. '";"' .. - TargetUnitCoalition .. '";"' .. TargetUnitCategory .. '";"' .. TargetUnitType .. '";"' .. TargetUnitName .. '";' .. - ScoreTimes .. ';' .. ScoreAmount ) + self.StatFile:write( + '"' .. self.RunID .. '"' .. ',' .. + '' .. ScoreTime .. '' .. ',' .. + '"' .. PlayerName .. '"' .. ',' .. + '"' .. ScoreType .. '"' .. ',' .. + '"' .. PlayerUnitCoalition .. '"' .. ',' .. + '"' .. PlayerUnitCategory .. '"' .. ',' .. + '"' .. PlayerUnitType .. '"' .. ',' .. + '"' .. PlayerUnitName .. '"' .. ',' .. + '"' .. TargetUnitCoalition .. '"' .. ',' .. + '"' .. TargetUnitCategory .. '"' .. ',' .. + '"' .. TargetUnitType .. '"' .. ',' .. + '"' .. TargetUnitName .. '"' .. ',' .. + '' .. ScoreTimes .. '' .. ',' .. + '' .. ScoreAmount + ) + self.StatFile:write( "\n" ) end end diff --git a/Moose/Escort.lua b/Moose/Escort.lua index 60b6c4e6d..dd195b277 100644 --- a/Moose/Escort.lua +++ b/Moose/Escort.lua @@ -96,7 +96,8 @@ ESCORT = { FollowScheduler = nil, ReportTargets = true, OptionROE = AI.Option.Air.val.ROE.OPEN_FIRE, - OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION + OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION, + TaskPoints = {} } --- MENUPARAM type @@ -222,10 +223,11 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) -- Initialize the EscortGroup - EscortGroup:OptionROTVertical() - EscortGroup:OptionROEOpenFire() + self.EscortGroup:WayPointInitialize(1) + + self.EscortGroup:OptionROTVertical() + self.EscortGroup:OptionROEOpenFire() - EscortGroup:SetTask( EscortGroup:TaskRoute( TaskPoints ) ) self.ReportTargetsScheduler = routines.scheduleFunction( self._ReportTargetsScheduler, { self }, timer.getTime() + 1, 30 ) @@ -312,7 +314,7 @@ function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance ) end EscortGroup:OptionROEHoldFire() - EscortGroup:OptionROTVertical() + EscortGroup:OptionROTPassiveDefense() self.CT1 = 0 self.GT1 = 0 @@ -568,21 +570,13 @@ end --- Registers the waypoints -- @param #ESCORT self +-- @return #table function ESCORT:RegisterRoute() self:F() local EscortGroup = self.EscortGroup -- Group#GROUP local TaskPoints = EscortGroup:GetTaskRoute() - self:T( TaskPoints ) - - for TaskPointID, TaskPoint in pairs( TaskPoints ) do - self:T( { "TaskPoint:", TaskPointID, #TaskPoint.task.params.tasks+1, TaskPoint } ) - if TaskPointID > 1 then - TaskPoint.task.params.tasks[#TaskPoint.task.params.tasks+1] = EscortGroup:TaskRegisterWayPoint( TaskPointID ) - end - self:T( TaskPoint ) - end self:T( TaskPoints ) diff --git a/Moose/Group.lua b/Moose/Group.lua index a654a751a..8e4ddc502 100644 --- a/Moose/Group.lua +++ b/Moose/Group.lua @@ -20,6 +20,7 @@ GROUP = { GroupID = 0, Controller = nil, DCSGroup = nil, + WayPointFunctions = {}, } --- A DCSGroup @@ -91,6 +92,85 @@ function GROUP:NewFromDCSUnit( DCSUnit ) return self end +--- Retrieve the group mission and allow to place function hooks within the mission waypoint plan. +-- Use the method @{Group#GROUP:WayPointFunction} to define the hook functions for specific waypoints. +-- Use the method @{Group@GROUP:WayPointExecute) to start the execution of the new mission plan. +-- Note that when WayPointInitialize is called, the Mission of the group is RESTARTED! +-- @param #GROUP self +-- @param #number WayPoint +-- @return #GROUP +function GROUP:WayPointInitialize() + + self.WayPoints = self:GetTaskRoute() + + return self +end + + +--- Registers a waypoint function that will be executed when the group moves over the WayPoint. +-- @param #GROUP self +-- @param #number WayPoint The waypoint number. Note that the start waypoint on the route is WayPoint 1! +-- @param #number WayPointIndex When defining multiple WayPoint functions for one WayPoint, use WayPointIndex to set the sequence of actions. +-- @param #function WayPointFunction The waypoint function to be called when the group moves over the waypoint. The waypoint function takes variable parameters. +-- @return #GROUP +function GROUP:WayPointFunction( WayPoint, WayPointIndex, WayPointFunction, ... ) + self:F( { WayPoint, WayPointIndex, WayPointFunction } ) + + table.insert( self.WayPoints[WayPoint].task.params.tasks, WayPointIndex ) + self.WayPoints[WayPoint].task.params.tasks[WayPointIndex] = self:TaskFunction( WayPoint, WayPointIndex, WayPointFunction, arg ) + return self +end + + +function GROUP:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionArguments ) + + local DCSTask + + local DCSScript = {} + DCSScript[#DCSScript+1] = "local MissionGroup = GROUP.FindGroup( ... ) " + DCSScript[#DCSScript+1] = FunctionString .. "( MissionGroup, " .. table.concat( FunctionArguments, "," ) .. ")" + + DCSTask = self:TaskWrappedAction( + self:CommandDoScript( + table.concat( DCSScript ) + ), WayPointIndex + ) + + self:T( DCSTask ) + + return DCSTask + +end + + + +--- Executes the WayPoint plan. +-- The function gets a WayPoint parameter, that you can use to restart the mission at a specific WayPoint. +-- Note that when the WayPoint parameter is used, the new start mission waypoint of the group will be 1! +-- @param #GROUP self +-- @param #number WayPoint The WayPoint from where to execute the mission. +-- @param #WaitTime The amount seconds to wait before initiating the mission. +-- @return #GROUP +function GROUP:WayPointExecute( WayPoint, WaitTime ) + + if not WayPoint then + WayPoint = 1 + end + + -- When starting the mission from a certain point, the TaskPoints need to be deleted before the given WayPoint. + for TaskPointID = 1, WayPoint - 1 do + table.remove( self.WayPoints, 1 ) + end + + self:T( self.WayPoints ) + + self:SetTask( self:TaskRoute( self.WayPoints ), WaitTime ) + + return self +end + + + --- Gets the DCSGroup of the GROUP. -- @param #GROUP self -- @return DCSGroup#Group The DCSGroup. @@ -201,7 +281,7 @@ function GROUP:Destroy() self:F( self.GroupName ) for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - self:CreateEventDead( timer.getTime(), UnitData ) + self:CreateEventCrash( timer.getTime(), UnitData ) end self.DCSGroup:destroy() @@ -386,12 +466,20 @@ end --- Pushing Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self -function GROUP:PushTask( DCSTask ) +function GROUP:PushTask( DCSTask, WaitTime ) self:F() local Controller = self:_GetController() - Controller:pushTask( DCSTask ) + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller:pushTask( DCSTask ) + + if not WaitTime then + Controller:pushTask( DCSTask ) + else + routines.scheduleFunction( Controller.pushTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + end return self end @@ -399,13 +487,20 @@ end --- Clearing the Task Queue and Setting the Task on the queue from the group. -- @param #GROUP self -- @return Group#GROUP self -function GROUP:SetTask( DCSTask ) +function GROUP:SetTask( DCSTask, WaitTime ) self:F( { DCSTask } ) local Controller = self:_GetController() - Controller:setTask( DCSTask ) + -- When a group SPAWNs, it takes about a second to get the group in the simulator. Setting tasks to unspawned groups provides unexpected results. + -- Therefore we schedule the functions to set the mission and options for the Group. + -- Controller.setTask( Controller, DCSTask ) + if not WaitTime then + WaitTime = 1 + end + routines.scheduleFunction( Controller.setTask, { Controller, DCSTask }, timer.getTime() + WaitTime ) + return self end @@ -480,7 +575,7 @@ end -- @param #GROUP self -- @param DCSCommand#Command DCSCommand -- @return DCSTask#Task -function GROUP:TaskWrappedAction( DCSCommand ) +function GROUP:TaskWrappedAction( DCSCommand, Index ) self:F( { DCSCommand } ) local DCSTaskWrappedAction @@ -488,9 +583,11 @@ function GROUP:TaskWrappedAction( DCSCommand ) DCSTaskWrappedAction = { id = "WrappedAction", enabled = true, + number = Index, + auto = false, params = { - action = DCSCommand - } + action = DCSCommand, + }, } self:T( { DCSTaskWrappedAction } ) @@ -593,10 +690,15 @@ end -- @param Zone#ZONE Zone The zone where to land. -- @param #number Duration The duration in seconds to stay on the ground. -- @return #GROUP self -function GROUP:TaskLandAtZone( Zone, Duration ) - self:F( { self.GroupName, Zone, Duration } ) +function GROUP:TaskLandAtZone( Zone, Duration, RandomPoint ) + self:F( { self.GroupName, Zone, Duration, RandomPoint } ) - local Point = Zone:GetPointVec2() + local Point + if RandomPoint then + Point = Zone:GetRandomPointVec2() + else + Point = Zone:GetPointVec2() + end local DCSTask = self:TaskLandAtVec2( Point, Duration ) @@ -813,26 +915,7 @@ function GROUP:Route( GoPoints ) return self end ---- Registers a Task to be executed at a waypoint. --- @param #GROUP self --- @param #number WayPoint The waypoint where to execute the task. --- @return #string The task. -function GROUP:TaskRegisterWayPoint( WayPoint ) - local DCSTask - - DCSTask = self:TaskWrappedAction( - self:CommandDoScript( - "local MissionGroup = GROUP:New( ... ) " .. - "env.info( MissionGroup:GetName() ) " .. - "MissionGroup:RegisterWayPoint ( " .. WayPoint .. " )" - ) - ) - - self:T( DCSTask ) - - return DCSTask -end --- Route the group to a given zone. -- The group final destination point can be randomized. @@ -860,7 +943,7 @@ function GROUP:TaskRouteToZone( Zone, Randomize, Speed, Formation ) local ZonePoint if Randomize then - ZonePoint = Zone:GetRandomPoint() + ZonePoint = Zone:GetRandomPointVec2() else ZonePoint = Zone:GetPointVec2() end @@ -901,8 +984,8 @@ function GROUP:CommandDoScript( DoScript ) local DCSDoScript = { id = "Script", params = { - command = DoScript - } + command = DoScript, + }, } self:T( DCSDoScript ) @@ -1260,7 +1343,7 @@ end function GROUP:Message( Message, Duration ) self:F( { Message, Duration } ) - return MESSAGE:New( Message, self:GetCallsign() .. "(" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) + return MESSAGE:New( Message, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")", Duration, self:GetClassNameAndID() ) end --- Send a message to all coalitions. @@ -1308,12 +1391,6 @@ function GROUP:MessageToClient( Message, Duration, Client ) self:Message( Message, Duration ):ToClient( Client ) end -function GROUP:RegisterWayPoint( WayPoint ) - - self:Message( "Moving over wayPoint " .. WayPoint, 20 ):ToAll() - self.WayPoint = WayPoint -end - diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index eff339882..be3462ccf 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -444,6 +444,12 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) else self:T( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) self.SpawnGroups[self.SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate ) + + -- If there is a SpawnFunction hook defined, call it. + if self.SpawnFunctionHook then + self.SpawnFunctionHook( self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments ) ) + end + -- TODO: Need to fix this by putting an "R" in the name of the group when the group repeats. --if self.SpawnRepeat then -- _Database:SetStatusGroup( SpawnTemplate.name, "ReSpawn" ) --end @@ -482,7 +488,7 @@ function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation ) self.AliveFactor = 1 -- self.SpawnLowTimer = 0 self.SpawnHighTimer = 0 - + if SpawnTime ~= nil and SpawnTimeVariation ~= nil then self.SpawnLowTimer = SpawnTime - SpawnTime / 2 * SpawnTimeVariation self.SpawnHighTimer = SpawnTime + SpawnTime / 2 * SpawnTimeVariation @@ -494,6 +500,25 @@ function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation ) return self end +--- Allows to place a CallFunction hook when a new group spawns. +-- The provided function will be called when a new group is spawned, including its given parameters. +-- The first parameter of the SpawnFunction is the @{Group#GROUP} that was spawned. +-- @param #SPAWN self +-- @param #function SpawnFunctionHook The function to be called when a group spawns. +-- @param SpawnFunctionArguments A random amount of arguments to be provided to the function when the group spawns. +-- @return #SPAWN +function SPAWN:SpawnFunction( SpawnFunctionHook, ... ) + self:F( SpawnFunction ) + + self.SpawnFunctionHook = SpawnFunctionHook + self.SpawnFunctionArguments = {} + if arg then + self.SpawnFunctionArguments = arg + end + + return self +end + --- Will start the spawning scheduler. @@ -637,7 +662,7 @@ function SPAWN:SpawnInZone( Zone, SpawnIndex ) self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y ) end - local SpawnPos = Zone:GetRandomPoint() + local SpawnPos = Zone:GetRandomPointVec2() local Point = {} Point.type = "Turning Point" Point.x = SpawnPos.x @@ -1216,8 +1241,8 @@ function SPAWN:_SpawnCleanUpScheduler() while SpawnGroup do if SpawnGroup:AllOnGround() and SpawnGroup:GetMaxVelocity() < 1 then - if not self.SpanUwnCleanUpTimeStamps[SpawnGroup:GetName()] then - self.SpawnCleapTimeStamps[SpawnGroup:GetName()] = timer.getTime() + if not self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] then + self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] = timer.getTime() else if self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] + self.SpawnCleanUpInterval < timer.getTime() then self:T( { "CleanUp Scheduler:", "Cleaning:", SpawnGroup } ) diff --git a/Moose/Zone.lua b/Moose/Zone.lua index 760a15fd6..eb16cf63a 100644 --- a/Moose/Zone.lua +++ b/Moose/Zone.lua @@ -40,7 +40,7 @@ function ZONE:GetPointVec2() return Point end -function ZONE:GetRandomPoint() +function ZONE:GetRandomPointVec2() self:F( self.ZoneName ) local Point = {} diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua index fa4516e7a..e53577029 100644 --- a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua +++ b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua @@ -4,26 +4,22 @@ Include.File( "Spawn" ) Include.File( "Escort" ) -do +do local function EventAliveHelicopter( Client ) local EscortGroupHeli1 = SpawnEscortHeli:ReSpawn(1) local EscortHeli1 = ESCORT:New( Client, EscortGroupHeli1, "Escort Alpha" ) - local EscortGroupPlane = SpawnEscortPlane:ReSpawn(1) - local EscortPlane = ESCORT:New( Client, EscortGroupPlane, "Escort Test Plane" ) - local EscortGroupGround = SpawnEscortGround:ReSpawn(1) - local EscortGround = ESCORT:New( Client, EscortGroupGround, "Test Ground" ) end local function EventAlivePlane( Client ) - local EscortGroupPlane = SpawnEscortPlane:ReSpawn(1) - local EscortPlane = ESCORT:New( Client, EscortGroupPlane, "Escort Test Plane" ) + local EscortGroupPlane2 = SpawnEscortPlane:ReSpawn(1) + local EscortPlane2 = ESCORT:New( Client, EscortGroupPlane2, "Escort Test Plane" ) - local EscortGroupGround = SpawnEscortGround:ReSpawn(1) - local EscortGround = ESCORT:New( Client, EscortGroupGround, "Test Ground" ) + local EscortGroupGround2 = SpawnEscortGround:ReSpawn(1) + local EscortGround2 = ESCORT:New( Client, EscortGroupGround2, "Test Ground" ) - local EscortGroupShip = SpawnEscortShip:ReSpawn(1) - local EscortShip = ESCORT:New( Client, EscortGroupShip, "Test Ship" ) + local EscortGroupShip2 = SpawnEscortShip:ReSpawn(1) + local EscortShip2 = ESCORT:New( Client, EscortGroupShip2, "Test Ship" ) end SpawnEscortHeli = SPAWN:New( "Escort Helicopter" ) diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz index b644553bd..c0f47f112 100644 Binary files a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz and b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz differ diff --git a/Tools and Installation/DCS World - MOOSE - Development - Part 1 - Tools and Installation.pptx b/Tools and Installation/DCS World - MOOSE - Development - Part 1 - Tools and Installation.pptx new file mode 100644 index 000000000..a8abf34b8 Binary files /dev/null and b/Tools and Installation/DCS World - MOOSE - Development - Part 1 - Tools and Installation.pptx differ diff --git a/Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE.pptx b/Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE.pptx new file mode 100644 index 000000000..44d5a6499 Binary files /dev/null and b/Tools and Installation/DCS World - MOOSE - Development - Part 2 - Using Eclipse and MOOSE.pptx differ diff --git a/Install.bat b/Trash/Install.bat similarity index 100% rename from Install.bat rename to Trash/Install.bat diff --git a/Manual.md b/Trash/Manual.md similarity index 100% rename from Manual.md rename to Trash/Manual.md diff --git a/README.md b/Trash/README.md similarity index 100% rename from README.md rename to Trash/README.md diff --git a/config.ld b/Trash/config.ld similarity index 100% rename from config.ld rename to Trash/config.ld