Merge remote-tracking branch 'refs/remotes/origin/master' into Embedded

This commit is contained in:
FlightControl 2016-05-25 07:00:58 +02:00
commit 2a97df7ef9
111 changed files with 13650 additions and 4836 deletions

View File

@ -37,10 +37,11 @@
-- @return #Group.Category
--TODO check coalition.side
--- Returns coalition of the group.
--- Returns the coalition of the group.
-- @function [parent=#Group] getCoalition
-- @param #Group self
-- @return #coalition.side
-- @return DCSCoalitionObject#coalition.side
--- Returns the group's name. This is the same name assigned to the group in Mission Editor.
-- @function [parent=#Group] getName

View File

@ -1,2 +1,8 @@
-- @type ModelTime
-------------------------------------------------------------------------------
-- @module DCSTime
--- @type ModelTime
-- @extends #number
--- @type Time
-- @extends #number

26
Dcs/DCScountry.lua Normal file
View File

@ -0,0 +1,26 @@
-------------------------------------------------------------------------------
-- @module DCScountry
--- @type country
-- @field #country.id id
--- @type country.id
-- @field RUSSIA
-- @field UKRAINE
-- @field USA
-- @field TURKEY
-- @field UK
-- @field FRANCE
-- @field GERMANY
-- @field CANADA
-- @field SPAIN
-- @field THE_NETHERLANDS
-- @field BELGIUM
-- @field NORWAY
-- @field DENMARK
-- @field ISRAEL
-- @field GEORGIA
-- @field INSURGENTS
-- @field ABKHAZIA
-- @field SOUTH_OSETIA
-- @field ITALY

View File

@ -0,0 +1,8 @@
Include.File( "Group" )
Include.File( "Unit" )
local UnitAirPlaneAI = _DATABASE:FindUnit( "Airplane AI" )
UnitAirPlaneAI:FlareRed()

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -213,6 +216,8 @@
</dl>
<h2><a id="#(CARGO)" >Type <code>CARGO</code></a></h2>
<h2><a id="#(CARGO_ZONE)" >Type <code>CARGO_ZONE</code></a></h2>
</div>
</div>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -68,8 +71,43 @@
<p>The CLIENT models client units in multi player missions.</p>
<p>Clients are those groups defined within the Mission Editor that have the skillset defined as "Client" or "Player".
Note that clients are NOT the same as groups, they are NOT necessarily alive. </p>
<h1><a href="##(CLIENT)">#CLIENT</a> class</h1>
<p>Clients are those <strong>Units</strong> defined within the Mission Editor that have the skillset defined as <strong>Client</strong> or <strong>Player</strong>.
Note that clients are NOT the same as Units, they are NOT necessarily alive.
The <a href="CLIENT.html">CLIENT</a> class is a wrapper class to handle the DCS Unit objects that have the skillset defined as <strong>Client</strong> or <strong>Player</strong>:</p>
<ul>
<li>Wraps the DCS Unit objects with skill level set to Player or Client.</li>
<li>Support all DCS Unit APIs.</li>
<li>Enhance with Unit specific APIs not in the DCS Group API set.</li>
<li>When player joins Unit, execute alive init logic.</li>
<li>Handles messages to players.</li>
<li>Manage the "state" of the DCS Unit.</li>
</ul>
<p>Clients are being used by the <a href="MISSION.html">MISSION</a> class to follow players and register their successes.</p>
<h1>CLIENT reference methods</h1>
<p>For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _<a href="DATABASE.html">DATABASE</a> object.
This is done at the beginning of the mission (when the mission starts).</p>
<p>The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference
using the DCS Unit or the DCS UnitName.</p>
<p>Another thing to know is that CLIENT objects do not "contain" the DCS Unit object.
The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution.
If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file.</p>
<p>The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance:</p>
<ul>
<li><a href="##(CLIENT).Find">CLIENT.Find</a>(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object.</li>
<li><a href="##(CLIENT).FindByName">CLIENT.FindByName</a>(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name.</li>
</ul>
<p>IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).</p>
<h2>Global(s)</h2>
<table class="function_list">
@ -77,12 +115,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
<td class="name" nowrap="nowrap"><a href="#CLIENT">CLIENT</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="#ClientGroupUnit">ClientGroupUnit</a></td>
<td class="summary">
</td>
</tr>
</table>
@ -98,12 +130,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
<td class="name" nowrap="nowrap"><a href="##(CLIENT).Alive">CLIENT:Alive(CallBack, ...)</a></td>
<td class="summary">
<p>Checks for a client alive event and calls a function on a continuous basis.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).AliveCheckScheduler">CLIENT.AliveCheckScheduler</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -158,12 +184,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClientGroupUnit">CLIENT.ClientGroupUnit</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClientID">CLIENT.ClientID</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -176,12 +196,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClientParameters">CLIENT.ClientParameters</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClientPosition">CLIENT:ClientPosition()</a></td>
<td class="summary">
<p>Returns the position of the CLIENT in <a href="DCSTypes.html##(Vec3)">DCSTypes#Vec3</a> format.</p>
</td>
</tr>
<tr>
@ -191,9 +205,15 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).GetAltitude">CLIENT:GetAltitude()</a></td>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).Find">CLIENT:Find(ClientName, ClientBriefing, DCSUnit)</a></td>
<td class="summary">
<p>Returns the altitude of the CLIENT.</p>
<p>Finds a CLIENT from the _DATABASE using the relevant DCS Unit.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).FindByName">CLIENT:FindByName(ClientName, ClientBriefing)</a></td>
<td class="summary">
<p>Finds a CLIENT from the _DATABASE using the relevant Client Unit Name.</p>
</td>
</tr>
<tr>
@ -224,24 +244,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
<td class="name" nowrap="nowrap"><a href="##(CLIENT).GetDCSGroup">CLIENT:GetDCSGroup()</a></td>
<td class="summary">
<p>Return the DCSGroup of a Client.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).GetPointVec2">CLIENT:GetPointVec2()</a></td>
<td class="summary">
<p>Returns the position of the CLIENT in <a href="DCSTypes.html##(Vec2)">DCSTypes#Vec2</a> format..</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).GetUnit">CLIENT:GetUnit()</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).IsAlive">CLIENT:IsAlive()</a></td>
<td class="summary">
<p>Checks if client is alive and returns true or false.</p>
</td>
</tr>
<tr>
@ -287,13 +289,13 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).New">CLIENT:New(ClientName, ClientBriefing)</a></td>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ONBOARDSIDE">CLIENT.ONBOARDSIDE</a></td>
<td class="summary">
<p>Use this method to register new Clients within the MOF.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ONBOARDSIDE">CLIENT.ONBOARDSIDE</a></td>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).Register">CLIENT:Register(ClientName)</a></td>
<td class="summary">
</td>
@ -302,6 +304,12 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
<td class="name" nowrap="nowrap"><a href="##(CLIENT).Reset">CLIENT:Reset(ClientName)</a></td>
<td class="summary">
<p>Resets a CLIENT.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ShowBriefing">CLIENT:ShowBriefing()</a></td>
<td class="summary">
<p>Show the briefing of the MISSION to the CLIENT.</p>
</td>
</tr>
<tr>
@ -355,20 +363,6 @@ Note that clients are NOT the same as groups, they are NOT necessarily alive. </
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="ClientGroupUnit" >
<strong>ClientGroupUnit</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<h2><a id="#(Client)" >Type <code>Client</code></a></h2>
@ -400,8 +394,8 @@ is the text defining the Mission briefing.</p>
</ul>
<h3>Return value</h3>
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em></p>
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em>
self</p>
</dd>
</dl>
@ -435,20 +429,6 @@ Function.</p>
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(CLIENT).AliveCheckScheduler" >
<strong>CLIENT.AliveCheckScheduler</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -538,6 +518,7 @@ Function.</p>
<dl class="function">
<dt>
<em></em>
<a id="#(CLIENT).ClientGroupID" >
<strong>CLIENT.ClientGroupID</strong>
</a>
@ -565,7 +546,6 @@ Function.</p>
<dl class="function">
<dt>
<em></em>
<a id="#(CLIENT).ClientGroupUnit" >
<strong>CLIENT.ClientGroupUnit</strong>
</a>
@ -574,20 +554,6 @@ Function.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(CLIENT).ClientID" >
<strong>CLIENT.ClientID</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -615,24 +581,6 @@ Function.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).ClientPosition" >
<strong>CLIENT:ClientPosition()</strong>
</a>
</dt>
<dd>
<p>Returns the position of the CLIENT in <a href="DCSTypes.html##(Vec3)">DCSTypes#Vec3</a> format.</p>
<h3>Return value</h3>
<p><em><a href="DCSTypes.html##(Vec3)">DCSTypes#Vec3</a>:</em></p>
</dd>
</dl>
<dl class="function">
@ -652,19 +600,95 @@ Function.</p>
<dl class="function">
<dt>
<a id="#(CLIENT).GetAltitude" >
<strong>CLIENT:GetAltitude()</strong>
<a id="#(CLIENT).Find" >
<strong>CLIENT:Find(ClientName, ClientBriefing, DCSUnit)</strong>
</a>
</dt>
<dd>
<p>Returns the altitude of the CLIENT.</p>
<p>Finds a CLIENT from the _DATABASE using the relevant DCS Unit.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#string ClientName </em></code>:
Name of the DCS <strong>Unit</strong> as defined within the Mission Editor.</p>
</li>
<li>
<p><code><em>#string ClientBriefing </em></code>:
Text that describes the briefing of the mission when a Player logs into the Client.</p>
</li>
<li>
<p><code><em> DCSUnit </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="DCSTypes.html##(Distance)">DCSTypes#Distance</a>:</em></p>
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em></p>
<h3>Usage:</h3>
<pre class="example"><code>-- Create new Clients.
local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
Mission:AddGoal( DeploySA6TroopsGoal )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )</code></pre>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).FindByName" >
<strong>CLIENT:FindByName(ClientName, ClientBriefing)</strong>
</a>
</dt>
<dd>
<p>Finds a CLIENT from the _DATABASE using the relevant Client Unit Name.</p>
<p>As an optional parameter, a briefing text can be given also.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#string ClientName </em></code>:
Name of the DCS <strong>Unit</strong> as defined within the Mission Editor.</p>
</li>
<li>
<p><code><em>#string ClientBriefing </em></code>:
Text that describes the briefing of the mission when a Player logs into the Client.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em></p>
<h3>Usage:</h3>
<pre class="example"><code>-- Create new Clients.
local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
Mission:AddGoal( DeploySA6TroopsGoal )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )</code></pre>
</dd>
</dl>
<dl class="function">
@ -759,53 +783,6 @@ Function.</p>
<p><em><a href="DCSGroup.html##(Group)">DCSGroup#Group</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).GetPointVec2" >
<strong>CLIENT:GetPointVec2()</strong>
</a>
</dt>
<dd>
<p>Returns the position of the CLIENT in <a href="DCSTypes.html##(Vec2)">DCSTypes#Vec2</a> format..</p>
<h3>Return value</h3>
<p><em><a href="DCSTypes.html##(Vec2)">DCSTypes#Vec2</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).GetUnit" >
<strong>CLIENT:GetUnit()</strong>
</a>
</dt>
<dd>
<p> TODO what is this??? check. possible double function.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).IsAlive" >
<strong>CLIENT:IsAlive()</strong>
</a>
</dt>
<dd>
<p>Checks if client is alive and returns true or false.</p>
</dd>
</dl>
<dl class="function">
@ -947,49 +924,6 @@ is the interval in seconds between the display of the <a href="Message.html##(ME
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).New" >
<strong>CLIENT:New(ClientName, ClientBriefing)</strong>
</a>
</dt>
<dd>
<p>Use this method to register new Clients within the MOF.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#string ClientName </em></code>:
Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client.</p>
</li>
<li>
<p><code><em>#string ClientBriefing </em></code>:
Text that describes the briefing of the mission when a Player logs into the Client.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em></p>
<h3>Usage:</h3>
<pre class="example"><code>-- Create new Clients.
local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
Mission:AddGoal( DeploySA6TroopsGoal )
Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )</code></pre>
</dd>
</dl>
<dl class="function">
@ -1004,6 +938,27 @@ Text that describes the briefing of the mission when a Player logs into the Clie
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).Register" >
<strong>CLIENT:Register(ClientName)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> ClientName </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
@ -1031,6 +986,24 @@ Name of the Group as defined within the Mission Editor. The Group must have a Un
<dl class="function">
<dt>
<a id="#(CLIENT).ShowBriefing" >
<strong>CLIENT:ShowBriefing()</strong>
</a>
</dt>
<dd>
<p>Show the briefing of the MISSION to the CLIENT.</p>
<h3>Return value</h3>
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(CLIENT).ShowCargo" >
<strong>CLIENT:ShowCargo()</strong>
</a>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -106,6 +109,12 @@
<td class="name" nowrap="nowrap"><a href="##(Group).getCategory">Group:getCategory()</a></td>
<td class="summary">
<p>Returns category of the group.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(Group).getCoalition">Group:getCoalition()</a></td>
<td class="summary">
<p>Returns the coalition of the group.</p>
</td>
</tr>
<tr>
@ -291,6 +300,24 @@
<p><em><a href="##(Group.Category)">#Group.Category</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(Group).getCoalition" >
<strong>Group:getCoalition()</strong>
</a>
</dt>
<dd>
<p>Returns the coalition of the group.</p>
<h3>Return value</h3>
<p><em><a href="DCSCoalitionObject.html##(coalition.side)">DCSCoalitionObject#coalition.side</a>:</em></p>
</dd>
</dl>
<dl class="function">

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -151,7 +154,25 @@ The following iterator methods are currently available within the DATABASE:</p>
<h2><a id="#(DATABASE)">Type <code>DATABASE</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).AlivePlayers">DATABASE.AlivePlayers</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).AddClient">DATABASE:AddClient(ClientName)</a></td>
<td class="summary">
<p>Adds a CLIENT based on the ClientName in the DATABASE.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).AddGroup">DATABASE:AddGroup(DCSGroup, GroupName)</a></td>
<td class="summary">
<p>Adds a GROUP based on the GroupName in the DATABASE.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).AddUnit">DATABASE:AddUnit(DCSUnit, DCSUnitName)</a></td>
<td class="summary">
<p>Adds a Unit based on the Unit Name in the DATABASE.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).CLIENTS">DATABASE.CLIENTS</a></td>
<td class="summary">
</td>
@ -163,13 +184,7 @@ The following iterator methods are currently available within the DATABASE:</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ClientsByID">DATABASE.ClientsByID</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ClientsByName">DATABASE.ClientsByName</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ClientsAlive">DATABASE.ClientsAlive</a></td>
<td class="summary">
</td>
@ -178,12 +193,6 @@ The following iterator methods are currently available within the DATABASE:</p>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).DCSGroups">DATABASE.DCSGroups</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).DCSGroupsAlive">DATABASE.DCSGroupsAlive</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -193,39 +202,15 @@ The following iterator methods are currently available within the DATABASE:</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).DCSUnitsAlive">DATABASE.DCSUnitsAlive</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).DeleteUnit">DATABASE:DeleteUnit(DCSUnitName)</a></td>
<td class="summary">
<p>Deletes a Unit from the DATABASE based on the Unit Name.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).Filter">DATABASE.Filter</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FilterCategories">DATABASE:FilterCategories(Categories)</a></td>
<td class="summary">
<p>Builds a set of units out of categories.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FilterCoalitions">DATABASE:FilterCoalitions(Coalitions)</a></td>
<td class="summary">
<p>Builds a set of units of coalitons.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FilterCountries">DATABASE:FilterCountries(Countries)</a></td>
<td class="summary">
<p>Builds a set of units of defined countries.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FilterGroupPrefixes">DATABASE:FilterGroupPrefixes(Prefixes)</a></td>
<td class="summary">
<p>Builds a set of units of defined group prefixes.</p>
</td>
</tr>
<tr>
@ -235,39 +220,57 @@ The following iterator methods are currently available within the DATABASE:</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FilterStart">DATABASE:FilterStart()</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FindClient">DATABASE:FindClient(ClientName)</a></td>
<td class="summary">
<p>Starts the filtering.</p>
<p>Finds a CLIENT based on the ClientName.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FilterTypes">DATABASE:FilterTypes(Types)</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FindGroup">DATABASE:FindGroup(GroupName)</a></td>
<td class="summary">
<p>Builds a set of units of defined unit types.</p>
<p>Finds a GROUP based on the GroupName.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FilterUnitPrefixes">DATABASE:FilterUnitPrefixes(Prefixes)</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).FindUnit">DATABASE:FindUnit(UnitName)</a></td>
<td class="summary">
<p>Builds a set of units of defined unit prefixes.</p>
<p>Finds a Unit based on the Unit Name.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ForEachAliveUnit">DATABASE:ForEachAliveUnit(IteratorFunction, ...)</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ForEach">DATABASE:ForEach(IteratorFunction, arg, Set)</a></td>
<td class="summary">
<p>Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ForEachClient">DATABASE:ForEachClient(IteratorFunction, ...)</a></td>
<td class="summary">
<p>Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ForEachDCSUnit">DATABASE:ForEachDCSUnit(IteratorFunction, ...)</a></td>
<td class="summary">
<p>Interate the DATABASE and call an interator function for each <strong>alive</strong> unit, providing the Unit and optional parameters.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).ForEachPlayer">DATABASE:ForEachPlayer(IteratorFunction, ...)</a></td>
<td class="summary">
<p>Interate the DATABASE and call an interator function for each <strong>alive</strong> player, providing the Unit of the player and optional parameters.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).GROUPS">DATABASE.GROUPS</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).GetStatusGroup">DATABASE:GetStatusGroup(GroupName)</a></td>
<td class="summary">
<p>Get a status to a Group within the Database, this to check crossing events for example.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).Groups">DATABASE.Groups</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -286,6 +289,12 @@ The following iterator methods are currently available within the DATABASE:</p>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).Players">DATABASE.Players</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).PlayersAlive">DATABASE.PlayersAlive</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -310,6 +319,12 @@ The following iterator methods are currently available within the DATABASE:</p>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).Statics">DATABASE.Statics</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).Templates">DATABASE.Templates</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -319,7 +334,7 @@ The following iterator methods are currently available within the DATABASE:</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).Units">DATABASE.Units</a></td>
<td class="name" nowrap="nowrap"><a href="##(DATABASE).UNITS">DATABASE.UNITS</a></td>
<td class="summary">
</td>
@ -334,6 +349,24 @@ The following iterator methods are currently available within the DATABASE:</p>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._EventOnDeadOrCrash">DATABASE:_EventOnDeadOrCrash(Event)</a></td>
<td class="summary">
<p>Handles the OnDead or OnCrash event for alive units set.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._EventOnPlayerEnterUnit">DATABASE:_EventOnPlayerEnterUnit(Event)</a></td>
<td class="summary">
<p>Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._EventOnPlayerLeaveUnit">DATABASE:_EventOnPlayerLeaveUnit(Event)</a></td>
<td class="summary">
<p>Handles the OnPlayerLeaveUnit event to clean the active players table.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._IsAliveDCSGroup">DATABASE:_IsAliveDCSGroup(DCSGroup)</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -346,12 +379,24 @@ The following iterator methods are currently available within the DATABASE:</p>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._IsIncludeDCSUnit">DATABASE:_IsIncludeDCSUnit(DCSUnit)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._RegisterDatabase">DATABASE:_RegisterDatabase()</a></td>
<td class="summary">
<p>Private method that registers all datapoints within in the mission.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._RegisterGroup">DATABASE:_RegisterGroup(GroupTemplate)</a></td>
<td class="summary">
<p>Registers new Group Templates within the DATABASE Object.</p>
<p>Private method that registers new Group Templates within the DATABASE Object.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(DATABASE)._RegisterPlayers">DATABASE:_RegisterPlayers()</a></td>
<td class="summary">
<p>Private method that registers all alive players in the mission.</p>
</td>
</tr>
</table>
@ -381,9 +426,82 @@ The following iterator methods are currently available within the DATABASE:</p>
<dl class="function">
<dt>
<a id="#(DATABASE).AddClient" >
<strong>DATABASE:AddClient(ClientName)</strong>
</a>
</dt>
<dd>
<p>Adds a CLIENT based on the ClientName in the DATABASE.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> ClientName </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).AddGroup" >
<strong>DATABASE:AddGroup(DCSGroup, GroupName)</strong>
</a>
</dt>
<dd>
<p>Adds a GROUP based on the GroupName in the DATABASE.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> DCSGroup </em></code>: </p>
</li>
<li>
<p><code><em> GroupName </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).AddUnit" >
<strong>DATABASE:AddUnit(DCSUnit, DCSUnitName)</strong>
</a>
</dt>
<dd>
<p>Adds a Unit based on the Unit Name in the DATABASE.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> DCSUnit </em></code>: </p>
</li>
<li>
<p><code><em> DCSUnitName </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).AlivePlayers" >
<strong>DATABASE.AlivePlayers</strong>
<a id="#(DATABASE).CLIENTS" >
<strong>DATABASE.CLIENTS</strong>
</a>
</dt>
<dd>
@ -410,22 +528,8 @@ The following iterator methods are currently available within the DATABASE:</p>
<dt>
<em></em>
<a id="#(DATABASE).ClientsByID" >
<strong>DATABASE.ClientsByID</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).ClientsByName" >
<strong>DATABASE.ClientsByName</strong>
<a id="#(DATABASE).ClientsAlive" >
<strong>DATABASE.ClientsAlive</strong>
</a>
</dt>
<dd>
@ -446,20 +550,6 @@ The following iterator methods are currently available within the DATABASE:</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).DCSGroupsAlive" >
<strong>DATABASE.DCSGroupsAlive</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -479,15 +569,22 @@ The following iterator methods are currently available within the DATABASE:</p>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).DCSUnitsAlive" >
<strong>DATABASE.DCSUnitsAlive</strong>
<a id="#(DATABASE).DeleteUnit" >
<strong>DATABASE:DeleteUnit(DCSUnitName)</strong>
</a>
</dt>
<dd>
<p>Deletes a Unit from the DATABASE based on the Unit Name.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> DCSUnitName </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
@ -502,126 +599,6 @@ The following iterator methods are currently available within the DATABASE:</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).FilterCategories" >
<strong>DATABASE:FilterCategories(Categories)</strong>
</a>
</dt>
<dd>
<p>Builds a set of units out of categories.</p>
<p>Possible current categories are plane, helicopter, ground, ship.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string Categories </em></code>:
Can take the following values: "plane", "helicopter", "ground", "ship".</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).FilterCoalitions" >
<strong>DATABASE:FilterCoalitions(Coalitions)</strong>
</a>
</dt>
<dd>
<p>Builds a set of units of coalitons.</p>
<p>Possible current coalitions are red, blue and neutral.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string Coalitions </em></code>:
Can take the following values: "red", "blue", "neutral".</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).FilterCountries" >
<strong>DATABASE:FilterCountries(Countries)</strong>
</a>
</dt>
<dd>
<p>Builds a set of units of defined countries.</p>
<p>Possible current countries are those known within DCS world.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string Countries </em></code>:
Can take those country strings known within DCS world.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).FilterGroupPrefixes" >
<strong>DATABASE:FilterGroupPrefixes(Prefixes)</strong>
</a>
</dt>
<dd>
<p>Builds a set of units of defined group prefixes.</p>
<p>All the units starting with the given group prefixes will be included within the set.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string Prefixes </em></code>:
The prefix of which the group name where the unit belongs to starts with.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
@ -641,41 +618,108 @@ self</p>
<dl class="function">
<dt>
<a id="#(DATABASE).FilterStart" >
<strong>DATABASE:FilterStart()</strong>
<a id="#(DATABASE).FindClient" >
<strong>DATABASE:FindClient(ClientName)</strong>
</a>
</dt>
<dd>
<p>Starts the filtering.</p>
<p>Finds a CLIENT based on the ClientName.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string ClientName </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
<p><em><a href="Client.html##(CLIENT)">Client#CLIENT</a>:</em>
The found CLIENT.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).FilterTypes" >
<strong>DATABASE:FilterTypes(Types)</strong>
<a id="#(DATABASE).FindGroup" >
<strong>DATABASE:FindGroup(GroupName)</strong>
</a>
</dt>
<dd>
<p>Builds a set of units of defined unit types.</p>
<p>Possible current types are those types known within DCS world.</p>
<p>Finds a GROUP based on the GroupName.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string Types </em></code>:
Can take those type strings known within DCS world.</p>
<p><code><em>#string GroupName </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="Group.html##(GROUP)">Group#GROUP</a>:</em>
The found GROUP.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).FindUnit" >
<strong>DATABASE:FindUnit(UnitName)</strong>
</a>
</dt>
<dd>
<p>Finds a Unit based on the Unit Name.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#string UnitName </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="Unit.html##(UNIT)">Unit#UNIT</a>:</em>
The found Unit.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).ForEach" >
<strong>DATABASE:ForEach(IteratorFunction, arg, Set)</strong>
</a>
</dt>
<dd>
<p>Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#function IteratorFunction </em></code>:
The function that will be called when there is an alive player in the database.</p>
</li>
<li>
<p><code><em> arg </em></code>: </p>
</li>
<li>
<p><code><em> Set </em></code>: </p>
</li>
</ul>
@ -689,23 +733,25 @@ self</p>
<dl class="function">
<dt>
<a id="#(DATABASE).FilterUnitPrefixes" >
<strong>DATABASE:FilterUnitPrefixes(Prefixes)</strong>
<a id="#(DATABASE).ForEachClient" >
<strong>DATABASE:ForEachClient(IteratorFunction, ...)</strong>
</a>
</dt>
<dd>
<p>Builds a set of units of defined unit prefixes.</p>
<p>Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters.</p>
<p>All the units starting with the given prefixes will be included within the set.</p>
<h3>Parameter</h3>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#string Prefixes </em></code>:
The prefix of which the unit name starts with.</p>
<p><code><em>#function IteratorFunction </em></code>:
The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter.</p>
</li>
<li>
<p><code><em> ... </em></code>: </p>
</li>
</ul>
@ -719,8 +765,8 @@ self</p>
<dl class="function">
<dt>
<a id="#(DATABASE).ForEachAliveUnit" >
<strong>DATABASE:ForEachAliveUnit(IteratorFunction, ...)</strong>
<a id="#(DATABASE).ForEachDCSUnit" >
<strong>DATABASE:ForEachDCSUnit(IteratorFunction, ...)</strong>
</a>
</dt>
<dd>
@ -746,6 +792,52 @@ The function that will be called when there is an alive unit in the database. Th
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE).ForEachPlayer" >
<strong>DATABASE:ForEachPlayer(IteratorFunction, ...)</strong>
</a>
</dt>
<dd>
<p>Interate the DATABASE and call an interator function for each <strong>alive</strong> player, providing the Unit of the player and optional parameters.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#function IteratorFunction </em></code>:
The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter.</p>
</li>
<li>
<p><code><em> ... </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).GROUPS" >
<strong>DATABASE.GROUPS</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -767,20 +859,6 @@ self</p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).Groups" >
<strong>DATABASE.Groups</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -831,6 +909,20 @@ DBObject = DATABASE:New()</code></pre>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).PlayersAlive" >
<strong>DATABASE.PlayersAlive</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -892,10 +984,15 @@ This method is used by the SPAWN class.</p>
<ul>
<li>
<p><code><em> SpawnTemplate </em></code>: </p>
<p><code><em>#table SpawnTemplate </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
@ -910,6 +1007,20 @@ This method is used by the SPAWN class.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(DATABASE).Templates" >
<strong>DATABASE.Templates</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -937,8 +1048,8 @@ self</p>
<dt>
<em></em>
<a id="#(DATABASE).Units" >
<strong>DATABASE.Units</strong>
<a id="#(DATABASE).UNITS" >
<strong>DATABASE.UNITS</strong>
</a>
</dt>
<dd>
@ -992,6 +1103,74 @@ self</p>
<dl class="function">
<dt>
<a id="#(DATABASE)._EventOnPlayerEnterUnit" >
<strong>DATABASE:_EventOnPlayerEnterUnit(Event)</strong>
</a>
</dt>
<dd>
<p>Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Event.html##(EVENTDATA)">Event#EVENTDATA</a> Event </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE)._EventOnPlayerLeaveUnit" >
<strong>DATABASE:_EventOnPlayerLeaveUnit(Event)</strong>
</a>
</dt>
<dd>
<p>Handles the OnPlayerLeaveUnit event to clean the active players table.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Event.html##(EVENTDATA)">Event#EVENTDATA</a> Event </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE)._IsAliveDCSGroup" >
<strong>DATABASE:_IsAliveDCSGroup(DCSGroup)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="DCSGroup.html##(Group)">DCSGroup#Group</a> DCSGroup </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE)._IsAliveDCSUnit" >
<strong>DATABASE:_IsAliveDCSUnit(DCSUnit)</strong>
</a>
@ -1044,22 +1223,63 @@ self</p>
<dl class="function">
<dt>
<a id="#(DATABASE)._RegisterDatabase" >
<strong>DATABASE:_RegisterDatabase()</strong>
</a>
</dt>
<dd>
<p>Private method that registers all datapoints within in the mission.</p>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE)._RegisterGroup" >
<strong>DATABASE:_RegisterGroup(GroupTemplate)</strong>
</a>
</dt>
<dd>
<p>Registers new Group Templates within the DATABASE Object.</p>
<p>Private method that registers new Group Templates within the DATABASE Object.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> GroupTemplate </em></code>: </p>
<p><code><em>#table GroupTemplate </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(DATABASE)._RegisterPlayers" >
<strong>DATABASE:_RegisterPlayers()</strong>
</a>
</dt>
<dd>
<p>Private method that registers all alive players in the mission.</p>
<h3>Return value</h3>
<p><em><a href="##(DATABASE)">#DATABASE</a>:</em>
self</p>
</dd>
</dl>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -232,6 +235,18 @@
<td class="name" nowrap="nowrap"><a href="##(EVENT).OnPilotDeadForUnit">EVENT:OnPilotDeadForUnit(EventDCSUnitName, EventFunction, EventSelf)</a></td>
<td class="summary">
<p>Set a new listener for an S<em>EVENT</em>PILOT_DEAD event.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(EVENT).OnPlayerEnterUnit">EVENT:OnPlayerEnterUnit(EventFunction, EventSelf)</a></td>
<td class="summary">
<p>Set a new listener for an S<em>EVENT</em>PLAYER<em>ENTER</em>UNIT event.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(EVENT).OnPlayerLeaveUnit">EVENT:OnPlayerLeaveUnit(EventFunction, EventSelf)</a></td>
<td class="summary">
<p>Set a new listener for an S<em>EVENT</em>PLAYER<em>LEAVE</em>UNIT event.</p>
</td>
</tr>
<tr>
@ -1259,6 +1274,72 @@ The self instance of the class for which the event is.</p>
<p><em><a href="##(EVENT)">#EVENT</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(EVENT).OnPlayerEnterUnit" >
<strong>EVENT:OnPlayerEnterUnit(EventFunction, EventSelf)</strong>
</a>
</dt>
<dd>
<p>Set a new listener for an S<em>EVENT</em>PLAYER<em>ENTER</em>UNIT event.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#function EventFunction </em></code>:
The function to be called when the event occurs for the unit.</p>
</li>
<li>
<p><code><em><a href="Base.html##(BASE)">Base#BASE</a> EventSelf </em></code>:
The self instance of the class for which the event is.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(EVENT)">#EVENT</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(EVENT).OnPlayerLeaveUnit" >
<strong>EVENT:OnPlayerLeaveUnit(EventFunction, EventSelf)</strong>
</a>
</dt>
<dd>
<p>Set a new listener for an S<em>EVENT</em>PLAYER<em>LEAVE</em>UNIT event.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#function EventFunction </em></code>:
The function to be called when the event occurs for the unit.</p>
</li>
<li>
<p><code><em><a href="Base.html##(BASE)">Base#BASE</a> EventSelf </em></code>:
The self instance of the class for which the event is.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(EVENT)">#EVENT</a>:</em></p>
</dd>
</dl>
<dl class="function">

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

File diff suppressed because it is too large Load Diff

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -284,12 +287,6 @@ A <a href="CLIENT.html">CLIENT</a> needs to be registered within the <a href="MI
<td class="name" nowrap="nowrap"><a href="##(MISSION).SUCCESS">MISSION.SUCCESS</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSION).ShowBriefing">MISSION.ShowBriefing(CLIENT, self, Client)</a></td>
<td class="summary">
<p>Show the briefing of the MISSION to the CLIENT.</p>
</td>
</tr>
<tr>
@ -1168,43 +1165,6 @@ local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical',
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSION).ShowBriefing" >
<strong>MISSION.ShowBriefing(CLIENT, self, Client)</strong>
</a>
</dt>
<dd>
<p>Show the briefing of the MISSION to the CLIENT.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> CLIENT </em></code>:
Client to show briefing to.</p>
</li>
<li>
<p><code><em> self </em></code>: </p>
</li>
<li>
<p><code><em> Client </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p>CLIENT</p>
</dd>
</dl>
<dl class="function">

View File

@ -46,12 +46,15 @@
<li>MOVEMENT</li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li>Menu</li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -91,6 +94,18 @@
<td class="name" nowrap="nowrap"><a href="#MENU_CLIENT_COMMAND">MENU_CLIENT_COMMAND</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="#MENU_COALITION">MENU_COALITION</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="#MENU_COALITION_COMMAND">MENU_COALITION_COMMAND</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -208,6 +223,56 @@
<td class="name" nowrap="nowrap"><a href="##(MENU_CLIENT_COMMAND).Remove">MENU_CLIENT_COMMAND:Remove()</a></td>
<td class="summary">
</td>
</tr>
</table>
<h2><a id="#(MENU_COALITION)">Type <code>MENU_COALITION</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(MENU_COALITION).ClassName">MENU_COALITION.ClassName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MENU_COALITION).New">MENU_COALITION:New(MenuCoalition, MenuText, ParentMenu)</a></td>
<td class="summary">
<p>Creates a new coalition menu item</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MENU_COALITION).Remove">MENU_COALITION:Remove()</a></td>
<td class="summary">
<p>Removes the sub menus recursively of this MENU_COALITION.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MENU_COALITION).RemoveSubMenus">MENU_COALITION:RemoveSubMenus()</a></td>
<td class="summary">
<p>Removes the sub menus recursively of this MENU_COALITION.</p>
</td>
</tr>
</table>
<h2><a id="#(MENU_COALITION_COMMAND)">Type <code>MENU_COALITION_COMMAND</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(MENU_COALITION_COMMAND).ClassName">MENU_COALITION_COMMAND.ClassName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MENU_COALITION_COMMAND).New">MENU_COALITION_COMMAND:New(MenuCoalition, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument)</a></td>
<td class="summary">
<p>Creates a new radio command item for a group</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MENU_COALITION_COMMAND).Remove">MENU_COALITION_COMMAND:Remove()</a></td>
<td class="summary">
<p>Removes a radio command item for a coalition</p>
</td>
</tr>
</table>
@ -283,6 +348,34 @@
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="##(MENU_COALITION)">#MENU_COALITION</a></em>
<a id="MENU_COALITION" >
<strong>MENU_COALITION</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="##(MENU_COALITION_COMMAND)">#MENU_COALITION_COMMAND</a></em>
<a id="MENU_COALITION_COMMAND" >
<strong>MENU_COALITION_COMMAND</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -645,6 +738,190 @@ self</p>
</dd>
</dl>
<h2><a id="#(MENU_COALITION)" >Type <code>MENU_COALITION</code></a></h2>
<p>The MENU_COALITION class</p>
<h3>Field(s)</h3>
<dl class="function">
<dt>
<em>#string</em>
<a id="#(MENU_COALITION).ClassName" >
<strong>MENU_COALITION.ClassName</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MENU_COALITION).New" >
<strong>MENU_COALITION:New(MenuCoalition, MenuText, ParentMenu)</strong>
</a>
</dt>
<dd>
<p>Creates a new coalition menu item</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="DCSCoalition.html##(coalition.side)">DCSCoalition#coalition.side</a> MenuCoalition </em></code>:
The coalition owning the menu.</p>
</li>
<li>
<p><code><em>#string MenuText </em></code>:
The text for the menu.</p>
</li>
<li>
<p><code><em>#table ParentMenu </em></code>:
The parent menu.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MENU_COALITION)">#MENU_COALITION</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MENU_COALITION).Remove" >
<strong>MENU_COALITION:Remove()</strong>
</a>
</dt>
<dd>
<p>Removes the sub menus recursively of this MENU_COALITION.</p>
<h3>Return value</h3>
<p><em><a href="##(MENU_COALITION)">#MENU_COALITION</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MENU_COALITION).RemoveSubMenus" >
<strong>MENU_COALITION:RemoveSubMenus()</strong>
</a>
</dt>
<dd>
<p>Removes the sub menus recursively of this MENU_COALITION.</p>
<h3>Return value</h3>
<p><em><a href="##(MENU_COALITION)">#MENU_COALITION</a>:</em>
self</p>
</dd>
</dl>
<h2><a id="#(MENU_COALITION_COMMAND)" >Type <code>MENU_COALITION_COMMAND</code></a></h2>
<p>The MENU<em>COALITION</em>COMMAND class</p>
<h3>Field(s)</h3>
<dl class="function">
<dt>
<em>#string</em>
<a id="#(MENU_COALITION_COMMAND).ClassName" >
<strong>MENU_COALITION_COMMAND.ClassName</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MENU_COALITION_COMMAND).New" >
<strong>MENU_COALITION_COMMAND:New(MenuCoalition, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument)</strong>
</a>
</dt>
<dd>
<p>Creates a new radio command item for a group</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="DCSCoalition.html##(coalition.side)">DCSCoalition#coalition.side</a> MenuCoalition </em></code>:
The coalition owning the menu.</p>
</li>
<li>
<p><code><em> MenuText </em></code>:
The text for the menu.</p>
</li>
<li>
<p><code><em> ParentMenu </em></code>:
The parent menu.</p>
</li>
<li>
<p><code><em> CommandMenuFunction </em></code>:
A function that is called when the menu key is pressed.</p>
</li>
<li>
<p><code><em> CommandMenuArgument </em></code>:
An argument for the function.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MENU_COALITION_COMMAND)">#MENU<em>COALITION</em>COMMAND</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MENU_COALITION_COMMAND).Remove" >
<strong>MENU_COALITION_COMMAND:Remove()</strong>
</a>
</dt>
<dd>
<p>Removes a radio command item for a coalition</p>
<h3>Return value</h3>
<p><em><a href="##(MENU_COALITION_COMMAND)">#MENU<em>COALITION</em>COMMAND</a>:</em>
self</p>
</dd>
</dl>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li>Message</li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -0,0 +1,931 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div>
<div id="main">
<div id="navigation">
<h2>Modules</h2>
<ul><li>
<a href="index.html">index</a>
</li></ul>
<ul>
<li><a href="Base.html">Base</a></li>
<li><a href="CARGO.html">CARGO</a></li>
<li><a href="CleanUp.html">CleanUp</a></li>
<li><a href="Client.html">Client</a></li>
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
<li><a href="DCSCommand.html">DCSCommand</a></li>
<li><a href="DCSController.html">DCSController</a></li>
<li><a href="DCSGroup.html">DCSGroup</a></li>
<li><a href="DCSObject.html">DCSObject</a></li>
<li><a href="DCSTask.html">DCSTask</a></li>
<li><a href="DCSTypes.html">DCSTypes</a></li>
<li><a href="DCSUnit.html">DCSUnit</a></li>
<li><a href="DCSWorld.html">DCSWorld</a></li>
<li><a href="DCStimer.html">DCStimer</a></li>
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
<li><a href="Database.html">Database</a></li>
<li><a href="Escort.html">Escort</a></li>
<li><a href="Event.html">Event</a></li>
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
<li><a href="Group.html">Group</a></li>
<li><a href="MISSION.html">MISSION</a></li>
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li>MissileTrainer</li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
<li><a href="Unit.html">Unit</a></li>
<li><a href="Zone.html">Zone</a></li>
<li><a href="env.html">env</a></li>
<li><a href="land.html">land</a></li>
<li><a href="routines.html">routines</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>MissileTrainer</code></h1>
<p>Provides missile training functions.</p>
<h1><a href="##(MISSILETRAINER)">#MISSILETRAINER</a> class</h1>
<p>The <a href="##(MISSILETRAINER)">#MISSILETRAINER</a> class uses the DCS world messaging system to be alerted of any missiles fired, and when a missile would hit your aircraft,
the class will destroy the missile within a certain range, to avoid damage to your aircraft.
It suports the following functionality:</p>
<ul>
<li>Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes.</li>
<li>Provide alerts of missile launches, including detailed information of the units launching, including bearing, range …</li>
<li>Provide alerts when a missile would have killed your aircraft.</li>
<li>Provide alerts when the missile self destructs.</li>
<li>Enable / Disable and Configure the Missile Trainer using the various menu options.</li>
</ul>
<p> When running a mission where MISSILETRAINER is used, the following radio menu structure ( 'Radio Menu' -> 'Other (F10)' -> 'MissileTrainer' ) options are available for the players:</p>
<ul>
<li><strong>Messages</strong>: Menu to configure all messages.
<ul>
<li><strong>Messages On</strong>: Show all messages.</li>
<li><strong>Messages Off</strong>: Disable all messages.</li>
</ul></li>
<li><strong>Tracking</strong>: Menu to configure missile tracking messages.
<ul>
<li><strong>To All</strong>: Shows missile tracking messages to all players.</li>
<li><strong>To Target</strong>: Shows missile tracking messages only to the player where the missile is targetted at.</li>
<li><strong>Tracking On</strong>: Show missile tracking messages.</li>
<li><strong>Tracking Off</strong>: Disable missile tracking messages.</li>
<li><strong>Frequency Increase</strong>: Increases the missile tracking message frequency with one second.</li>
<li><strong>Frequency Decrease</strong>: Decreases the missile tracking message frequency with one second.</li>
</ul></li>
<li><strong>Alerts</strong>: Menu to configure alert messages.
<ul>
<li><strong>To All</strong>: Shows alert messages to all players.</li>
<li><strong>To Target</strong>: Shows alert messages only to the player where the missile is (was) targetted at.</li>
<li><strong>Hits On</strong>: Show missile hit alert messages.</li>
<li><strong>Hits Off</strong>: Disable missile hit alert messages.</li>
<li><strong>Launches On</strong>: Show missile launch messages.</li>
<li><strong>Launches Off</strong>: Disable missile launch messages.</li>
</ul></li>
<li><strong>Details</strong>: Menu to configure message details.
<ul>
<li><strong>Range On</strong>: Shows range information when a missile is fired to a target.</li>
<li><strong>Range Off</strong>: Disable range information when a missile is fired to a target.</li>
<li><strong>Bearing On</strong>: Shows bearing information when a missile is fired to a target.</li>
<li><strong>Bearing Off</strong>: Disable bearing information when a missile is fired to a target.</li>
</ul></li>
<li><strong>Distance</strong>: Menu to configure the distance when a missile needs to be destroyed when near to a player, during tracking. This will improve/influence hit calculation accuracy, but has the risk of damaging the aircraft when the missile reaches the aircraft before the distance is measured.
<ul>
<li><strong>50 meter</strong>: Destroys the missile when the distance to the aircraft is below or equal to 50 meter.</li>
<li><strong>100 meter</strong>: Destroys the missile when the distance to the aircraft is below or equal to 100 meter.</li>
<li><strong>150 meter</strong>: Destroys the missile when the distance to the aircraft is below or equal to 150 meter.</li>
<li><strong>200 meter</strong>: Destroys the missile when the distance to the aircraft is below or equal to 200 meter.</li>
</ul></li>
</ul>
<h1>MISSILETRAINER construction methods:</h1>
<p>Create a new MISSILETRAINER object with the <a href="##(MISSILETRAINER).New">MISSILETRAINER.New</a> method:</p>
<ul>
<li><a href="##(MISSILETRAINER).New">MISSILETRAINER.New</a>: Creates a new MISSILETRAINER object taking the maximum distance to your aircraft to evaluate when a missile needs to be destroyed.</li>
</ul>
<p>MISSILETRAINER will collect each unit declared in the mission with a skill level "Client" and "Player", and will monitor the missiles shot at those.</p>
<h1>MISSILETRAINER initialization methods:</h1>
<p>A MISSILETRAINER object will behave differently based on the usage of initialization methods:</p>
<ul>
<li><a href="##(MISSILETRAINER).InitMessagesOnOff">MISSILETRAINER.InitMessagesOnOff</a>: Sets by default the display of any message to be ON or OFF.</li>
<li><a href="##(MISSILETRAINER).InitTrackingToAll">MISSILETRAINER.InitTrackingToAll</a>: Sets by default the missile tracking report for all players or only for those missiles targetted to you.</li>
<li><a href="##(MISSILETRAINER).InitTrackingOnOff">MISSILETRAINER.InitTrackingOnOff</a>: Sets by default the display of missile tracking report to be ON or OFF.</li>
<li><a href="##(MISSILETRAINER).InitTrackingFrequency">MISSILETRAINER.InitTrackingFrequency</a>: Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.</li>
<li><a href="##(MISSILETRAINER).InitAlertsToAll">MISSILETRAINER.InitAlertsToAll</a>: Sets by default the display of alerts to be shown to all players or only to you.</li>
<li><a href="##(MISSILETRAINER).InitAlertsHitsOnOff">MISSILETRAINER.InitAlertsHitsOnOff</a>: Sets by default the display of hit alerts ON or OFF.</li>
<li><a href="##(MISSILETRAINER).InitAlertsLaunchesOnOff">MISSILETRAINER.InitAlertsLaunchesOnOff</a>: Sets by default the display of launch alerts ON or OFF.</li>
<li><a href="##(MISSILETRAINER).InitRangeOnOff">MISSILETRAINER.InitRangeOnOff</a>: Sets by default the display of range information of missiles ON of OFF.</li>
<li><a href="##(MISSILETRAINER).InitBearingOnOff">MISSILETRAINER.InitBearingOnOff</a>: Sets by default the display of bearing information of missiles ON of OFF.</li>
<li><a href="##(MISSILETRAINER).InitMenusOnOff">MISSILETRAINER.InitMenusOnOff</a>: Allows to configure the options through the radio menu.</li>
</ul>
<h2>Global(s)</h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="#MISSILETRAINER">MISSILETRAINER</a></td>
<td class="summary">
</td>
</tr>
</table>
<h2><a id="#(MISSILETRAINER)">Type <code>MISSILETRAINER</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).AlertsHitsOnOff">MISSILETRAINER.AlertsHitsOnOff</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).AlertsLaunchesOnOff">MISSILETRAINER.AlertsLaunchesOnOff</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).AlertsToAll">MISSILETRAINER.AlertsToAll</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).ClassName">MISSILETRAINER.ClassName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).DetailsBearingOnOff">MISSILETRAINER.DetailsBearingOnOff</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).DetailsRangeOnOff">MISSILETRAINER.DetailsRangeOnOff</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitAlertsHitsOnOff">MISSILETRAINER:InitAlertsHitsOnOff(AlertsHitsOnOff)</a></td>
<td class="summary">
<p>Sets by default the display of hit alerts ON or OFF.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitAlertsLaunchesOnOff">MISSILETRAINER:InitAlertsLaunchesOnOff(AlertsLaunchesOnOff)</a></td>
<td class="summary">
<p>Sets by default the display of launch alerts ON or OFF.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitAlertsToAll">MISSILETRAINER:InitAlertsToAll(AlertsToAll)</a></td>
<td class="summary">
<p>Sets by default the display of alerts to be shown to all players or only to you.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitBearingOnOff">MISSILETRAINER:InitBearingOnOff(DetailsBearingOnOff)</a></td>
<td class="summary">
<p>Sets by default the display of bearing information of missiles ON of OFF.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitMenusOnOff">MISSILETRAINER:InitMenusOnOff(MenusOnOff)</a></td>
<td class="summary">
<p>Enables / Disables the menus.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitMessagesOnOff">MISSILETRAINER:InitMessagesOnOff(MessagesOnOff)</a></td>
<td class="summary">
<p>Sets by default the display of any message to be ON or OFF.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitRangeOnOff">MISSILETRAINER:InitRangeOnOff(DetailsRangeOnOff)</a></td>
<td class="summary">
<p>Sets by default the display of range information of missiles ON of OFF.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitTrackingFrequency">MISSILETRAINER:InitTrackingFrequency(TrackingFrequency)</a></td>
<td class="summary">
<p>Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitTrackingOnOff">MISSILETRAINER:InitTrackingOnOff(TrackingOnOff)</a></td>
<td class="summary">
<p>Sets by default the display of missile tracking report to be ON or OFF.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).InitTrackingToAll">MISSILETRAINER:InitTrackingToAll(TrackingToAll)</a></td>
<td class="summary">
<p>Sets by default the missile tracking report for all players or only for those missiles targetted to you.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).MenusOnOff">MISSILETRAINER.MenusOnOff</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).MessagesOnOff">MISSILETRAINER.MessagesOnOff</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).New">MISSILETRAINER:New(Distance, Briefing)</a></td>
<td class="summary">
<p>Creates the main object which is handling missile tracking.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).TrackingFrequency">MISSILETRAINER.TrackingFrequency</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).TrackingOnOff">MISSILETRAINER.TrackingOnOff</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER).TrackingToAll">MISSILETRAINER.TrackingToAll</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER)._AddBearing">MISSILETRAINER:_AddBearing(Client, TrainerWeapon)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER)._AddRange">MISSILETRAINER:_AddRange(Client, TrainerWeapon)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER)._EventShot">MISSILETRAINER:_EventShot(Event)</a></td>
<td class="summary">
<p>Detects if an SA site was shot with an anti radiation missile.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER)._MenuMessages">MISSILETRAINER._MenuMessages(MenuParameters)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(MISSILETRAINER)._TrackMissiles">MISSILETRAINER:_TrackMissiles()</a></td>
<td class="summary">
</td>
</tr>
</table>
<h2>Global(s)</h2>
<dl class="function">
<dt>
<em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a></em>
<a id="MISSILETRAINER" >
<strong>MISSILETRAINER</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<h2><a id="#(MissileTrainer)" >Type <code>MissileTrainer</code></a></h2>
<h2><a id="#(MISSILETRAINER)" >Type <code>MISSILETRAINER</code></a></h2>
<p>The MISSILETRAINER class</p>
<h3>Field(s)</h3>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).AlertsHitsOnOff" >
<strong>MISSILETRAINER.AlertsHitsOnOff</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).AlertsLaunchesOnOff" >
<strong>MISSILETRAINER.AlertsLaunchesOnOff</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).AlertsToAll" >
<strong>MISSILETRAINER.AlertsToAll</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#string</em>
<a id="#(MISSILETRAINER).ClassName" >
<strong>MISSILETRAINER.ClassName</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).DetailsBearingOnOff" >
<strong>MISSILETRAINER.DetailsBearingOnOff</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).DetailsRangeOnOff" >
<strong>MISSILETRAINER.DetailsRangeOnOff</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitAlertsHitsOnOff" >
<strong>MISSILETRAINER:InitAlertsHitsOnOff(AlertsHitsOnOff)</strong>
</a>
</dt>
<dd>
<p>Sets by default the display of hit alerts ON or OFF.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean AlertsHitsOnOff </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitAlertsLaunchesOnOff" >
<strong>MISSILETRAINER:InitAlertsLaunchesOnOff(AlertsLaunchesOnOff)</strong>
</a>
</dt>
<dd>
<p>Sets by default the display of launch alerts ON or OFF.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean AlertsLaunchesOnOff </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitAlertsToAll" >
<strong>MISSILETRAINER:InitAlertsToAll(AlertsToAll)</strong>
</a>
</dt>
<dd>
<p>Sets by default the display of alerts to be shown to all players or only to you.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean AlertsToAll </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitBearingOnOff" >
<strong>MISSILETRAINER:InitBearingOnOff(DetailsBearingOnOff)</strong>
</a>
</dt>
<dd>
<p>Sets by default the display of bearing information of missiles ON of OFF.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean DetailsBearingOnOff </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitMenusOnOff" >
<strong>MISSILETRAINER:InitMenusOnOff(MenusOnOff)</strong>
</a>
</dt>
<dd>
<p>Enables / Disables the menus.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean MenusOnOff </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitMessagesOnOff" >
<strong>MISSILETRAINER:InitMessagesOnOff(MessagesOnOff)</strong>
</a>
</dt>
<dd>
<p>Sets by default the display of any message to be ON or OFF.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean MessagesOnOff </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitRangeOnOff" >
<strong>MISSILETRAINER:InitRangeOnOff(DetailsRangeOnOff)</strong>
</a>
</dt>
<dd>
<p>Sets by default the display of range information of missiles ON of OFF.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean DetailsRangeOnOff </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitTrackingFrequency" >
<strong>MISSILETRAINER:InitTrackingFrequency(TrackingFrequency)</strong>
</a>
</dt>
<dd>
<p>Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.</p>
<p>The default frequency is a 3 second interval, so the Tracking Frequency parameter specifies the increase or decrease from the default 3 seconds or the last frequency update.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#number TrackingFrequency </em></code>:
Provide a negative or positive value in seconds to incraese or decrease the display frequency. </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitTrackingOnOff" >
<strong>MISSILETRAINER:InitTrackingOnOff(TrackingOnOff)</strong>
</a>
</dt>
<dd>
<p>Sets by default the display of missile tracking report to be ON or OFF.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean TrackingOnOff </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).InitTrackingToAll" >
<strong>MISSILETRAINER:InitTrackingToAll(TrackingToAll)</strong>
</a>
</dt>
<dd>
<p>Sets by default the missile tracking report for all players or only for those missiles targetted to you.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em>#boolean TrackingToAll </em></code>:
true or false</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).MenusOnOff" >
<strong>MISSILETRAINER.MenusOnOff</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).MessagesOnOff" >
<strong>MISSILETRAINER.MessagesOnOff</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).New" >
<strong>MISSILETRAINER:New(Distance, Briefing)</strong>
</a>
</dt>
<dd>
<p>Creates the main object which is handling missile tracking.</p>
<p>When a missile is fired a SCHEDULER is set off that follows the missile. When near a certain a client player, the missile will be destroyed.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#number Distance </em></code>:
The distance in meters when a tracked missile needs to be destroyed when close to a player.</p>
</li>
<li>
<p><code><em>#string Briefing </em></code>:
(Optional) Will show a text to the players when starting their mission. Can be used for briefing purposes. </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(MISSILETRAINER)">#MISSILETRAINER</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER).TrackingFrequency" >
<strong>MISSILETRAINER.TrackingFrequency</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).TrackingOnOff" >
<strong>MISSILETRAINER.TrackingOnOff</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(MISSILETRAINER).TrackingToAll" >
<strong>MISSILETRAINER.TrackingToAll</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER)._AddBearing" >
<strong>MISSILETRAINER:_AddBearing(Client, TrainerWeapon)</strong>
</a>
</dt>
<dd>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> Client </em></code>: </p>
</li>
<li>
<p><code><em> TrainerWeapon </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER)._AddRange" >
<strong>MISSILETRAINER:_AddRange(Client, TrainerWeapon)</strong>
</a>
</dt>
<dd>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> Client </em></code>: </p>
</li>
<li>
<p><code><em> TrainerWeapon </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER)._EventShot" >
<strong>MISSILETRAINER:_EventShot(Event)</strong>
</a>
</dt>
<dd>
<p>Detects if an SA site was shot with an anti radiation missile.</p>
<p>In this case, take evasive actions based on the skill level set within the ME.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Event.html##(EVENTDATA)">Event#EVENTDATA</a> Event </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER)._MenuMessages" >
<strong>MISSILETRAINER._MenuMessages(MenuParameters)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> MenuParameters </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(MISSILETRAINER)._TrackMissiles" >
<strong>MISSILETRAINER:_TrackMissiles()</strong>
</a>
</dt>
<dd>
</dd>
</dl>
</div>
</div>
</body>
</html>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li>NOTASK</li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li>PICKUPTASK</li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li>ROUTETASK</li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li>STAGE</li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -0,0 +1,252 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div>
<div id="main">
<div id="navigation">
<h2>Modules</h2>
<ul><li>
<a href="index.html">index</a>
</li></ul>
<ul>
<li><a href="Base.html">Base</a></li>
<li><a href="CARGO.html">CARGO</a></li>
<li><a href="CleanUp.html">CleanUp</a></li>
<li><a href="Client.html">Client</a></li>
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
<li><a href="DCSCommand.html">DCSCommand</a></li>
<li><a href="DCSController.html">DCSController</a></li>
<li><a href="DCSGroup.html">DCSGroup</a></li>
<li><a href="DCSObject.html">DCSObject</a></li>
<li><a href="DCSTask.html">DCSTask</a></li>
<li><a href="DCSTypes.html">DCSTypes</a></li>
<li><a href="DCSUnit.html">DCSUnit</a></li>
<li><a href="DCSWorld.html">DCSWorld</a></li>
<li><a href="DCStimer.html">DCStimer</a></li>
<li><a href="DEPLOYTASK.html">DEPLOYTASK</a></li>
<li><a href="DESTROYBASETASK.html">DESTROYBASETASK</a></li>
<li><a href="DESTROYGROUPSTASK.html">DESTROYGROUPSTASK</a></li>
<li><a href="DESTROYRADARSTASK.html">DESTROYRADARSTASK</a></li>
<li><a href="DESTROYUNITTYPESTASK.html">DESTROYUNITTYPESTASK</a></li>
<li><a href="Database.html">Database</a></li>
<li><a href="Escort.html">Escort</a></li>
<li><a href="Event.html">Event</a></li>
<li><a href="GOHOMETASK.html">GOHOMETASK</a></li>
<li><a href="Group.html">Group</a></li>
<li><a href="MISSION.html">MISSION</a></li>
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li>Scheduler</li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
<li><a href="Unit.html">Unit</a></li>
<li><a href="Zone.html">Zone</a></li>
<li><a href="env.html">env</a></li>
<li><a href="land.html">land</a></li>
<li><a href="routines.html">routines</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>Scheduler</code></h1>
<p>Models time events calling event handing functions.</p>
<h2>Global(s)</h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="#SCHEDULER">SCHEDULER</a></td>
<td class="summary">
</td>
</tr>
</table>
<h2><a id="#(SCHEDULER)">Type <code>SCHEDULER</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(SCHEDULER).ClassName">SCHEDULER.ClassName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SCHEDULER).New">SCHEDULER:New(TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds)</a></td>
<td class="summary">
<p>SCHEDULER constructor.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SCHEDULER).Scheduler">SCHEDULER:Scheduler()</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SCHEDULER).Start">SCHEDULER:Start()</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SCHEDULER).Stop">SCHEDULER:Stop()</a></td>
<td class="summary">
</td>
</tr>
</table>
<h2>Global(s)</h2>
<dl class="function">
<dt>
<em><a href="##(SCHEDULER)">#SCHEDULER</a></em>
<a id="SCHEDULER" >
<strong>SCHEDULER</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<h2><a id="#(Scheduler)" >Type <code>Scheduler</code></a></h2>
<h2><a id="#(SCHEDULER)" >Type <code>SCHEDULER</code></a></h2>
<p>The SCHEDULER class</p>
<h3>Field(s)</h3>
<dl class="function">
<dt>
<em>#string</em>
<a id="#(SCHEDULER).ClassName" >
<strong>SCHEDULER.ClassName</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SCHEDULER).New" >
<strong>SCHEDULER:New(TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds)</strong>
</a>
</dt>
<dd>
<p>SCHEDULER constructor.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#table TimeEventObject </em></code>: </p>
</li>
<li>
<p><code><em>#function TimeEventFunction </em></code>: </p>
</li>
<li>
<p><code><em>#table TimeEventFunctionArguments </em></code>: </p>
</li>
<li>
<p><code><em>#number StartSeconds </em></code>: </p>
</li>
<li>
<p><code><em>#number RepeatSecondsInterval </em></code>: </p>
</li>
<li>
<p><code><em>#number RandomizationFactor </em></code>: </p>
</li>
<li>
<p><code><em>#number StopSeconds </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(SCHEDULER)">#SCHEDULER</a>:</em></p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SCHEDULER).Scheduler" >
<strong>SCHEDULER:Scheduler()</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SCHEDULER).Start" >
<strong>SCHEDULER:Start()</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SCHEDULER).Stop" >
<strong>SCHEDULER:Stop()</strong>
</a>
</dt>
<dd>
</dd>
</dl>
</div>
</div>
</body>
</html>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li>Scoring</li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li>Sead</li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

1332
Documentation/Set.html Normal file

File diff suppressed because it is too large Load Diff

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li>Spawn</li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -116,7 +119,7 @@ So in principle, the group list will contain all parameters and configurations a
<li><a href="##(SPAWN).RandomizeTemplate">SPAWN.RandomizeTemplate</a>: Randomize the group templates so that when a new group is spawned, a random group template is selected from one of the templates defined. </li>
<li><a href="##(SPAWN).Uncontrolled">SPAWN.Uncontrolled</a>: Spawn plane groups uncontrolled.</li>
<li><a href="##(SPAWN).Array">SPAWN.Array</a>: Make groups visible before they are actually activated, and order these groups like a batallion in an array.</li>
<li><a href="##(SPAWN).Repeat">SPAWN.Repeat</a>: Re-spawn groups when they land at the home base. Similar functions are <a href="##(SPAWN).RepeatOnLanding">SPAWN.RepeatOnLanding</a> and <a href="##(SPAWN).RepeatOnEngineShutDown">SPAWN.RepeatOnEngineShutDown</a>.</li>
<li><a href="##(SPAWN).InitRepeat">SPAWN.InitRepeat</a>: Re-spawn groups when they land at the home base. Similar functions are <a href="##(SPAWN).InitRepeatOnLanding">SPAWN.InitRepeatOnLanding</a> and <a href="##(SPAWN).InitRepeatOnEngineShutDown">SPAWN.InitRepeatOnEngineShutDown</a>.</li>
</ul>
<h1>SPAWN spawning methods:</h1>
@ -158,12 +161,6 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
<h2><a id="#(SPAWN)">Type <code>SPAWN</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).AliveFactor">SPAWN.AliveFactor</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).Array">SPAWN:Array(SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY)</a></td>
<td class="summary">
<p>Makes the groups visible before start (like a batallion).</p>
@ -182,7 +179,7 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).CleanUpFunction">SPAWN.CleanUpFunction</a></td>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).CleanUpScheduler">SPAWN.CleanUpScheduler</a></td>
<td class="summary">
</td>
@ -215,6 +212,24 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).GetSpawnIndexFromGroup">SPAWN:GetSpawnIndexFromGroup(SpawnGroup)</a></td>
<td class="summary">
<p>Get the index from a given group.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).InitRepeat">SPAWN:InitRepeat()</a></td>
<td class="summary">
<p>For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).InitRepeatOnEngineShutDown">SPAWN:InitRepeatOnEngineShutDown()</a></td>
<td class="summary">
<p>Respawn after landing when its engines have shut down.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).InitRepeatOnLanding">SPAWN:InitRepeatOnLanding()</a></td>
<td class="summary">
<p>Respawn group after landing.</p>
</td>
</tr>
<tr>
@ -254,9 +269,9 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).Repeat">SPAWN:Repeat()</a></td>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).Repeat">SPAWN.Repeat</a></td>
<td class="summary">
<p>For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.</p>
</td>
</tr>
<tr>
@ -293,12 +308,6 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnCleanUpTimeStamps">SPAWN.SpawnCleanUpTimeStamps</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnCurrentTimer">SPAWN.SpawnCurrentTimer</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -329,24 +338,12 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnGroupName">SPAWN:SpawnGroupName(SpawnIndex)</a></td>
<td class="summary">
<p>Will return the SpawnGroupName either with with a specific count number or without any count.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnHighTimer">SPAWN.SpawnHighTimer</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnInZone">SPAWN:SpawnInZone(Zone, ZoneRandomize, SpawnIndex)</a></td>
<td class="summary">
<p>Will spawn a Group within a given <a href="Zone.html##(ZONE)">Zone#ZONE</a>.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnLowTimer">SPAWN.SpawnLowTimer</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -389,18 +386,12 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnRandomizeTemplate">SPAWN.SpawnRandomizeTemplate</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnRepeat">SPAWN.SpawnRepeat</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnScheduleStart">SPAWN:SpawnScheduleStart()</a></td>
<td class="summary">
<p>Will start the spawning scheduler.</p>
<p>Will re-start the spawning scheduler.</p>
</td>
</tr>
<tr>
@ -416,7 +407,7 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnSetTimer">SPAWN.SpawnSetTimer</a></td>
<td class="name" nowrap="nowrap"><a href="##(SPAWN).SpawnScheduler">SPAWN.SpawnScheduler</a></td>
<td class="summary">
</td>
@ -550,13 +541,13 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN)._RandomizeRoute">SPAWN:_RandomizeRoute(SpawnIndex)</a></td>
<td class="summary">
<p>Internal function randomizing the routes.</p>
<p>Private method randomizing the routes.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN)._RandomizeTemplate">SPAWN:_RandomizeTemplate(SpawnIndex)</a></td>
<td class="summary">
<p>Private method that randomizes the template of the group.</p>
</td>
</tr>
<tr>
@ -604,20 +595,6 @@ Check the <a href="##(SPAWN).CleanUp">SPAWN.CleanUp</a> for further info.</p>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(SPAWN).AliveFactor" >
<strong>SPAWN.AliveFactor</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SPAWN).Array" >
<strong>SPAWN:Array(SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY)</strong>
</a>
@ -721,14 +698,17 @@ self</p>
<dt>
<em></em>
<a id="#(SPAWN).CleanUpFunction" >
<strong>SPAWN.CleanUpFunction</strong>
<a id="#(SPAWN).CleanUpScheduler" >
<strong>SPAWN.CleanUpScheduler</strong>
</a>
</dt>
<dd>
<p>self.CleanUpFunction = routines.scheduleFunction( self._SpawnCleanUpScheduler, { self }, timer.getTime() + 1, SpawnCleanUpInterval )</p>
</dd>
</dl>
<dl class="function">
@ -876,6 +856,71 @@ When no group is found, #nil is returned.</p>
<dl class="function">
<dt>
<a id="#(SPAWN).InitRepeat" >
<strong>SPAWN:InitRepeat()</strong>
</a>
</dt>
<dd>
<p>For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.</p>
<p>This function is used to re-spawn automatically (so no extra call is needed anymore) the same group after it has landed.
This will enable a spawned group to be re-spawned after it lands, until it is destroyed...
Note: When the group is respawned, it will re-spawn from the original airbase where it took off.
So ensure that the routes for groups that respawn, always return to the original airbase, or players may get confused ...</p>
<h3>Return value</h3>
<p><em><a href="##(SPAWN)">#SPAWN</a>:</em>
self</p>
<h3>Usage:</h3>
<pre class="example"><code>-- RU Su-34 - AI Ship Attack
-- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()</code></pre>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SPAWN).InitRepeatOnEngineShutDown" >
<strong>SPAWN:InitRepeatOnEngineShutDown()</strong>
</a>
</dt>
<dd>
<p>Respawn after landing when its engines have shut down.</p>
<h3>Return value</h3>
<p><em><a href="##(SPAWN)">#SPAWN</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SPAWN).InitRepeatOnLanding" >
<strong>SPAWN:InitRepeatOnLanding()</strong>
</a>
</dt>
<dd>
<p>Respawn group after landing.</p>
<h3>Return value</h3>
<p><em><a href="##(SPAWN)">#SPAWN</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(SPAWN).Limit" >
<strong>SPAWN:Limit(SpawnMaxUnitsAlive, SpawnMaxGroups)</strong>
</a>
@ -1123,29 +1168,14 @@ The group that was spawned. You can use this group for further actions.</p>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(SPAWN).Repeat" >
<strong>SPAWN:Repeat()</strong>
<strong>SPAWN.Repeat</strong>
</a>
</dt>
<dd>
<p>For planes and helicopters, when these groups go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the runtime environment.</p>
<p>This function is used to re-spawn automatically (so no extra call is needed anymore) the same group after it has landed.
This will enable a spawned group to be re-spawned after it lands, until it is destroyed...
Note: When the group is respawned, it will re-spawn from the original airbase where it took off.
So ensure that the routes for groups that respawn, always return to the original airbase, or players may get confused ...</p>
<h3>Return value</h3>
<p><em><a href="##(SPAWN)">#SPAWN</a>:</em>
self</p>
<h3>Usage:</h3>
<pre class="example"><code>-- RU Su-34 - AI Ship Attack
-- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()</code></pre>
</dd>
</dl>
@ -1238,23 +1268,6 @@ The group that was spawned. You can use this group for further actions.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(SPAWN).SpawnCurrentTimer" >
<strong>SPAWN.SpawnCurrentTimer</strong>
</a>
</dt>
<dd>
<p> The internal timer counter to trigger a scheduled spawning of SpawnTemplatePrefix.</p>
</dd>
</dl>
<dl class="function">
@ -1412,20 +1425,6 @@ Is the number of the Group that is to be spawned.</p>
<p><em>#string:</em>
SpawnGroupName</p>
</dd>
</dl>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(SPAWN).SpawnHighTimer" >
<strong>SPAWN.SpawnHighTimer</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -1479,20 +1478,6 @@ when nothing was spawned.</p>
</li>
</ol>
</dd>
</dl>
<dl class="function">
<dt>
<em>#number</em>
<a id="#(SPAWN).SpawnLowTimer" >
<strong>SPAWN.SpawnLowTimer</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -1597,20 +1582,6 @@ when nothing was spawned.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(SPAWN).SpawnRepeat" >
<strong>SPAWN.SpawnRepeat</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
@ -1622,10 +1593,10 @@ when nothing was spawned.</p>
</dt>
<dd>
<p>Will start the spawning scheduler.</p>
<p>Will re-start the spawning scheduler.</p>
<p>Note: This function is called automatically when <a href="##(SPAWN).Scheduled">SPAWN.Scheduled</a> is called.</p>
<p>Note: This function is only required to be called when the schedule was stopped.</p>
</dd>
</dl>
@ -1692,18 +1663,15 @@ Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
<dl class="function">
<dt>
<em>#number</em>
<a id="#(SPAWN).SpawnSetTimer" >
<strong>SPAWN.SpawnSetTimer</strong>
<em></em>
<a id="#(SPAWN).SpawnScheduler" >
<strong>SPAWN.SpawnScheduler</strong>
</a>
</dt>
<dd>
<p> The internal timer value when a scheduled spawning of SpawnTemplatePrefix occurs.</p>
</dd>
</dl>
<dl class="function">
@ -2022,10 +1990,15 @@ Nothing found</p>
<ul>
<li>
<p><code><em> SpawnTemplatePrefix </em></code>: </p>
<p><code><em>#string SpawnTemplatePrefix </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p>@SPAWN self</p>
</dd>
</dl>
<dl class="function">
@ -2184,15 +2157,20 @@ This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.</p
<ul>
<li>
<p><code><em> SpawnTemplatePrefix </em></code>: </p>
<p><code><em>#string SpawnTemplatePrefix </em></code>: </p>
</li>
<li>
<p><code><em> SpawnIndex </em></code>: </p>
<p><code><em>#number SpawnIndex </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(SPAWN)">#SPAWN</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
@ -2204,7 +2182,7 @@ This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.</p
</dt>
<dd>
<p>Internal function randomizing the routes.</p>
<p>Private method randomizing the routes.</p>
<h3>Parameter</h3>
<ul>
@ -2231,16 +2209,21 @@ The index of the group to be spawned.</p>
</dt>
<dd>
<p>Private method that randomizes the template of the group.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> SpawnIndex </em></code>: </p>
<p><code><em>#number SpawnIndex </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(SPAWN)">#SPAWN</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li>StaticObject</li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li>TASK</li>

File diff suppressed because it is too large Load Diff

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -88,6 +91,12 @@
<td class="name" nowrap="nowrap"><a href="##(ZONE).GetPointVec2">ZONE:GetPointVec2()</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(ZONE).GetPointVec3">ZONE:GetPointVec3(Height)</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -157,6 +166,27 @@
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(ZONE).GetPointVec3" >
<strong>ZONE:GetPointVec3(Height)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> Height </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>
@ -212,7 +215,7 @@
<tr>
<td class="name" nowrap="nowrap"><a href="Group.html">Group</a></td>
<td class="summary">
<p>A GROUP class abstraction of a DCSGroup class.</p>
<p>GROUP class.</p>
</td>
</tr>
<tr>
@ -237,6 +240,12 @@
<td class="name" nowrap="nowrap"><a href="Message.html">Message</a></td>
<td class="summary">
<p>Message System to display Messages for Clients and Coalitions or All.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="MissileTrainer.html">MissileTrainer</a></td>
<td class="summary">
<p>Provides missile training functions.</p>
</td>
</tr>
<tr>
@ -261,6 +270,12 @@
<td class="name" nowrap="nowrap"><a href="STAGE.html">STAGE</a></td>
<td class="summary">
<p>Stages within a <a href="TASK.html">TASK</a> within a <a href="MISSION.html">MISSION</a>.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="Scheduler.html">Scheduler</a></td>
<td class="summary">
<p>Models time events calling event handing functions.</p>
</td>
</tr>
<tr>
@ -273,6 +288,12 @@
<td class="name" nowrap="nowrap"><a href="Sead.html">Sead</a></td>
<td class="summary">
<p>Provides defensive behaviour to a set of SAM sites within a running Mission.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="Set.html">Set</a></td>
<td class="summary">
<p>Manage sets of units and groups.</p>
</td>
</tr>
<tr>
@ -296,7 +317,14 @@
<tr>
<td class="name" nowrap="nowrap"><a href="Unit.html">Unit</a></td>
<td class="summary">
<p>UNIT Classes</p>
<p>UNIT Class</p>
<h1><a href="UNIT.html">UNIT</a> class</h1>
<p>The <a href="UNIT.html">UNIT</a> class is a wrapper class to handle the DCS Unit objects:</p>
<ul>
<li>Support all DCS Unit APIs.</li>
</ul>
</td>
</tr>
<tr>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -46,12 +46,15 @@
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="NOTASK.html">NOTASK</a></li>
<li><a href="PICKUPTASK.html">PICKUPTASK</a></li>
<li><a href="ROUTETASK.html">ROUTETASK</a></li>
<li><a href="STAGE.html">STAGE</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<li><a href="Scoring.html">Scoring</a></li>
<li><a href="Sead.html">Sead</a></li>
<li><a href="Set.html">Set</a></li>
<li><a href="Spawn.html">Spawn</a></li>
<li><a href="StaticObject.html">StaticObject</a></li>
<li><a href="TASK.html">TASK</a></li>

View File

@ -5,13 +5,16 @@ echo env.info( 'Moose Embedded' ) > Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Routines.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Base.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Event.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Menu.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Group.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Unit.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Zone.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Client.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Database.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Moose.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Scheduler.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Scoring.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Cargo.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Client.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Message.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Stage.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Task.lua Moose_Embedded.lua
@ -30,3 +33,4 @@ copy /b Moose_Embedded.lua + ..\Moose\Spawn.lua Moose_Embedded.l
copy /b Moose_Embedded.lua + ..\Moose\Movement.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Sead.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\Escort.lua Moose_Embedded.lua
copy /b Moose_Embedded.lua + ..\Moose\MissileTrainer.lua Moose_Embedded.lua

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,31 +0,0 @@
rem Generate Moose_Embedded.lua
copy Trace.lua ^
+ Routines.lua ^
+ Base.lua ^
+ Menu.lua ^
+ Group.lua ^
+ Unit.lua ^
+ Zone.lua ^
+ Database.lua ^
+ Cargo.lua ^
+ Client.lua ^
+ Message.lua ^
+ Stage.lua ^
+ Task.lua ^
+ GoHomeTask.lua ^
+ DestroyBaseTask.lua ^
+ DestroyGroupsTask.lua ^
+ DestroyRadarsTask.lua ^
+ DestroyUnitTypesTask.lua ^
+ PickupTask.lua ^
+ DeployTask.lua ^
+ NoTask.lua ^
+ RouteTask.lua ^
+ Mission.lua ^
+ CleanUp.lua ^
+ Spawn.lua ^
+ Movement.lua ^
+ Sead.lua ^
Moose_Embedded.lua

View File

@ -1,4 +1,3 @@
local base = _G
env.info("Loading MOOSE " .. base.timer.getAbsTime() )

Binary file not shown.

View File

@ -353,6 +353,7 @@ end
-- @param #number Level
function BASE:TraceLevel( Level )
_TraceLevel = Level
self:E( "Tracing level " .. Level )
end
--- Set tracing for a class
@ -361,6 +362,7 @@ end
function BASE:TraceClass( Class )
_TraceClass[Class] = true
_TraceClassMethod[Class] = {}
self:E( "Tracing class " .. Class )
end
--- Set tracing for a specific method of class
@ -373,6 +375,7 @@ function BASE:TraceClassMethod( Class, Method )
_TraceClassMethod[Class].Method = {}
end
_TraceClassMethod[Class].Method[Method] = true
self:E( "Tracing method " .. Method .. " of class " .. Class )
end
--- Trace a function call. Must be at the beginning of the function logic.

View File

@ -31,18 +31,31 @@ CARGO_ZONE = {
}
}
function CARGO_ZONE:New( CargoZoneName, CargoHostName ) local self = BASE:Inherit( self, BASE:New() )
--- Creates a new zone where cargo can be collected or deployed.
-- The zone functionality is useful to smoke or indicate routes for cargo pickups or deployments.
-- Provide the zone name as declared in the mission file into the CargoZoneName in the :New method.
-- An optional parameter is the CargoHostName, which is a Group declared with Late Activation switched on in the mission file.
-- The CargoHostName is the "host" of the cargo zone:
--
-- * It will smoke the zone position when a client is approaching the zone.
-- * Depending on the cargo type, it will assist in the delivery of the cargo by driving to and from the client.
--
-- @param #CARGO_ZONE self
-- @param #string CargoZoneName The name of the zone as declared within the mission editor.
-- @param #string CargoHostName The name of the Group "hosting" the zone. The Group MUST NOT be a static, and must be a "mobile" unit.
function CARGO_ZONE:New( CargoZoneName, CargoHostName ) local self = BASE:Inherit( self, ZONE:New( CargoZoneName ) )
self:F( { CargoZoneName, CargoHostName } )
self.CargoZoneName = CargoZoneName
self.CargoZone = trigger.misc.getZone( CargoZoneName )
self.SignalHeight = 2
--self.CargoZone = trigger.misc.getZone( CargoZoneName )
if CargoHostName then
self.CargoHostName = CargoHostName
end
self:T( self.CargoZone )
self:T( self.CargoZoneName )
return self
end
@ -50,17 +63,19 @@ end
function CARGO_ZONE:Spawn()
self:F( self.CargoHostName )
if self.CargoHostSpawn then
local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex()
if CargoHostGroup and CargoHostGroup:IsAlive() then
else
self.CargoHostSpawn:ReSpawn( 1 )
end
else
self:T( "Initialize CargoHostSpawn" )
self.CargoHostSpawn = SPAWN:New( self.CargoHostName ):Limit( 1, 1 )
self.CargoHostSpawn:ReSpawn( 1 )
end
if self.CargoHostName then -- Only spawn a host in the zone when there is one given as a parameter in the New function.
if self.CargoHostSpawn then
local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex()
if CargoHostGroup and CargoHostGroup:IsAlive() then
else
self.CargoHostSpawn:ReSpawn( 1 )
end
else
self:T( "Initialize CargoHostSpawn" )
self.CargoHostSpawn = SPAWN:New( self.CargoHostName ):Limit( 1, 1 )
self.CargoHostSpawn:ReSpawn( 1 )
end
end
return self
end
@ -114,6 +129,7 @@ function CARGO_ZONE:ReportCargosToClient( Client, CargoType )
end
end
function CARGO_ZONE:Signal()
self:F()
@ -130,7 +146,7 @@ function CARGO_ZONE:Signal()
if SignalUnit then
self:T( 'Signalling Unit' )
local SignalVehiclePos = SignalUnit:GetPositionVec3()
local SignalVehiclePos = SignalUnit:GetPointVec3()
SignalVehiclePos.y = SignalVehiclePos.y + 2
if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then
@ -148,16 +164,15 @@ function CARGO_ZONE:Signal()
else
local CurrentPosition = { x = self.CargoZone.point.x, y = self.CargoZone.point.z }
self.CargoZone.point.y = land.getHeight( CurrentPosition ) + 2
local ZonePointVec3 = self:GetPointVec3( self.SignalHeight ) -- Get the zone position + the landheight + 2 meters
if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then
trigger.action.smoke( self.CargoZone.point, self.SignalColor.TRIGGERCOLOR )
trigger.action.smoke( ZonePointVec3, self.SignalColor.TRIGGERCOLOR )
Signalled = true
elseif self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.FLARE.ID then
trigger.action.signalFlare( self.CargoZone.point, self.SignalColor.TRIGGERCOLOR, 0 )
trigger.action.signalFlare( ZonePointVec3, self.SignalColor.TRIGGERCOLOR, 0 )
Signalled = false
end
@ -168,85 +183,121 @@ function CARGO_ZONE:Signal()
end
function CARGO_ZONE:WhiteSmoke()
function CARGO_ZONE:WhiteSmoke( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:BlueSmoke()
function CARGO_ZONE:BlueSmoke( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.BLUE
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:RedSmoke()
function CARGO_ZONE:RedSmoke( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:OrangeSmoke()
function CARGO_ZONE:OrangeSmoke( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.ORANGE
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:GreenSmoke()
function CARGO_ZONE:GreenSmoke( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.SMOKE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:WhiteFlare()
function CARGO_ZONE:WhiteFlare( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.WHITE
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:RedFlare()
function CARGO_ZONE:RedFlare( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.RED
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:GreenFlare()
function CARGO_ZONE:GreenFlare( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.GREEN
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
function CARGO_ZONE:YellowFlare()
function CARGO_ZONE:YellowFlare( SignalHeight )
self:F()
self.SignalType = CARGO_ZONE.SIGNAL.TYPE.FLARE
self.SignalColor = CARGO_ZONE.SIGNAL.COLOR.YELLOW
if SignalHeight then
self.SignalHeight = SignalHeight
end
return self
end
@ -517,6 +568,7 @@ function CARGO_GROUP:Spawn( Client )
self.CargoGroupName = self.CargoSpawn:SpawnFromUnit( self.CargoZone:GetCargoHostUnit(), 60, 30, 1 ):GetName()
else
--- ReSpawn the Cargo in the CargoZone without a host ...
self:T( self.CargoZone )
self.CargoGroupName = self.CargoSpawn:SpawnInZone( self.CargoZone, true, 1 ):GetName()
end
self:StatusNone()
@ -534,7 +586,7 @@ function CARGO_GROUP:IsNear( Client, LandingZone )
if self.CargoGroupName then
local CargoGroup = Group.getByName( self.CargoGroupName )
if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 250 ) then
if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 250 ) then
Near = true
end
end
@ -557,64 +609,72 @@ function CARGO_GROUP:OnBoard( Client, LandingZone, OnBoardSide )
local CargoGroup = Group.getByName( self.CargoGroupName )
local CargoUnits = CargoGroup:getUnits()
local CargoPos = CargoUnits[1]:getPoint()
local CargoUnit = CargoGroup:getUnit(1)
local CargoPos = CargoUnit:getPoint()
self.CargoInAir = CargoUnit:inAir()
self:T( self.CargoInAir )
-- Only move the group to the carrier when the cargo is not in the air
-- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea).
if not self.CargoInAir then
local Points = {}
self:T( 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z )
self:T( 'CarrierPosMove x = ' .. CarrierPosMove.x .. " z = " .. CarrierPosMove.z )
Points[#Points+1] = routines.ground.buildWP( CargoPos, "Cone", 10 )
self:T( 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y )
if OnBoardSide == nil then
OnBoardSide = CLIENT.ONBOARDSIDE.NONE
end
if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then
self:T( "TransportCargoOnBoard: Onboarding LEFT" )
CarrierPosMove.z = CarrierPosMove.z - 25
CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then
self:T( "TransportCargoOnBoard: Onboarding RIGHT" )
CarrierPosMove.z = CarrierPosMove.z + 25
CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then
self:T( "TransportCargoOnBoard: Onboarding BACK" )
CarrierPosMove.x = CarrierPosMove.x - 25
CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then
self:T( "TransportCargoOnBoard: Onboarding FRONT" )
CarrierPosMove.x = CarrierPosMove.x + 25
CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then
self:T( "TransportCargoOnBoard: Onboarding CENTRAL" )
Points[#Points+1] = routines.ground.buildWP( CarrierPos, "Cone", 10 )
end
self:T( "TransportCargoOnBoard: Routing " .. self.CargoGroupName )
routines.scheduleFunction( routines.goRoute, { self.CargoGroupName, Points}, timer.getTime() + 4 )
local Points = {}
self:T( 'CargoPos x = ' .. CargoPos.x .. " z = " .. CargoPos.z )
self:T( 'CarrierPosMove x = ' .. CarrierPosMove.x .. " z = " .. CarrierPosMove.z )
Points[#Points+1] = routines.ground.buildWP( CargoPos, "Cone", 10 )
self:T( 'Points[1] x = ' .. Points[1].x .. " y = " .. Points[1].y )
if OnBoardSide == nil then
OnBoardSide = CLIENT.ONBOARDSIDE.NONE
end
if OnBoardSide == CLIENT.ONBOARDSIDE.LEFT then
self:T( "TransportCargoOnBoard: Onboarding LEFT" )
CarrierPosMove.z = CarrierPosMove.z - 25
CarrierPosOnBoard.z = CarrierPosOnBoard.z - 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.RIGHT then
self:T( "TransportCargoOnBoard: Onboarding RIGHT" )
CarrierPosMove.z = CarrierPosMove.z + 25
CarrierPosOnBoard.z = CarrierPosOnBoard.z + 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.BACK then
self:T( "TransportCargoOnBoard: Onboarding BACK" )
CarrierPosMove.x = CarrierPosMove.x - 25
CarrierPosOnBoard.x = CarrierPosOnBoard.x - 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.FRONT then
self:T( "TransportCargoOnBoard: Onboarding FRONT" )
CarrierPosMove.x = CarrierPosMove.x + 25
CarrierPosOnBoard.x = CarrierPosOnBoard.x + 5
Points[#Points+1] = routines.ground.buildWP( CarrierPosMove, "Cone", 10 )
Points[#Points+1] = routines.ground.buildWP( CarrierPosOnBoard, "Cone", 10 )
elseif OnBoardSide == CLIENT.ONBOARDSIDE.NONE then
self:T( "TransportCargoOnBoard: Onboarding CENTRAL" )
Points[#Points+1] = routines.ground.buildWP( CarrierPos, "Cone", 10 )
end
self:T( "TransportCargoOnBoard: Routing " .. self.CargoGroupName )
routines.scheduleFunction( routines.goRoute, { self.CargoGroupName, Points}, timer.getTime() + 4 )
end
self:StatusLoading( Client )
@ -628,12 +688,19 @@ function CARGO_GROUP:OnBoarded( Client, LandingZone )
local OnBoarded = false
local CargoGroup = Group.getByName( self.CargoGroupName )
if routines.IsPartOfGroupInRadius( CargoGroup, Client:ClientPosition(), 25 ) then
CargoGroup:destroy()
self:StatusLoaded( Client )
OnBoarded = true
end
local CargoGroup = Group.getByName( self.CargoGroupName )
if not self.CargoInAir then
if routines.IsPartOfGroupInRadius( CargoGroup, Client:GetPositionVec3(), 25 ) then
CargoGroup:destroy()
self:StatusLoaded( Client )
OnBoarded = true
end
else
CargoGroup:destroy()
self:StatusLoaded( Client )
OnBoarded = true
end
return OnBoarded
end
@ -723,7 +790,7 @@ function CARGO_PACKAGE:IsNear( Client, LandingZone )
self:T( self.CargoClient.ClientName )
self:T( 'Client Exists.' )
if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), Client:ClientPosition(), 150 ) then
if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), Client:GetPositionVec3(), 150 ) then
Near = true
end
end
@ -830,7 +897,7 @@ function CARGO_PACKAGE:OnBoarded( Client, LandingZone )
local OnBoarded = false
if self.CargoClient and self.CargoClient:GetDCSGroup() then
if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), self.CargoClient:ClientPosition(), 10 ) then
if routines.IsUnitInRadius( self.CargoClient:GetClientGroupDCSUnit(), self.CargoClient:GetPositionVec3(), 10 ) then
-- Switch Cargo from self.CargoClient to Client ... Each cargo can have only one client. So assigning the new client for the cargo is enough.
self:StatusLoaded( Client )

View File

@ -1,6 +1,39 @@
--- The CLIENT models client units in multi player missions.
-- Clients are those groups defined within the Mission Editor that have the skillset defined as "Client" or "Player".
-- Note that clients are NOT the same as groups, they are NOT necessarily alive.
--
-- @{#CLIENT} class
-- ================
-- Clients are those **Units** defined within the Mission Editor that have the skillset defined as __Client__ or __Player__.
-- Note that clients are NOT the same as Units, they are NOT necessarily alive.
-- The @{CLIENT} class is a wrapper class to handle the DCS Unit objects that have the skillset defined as __Client__ or __Player__:
--
-- * Wraps the DCS Unit objects with skill level set to Player or Client.
-- * Support all DCS Unit APIs.
-- * Enhance with Unit specific APIs not in the DCS Group API set.
-- * When player joins Unit, execute alive init logic.
-- * Handles messages to players.
-- * Manage the "state" of the DCS Unit.
--
-- Clients are being used by the @{MISSION} class to follow players and register their successes.
--
-- CLIENT reference methods
-- =======================
-- For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _@{DATABASE} object.
-- This is done at the beginning of the mission (when the mission starts).
--
-- The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference
-- using the DCS Unit or the DCS UnitName.
--
-- Another thing to know is that CLIENT objects do not "contain" the DCS Unit object.
-- The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution.
-- If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file.
--
-- The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance:
--
-- * @{#CLIENT.Find}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object.
-- * @{#CLIENT.FindByName}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name.
--
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).
--
-- @module Client
-- @author FlightControl
@ -12,7 +45,7 @@ Include.File( "Message" )
--- The CLIENT class
-- @type CLIENT
-- @extends Base#BASE
-- @extends Unit#UNIT
CLIENT = {
ONBOARDSIDE = {
NONE = 0,
@ -33,9 +66,37 @@ CLIENT = {
}
--- Use this method to register new Clients within the MOF.
--- Finds a CLIENT from the _DATABASE using the relevant DCS Unit.
-- @param #CLIENT self
-- @param #string ClientName Name of the Group as defined within the Mission Editor. The Group must have a Unit with the type Client.
-- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor.
-- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client.
-- @return #CLIENT
-- @usage
-- -- Create new Clients.
-- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
-- Mission:AddGoal( DeploySA6TroopsGoal )
--
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
function CLIENT:Find( DCSUnit )
local ClientName = DCSUnit:getName()
local ClientFound = _DATABASE:FindClient( ClientName )
if ClientFound then
ClientFound:F( ClientName )
return ClientFound
end
error( "CLIENT not found for: " .. ClientName )
end
--- Finds a CLIENT from the _DATABASE using the relevant Client Unit Name.
-- As an optional parameter, a briefing text can be given also.
-- @param #CLIENT self
-- @param #string ClientName Name of the DCS **Unit** as defined within the Mission Editor.
-- @param #string ClientBriefing Text that describes the briefing of the mission when a Player logs into the Client.
-- @return #CLIENT
-- @usage
@ -43,21 +104,38 @@ CLIENT = {
-- local Mission = MISSIONSCHEDULER.AddMission( 'Russia Transport Troops SA-6', 'Operational', 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.', 'Russia' )
-- Mission:AddGoal( DeploySA6TroopsGoal )
--
-- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
-- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
-- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
-- Mission:AddClient( CLIENT:New( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
function CLIENT:New( ClientName, ClientBriefing )
local self = BASE:Inherit( self, BASE:New() )
self:F( ClientName, ClientBriefing )
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 1' ):Transport() )
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 3' ):Transport() )
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*HOT-Deploy Troops 2' ):Transport() )
-- Mission:AddClient( CLIENT:FindByName( 'RU MI-8MTV2*RAMP-Deploy Troops 4' ):Transport() )
function CLIENT:FindByName( ClientName, ClientBriefing )
local ClientFound = _DATABASE:FindClient( ClientName )
self.ClientName = ClientName
self:AddBriefing( ClientBriefing )
self.MessageSwitch = true
return self
if ClientFound then
ClientFound:F( { ClientName, ClientBriefing } )
ClientFound:AddBriefing( ClientBriefing )
ClientFound.MessageSwitch = true
return ClientFound
end
error( "CLIENT not found for: " .. ClientName )
end
function CLIENT:Register( ClientName )
local self = BASE:Inherit( self, UNIT:Register( ClientName ) )
self:F( ClientName )
self.ClientName = ClientName
self.MessageSwitch = true
self.ClientAlive2 = false
self.AliveCheckScheduler = routines.scheduleFunction( self._AliveCheckScheduler, { self }, timer.getTime() + 1, 5 )
return self
end
--- Transport defines that the Client is a Transport. Transports show cargo.
-- @param #CLIENT self
-- @return #CLIENT
@ -71,13 +149,38 @@ end
--- AddBriefing adds a briefing to a CLIENT when a player joins a mission.
-- @param #CLIENT self
-- @param #string ClientBriefing is the text defining the Mission briefing.
-- @return #CLIENT
-- @return #CLIENT self
function CLIENT:AddBriefing( ClientBriefing )
self:F()
self:F( ClientBriefing )
self.ClientBriefing = ClientBriefing
self.ClientBriefingShown = false
return self
end
--- Show the briefing of the MISSION to the CLIENT.
-- @param #CLIENT self
-- @return #CLIENT self
function CLIENT:ShowBriefing()
self:F( { self.ClientName, self.ClientBriefingShown } )
if not self.ClientBriefingShown then
self.ClientBriefingShown = true
local Briefing = ""
if self.MissionBriefing then
Briefing = Briefing .. self.MissionBriefing
end
if self.ClientBriefing then
Briefing = Briefing .. "\n" .. self.ClientBriefing
end
Briefing = Briefing .. "\nPress [LEFT ALT]+[B] to view the complete mission briefing."
self:Message( Briefing, 30, self.ClientName .. '/MissionBriefing', "Briefing" )
end
return self
end
--- Resets a CLIENT.
-- @param #CLIENT self
@ -87,21 +190,6 @@ function CLIENT:Reset( ClientName )
self._Menus = {}
end
--- Checks for a client alive event and calls a function on a continuous basis.
-- @param #CLIENT self
-- @param #function CallBack Function.
-- @return #CLIENT
function CLIENT:Alive( CallBack, ... )
self:F()
self.ClientAlive2 = false
self.ClientCallBack = CallBack
self.ClientParameters = arg
self.AliveCheckScheduler = routines.scheduleFunction( self._AliveCheckScheduler, { self }, timer.getTime() + 1, 5 )
return self
end
-- Is Functions
--- Checks if the CLIENT is a multi-seated UNIT.
@ -126,32 +214,30 @@ function CLIENT:IsMultiSeated()
return false
end
--- Checks if client is alive and returns true or false.
--- Checks for a client alive event and calls a function on a continuous basis.
-- @param #CLIENT self
-- @returns #boolean Returns true if client is alive.
function CLIENT:IsAlive()
self:F( self.ClientName )
-- @param #function CallBack Function.
-- @return #CLIENT
function CLIENT:Alive( CallBack, ... )
self:F()
local ClientDCSGroup = self:GetDCSGroup()
if ClientDCSGroup then
self:T("true")
return true
end
self:T( "false" )
return false
end
self.ClientCallBack = CallBack
self.ClientParameters = arg
return self
end
--- @param #CLIENT self
function CLIENT:_AliveCheckScheduler()
self:F( { self.ClientName, self.ClientAlive2 } )
self:F( { self.ClientName, self.ClientAlive2, self.ClientBriefingShown } )
if self:IsAlive() then
if self:IsAlive() then -- Polymorphic call of UNIT
if self.ClientAlive2 == false then
self:T("Calling Callback function")
self.ClientCallBack( self, unpack( self.ClientParameters ) )
self:ShowBriefing()
if self.ClientCallBack then
self:T("Calling Callback function")
self.ClientCallBack( self, unpack( self.ClientParameters ) )
end
self.ClientAlive2 = true
end
else
@ -175,6 +261,8 @@ function CLIENT:GetDCSGroup()
-- else
-- return nil
-- end
local ClientUnit = Unit.getByName( self.ClientName )
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) }
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
@ -183,49 +271,51 @@ function CLIENT:GetDCSGroup()
self:T3( { "UnitData:", UnitData } )
if UnitData and UnitData:isExist() then
local ClientGroup = Group.getByName( self.ClientName )
if ClientGroup then
self:T3( "ClientGroup = " .. self.ClientName )
if ClientGroup:isExist() then
if ClientGroup:getID() == UnitData:getGroup():getID() then
self:T3( "Normal logic" )
self:T3( self.ClientName .. " : group found!" )
return ClientGroup
end
else
-- Now we need to resolve the bugs in DCS 1.5 ...
-- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil)
self:T3( "Bug 1.5 logic" )
local ClientUnits = _DATABASE.Groups[self.ClientName].Units
self:T3( { ClientUnits[1].name, env.getValueDictByKey(ClientUnits[1].name) } )
for ClientUnitID, ClientUnitData in pairs( ClientUnits ) do
self:T3( { tonumber(UnitData:getID()), ClientUnitData.unitId } )
if tonumber(UnitData:getID()) == ClientUnitData.unitId then
local ClientGroupTemplate = _DATABASE.Groups[self.ClientName].Template
self.ClientID = ClientGroupTemplate.groupId
self.ClientGroupUnit = UnitData
self:T3( self.ClientName .. " : group found in bug 1.5 resolvement logic!" )
return ClientGroup
end
end
end
-- else
-- error( "Client " .. self.ClientName .. " not found!" )
end
--self:E(self.ClientName)
if ClientUnit then
local ClientGroup = ClientUnit:getGroup()
if ClientGroup then
self:T3( "ClientGroup = " .. self.ClientName )
if ClientGroup:isExist() and UnitData:getGroup():isExist() then
if ClientGroup:getID() == UnitData:getGroup():getID() then
self:T3( "Normal logic" )
self:T3( self.ClientName .. " : group found!" )
self.ClientGroupID = ClientGroup:getID()
self.ClientGroupName = ClientGroup:getName()
return ClientGroup
end
else
-- Now we need to resolve the bugs in DCS 1.5 ...
-- Consult the database for the units of the Client Group. (ClientGroup:getUnits() returns nil)
self:T3( "Bug 1.5 logic" )
local ClientGroupTemplate = _DATABASE.Templates.Units[self.ClientName].GroupTemplate
self.ClientGroupID = ClientGroupTemplate.groupId
self.ClientGroupName = _DATABASE.Templates.Units[self.ClientName].GroupName
self:T3( self.ClientName .. " : group found in bug 1.5 resolvement logic!" )
return ClientGroup
end
-- else
-- error( "Client " .. self.ClientName .. " not found!" )
end
else
--self:E( { "Client not found!", self.ClientName } )
end
end
end
end
-- For non player clients
local ClientGroup = Group.getByName( self.ClientName )
if ClientGroup then
self:T3( "ClientGroup = " .. self.ClientName )
if ClientGroup:isExist() then
self:T3( "Normal logic" )
self:T3( self.ClientName .. " : group found!" )
return ClientGroup
end
end
if ClientUnit then
local ClientGroup = ClientUnit:getGroup()
if ClientGroup then
self:T3( "ClientGroup = " .. self.ClientName )
if ClientGroup:isExist() then
self:T3( "Normal logic" )
self:T3( self.ClientName .. " : group found!" )
return ClientGroup
end
end
end
self.ClientGroupID = nil
self.ClientGroupUnit = nil
@ -240,16 +330,9 @@ end
-- @return DCSTypes#Group.ID
function CLIENT:GetClientGroupID()
if not self.ClientGroupID then
local ClientGroup = self:GetDCSGroup()
if ClientGroup and ClientGroup:isExist() then
self.ClientGroupID = ClientGroup:getID()
else
self.ClientGroupID = self.ClientID
end
end
local ClientGroup = self:GetDCSGroup()
self:T( self.ClientGroupID )
--self:E( self.ClientGroupID ) -- Determined in GetDCSGroup()
return self.ClientGroupID
end
@ -259,16 +342,9 @@ end
-- @return #string
function CLIENT:GetClientGroupName()
if not self.ClientGroupName then
local ClientGroup = self:GetDCSGroup()
if ClientGroup and ClientGroup:isExist() then
self.ClientGroupName = ClientGroup:getName()
else
self.ClientGroupName = self.ClientName
end
end
local ClientGroup = self:GetDCSGroup()
self:T( self.ClientGroupName )
self:T( self.ClientGroupName ) -- Determined in GetDCSGroup()
return self.ClientGroupName
end
@ -276,14 +352,15 @@ end
-- @param #CLIENT self
-- @return Unit#UNIT
function CLIENT:GetClientGroupUnit()
self:F()
self:F2()
local ClientGroup = self:GetDCSGroup()
if ClientGroup and ClientGroup:isExist() then
return UNIT:New( ClientGroup:getUnit(1) )
else
return UNIT:New( self.ClientGroupUnit )
local ClientDCSUnit = Unit.getByName( self.ClientName )
self:T( self.ClientDCSUnit )
if ClientDCSUnit and ClientDCSUnit:isExist() then
local ClientUnit = _DATABASE:FindUnit( self.ClientName )
self:T2( ClientUnit )
return ClientUnit
end
end
@ -293,80 +370,14 @@ end
function CLIENT:GetClientGroupDCSUnit()
self:F2()
local ClientGroup = self:GetDCSGroup()
local ClientDCSUnit = Unit.getByName( self.ClientName )
if ClientGroup and ClientGroup:isExist() then
return ClientGroup:getUnit(1)
else
return self.ClientGroupUnit
if ClientDCSUnit and ClientDCSUnit:isExist() then
self:T2( ClientDCSUnit )
return ClientDCSUnit
end
end
-- TODO what is this??? check. possible double function.
function CLIENT:GetUnit()
self:F()
return UNIT:New( self:GetClientGroupDCSUnit() )
end
--- Returns the position of the CLIENT in @{DCSTypes#Vec2} format..
-- @param #CLIENT self
-- @return DCSTypes#Vec2
function CLIENT:GetPointVec2()
self:F()
ClientGroupUnit = self:GetClientGroupDCSUnit()
if ClientGroupUnit then
if ClientGroupUnit:isExist() then
local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3
local PointVec2 = {} --DCSTypes#Vec2
PointVec2.x = PointVec3.x
PointVec2.y = PointVec3.z
self:T( { PointVec2 } )
return PointVec2
end
end
return nil
end
--- Returns the position of the CLIENT in @{DCSTypes#Vec3} format.
-- @param #CLIENT self
-- @return DCSTypes#Vec3
function CLIENT:ClientPosition()
self:F()
ClientGroupUnit = self:GetClientGroupDCSUnit()
if ClientGroupUnit then
if ClientGroupUnit:isExist() then
return ClientGroupUnit:getPosition()
end
end
return nil
end
--- Returns the altitude of the CLIENT.
-- @param #CLIENT self
-- @return DCSTypes#Distance
function CLIENT:GetAltitude()
self:F()
ClientGroupUnit = self:GetClientGroupDCSUnit()
if ClientGroupUnit then
if ClientGroupUnit:isExist() then
local PointVec3 = ClientGroupUnit:getPoint() --DCSTypes#Vec3
return PointVec3.y
end
end
return nil
end
--- Evaluates if the CLIENT is a transport.
-- @param #CLIENT self
@ -413,7 +424,7 @@ end
-- @param #string MessageCategory is the category of the message (the title).
-- @param #number MessageInterval is the interval in seconds between the display of the @{Message#MESSAGE} when the CLIENT is in the air.
function CLIENT:Message( Message, MessageDuration, MessageId, MessageCategory, MessageInterval )
self:F()
self:F( { Message, MessageDuration, MessageId, MessageCategory, MessageInterval } )
if not self.MenuMessages then
if self:GetClientGroupID() then

View File

@ -66,25 +66,31 @@ Include.File( "Routines" )
Include.File( "Base" )
Include.File( "Menu" )
Include.File( "Group" )
Include.File( "Unit" )
Include.File( "Event" )
Include.File( "Client" )
--- DATABASE class
-- @type DATABASE
-- @extends Base#BASE
DATABASE = {
ClassName = "DATABASE",
Templates = {
Units = {},
Groups = {},
ClientsByName = {},
ClientsByID = {},
},
DCSUnits = {},
DCSUnitsAlive = {},
Units = {},
Groups = {},
DCSGroups = {},
DCSGroupsAlive = {},
UNITS = {},
GROUPS = {},
NavPoints = {},
Statics = {},
Players = {},
AlivePlayers = {},
ClientsByName = {},
ClientsByID = {},
PlayersAlive = {},
CLIENTS = {},
ClientsAlive = {},
Filter = {
Coalitions = nil,
Categories = nil,
@ -140,148 +146,85 @@ function DATABASE:New()
_EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self )
_EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self )
return self
end
--- Builds a set of units of coalitons.
-- Possible current coalitions are red, blue and neutral.
-- @param #DATABASE self
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral".
-- @return #DATABASE self
function DATABASE:FilterCoalitions( Coalitions )
if not self.Filter.Coalitions then
self.Filter.Coalitions = {}
end
if type( Coalitions ) ~= "table" then
Coalitions = { Coalitions }
end
for CoalitionID, Coalition in pairs( Coalitions ) do
self.Filter.Coalitions[Coalition] = Coalition
end
return self
end
--- Builds a set of units out of categories.
-- Possible current categories are plane, helicopter, ground, ship.
-- @param #DATABASE self
-- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship".
-- @return #DATABASE self
function DATABASE:FilterCategories( Categories )
if not self.Filter.Categories then
self.Filter.Categories = {}
end
if type( Categories ) ~= "table" then
Categories = { Categories }
end
for CategoryID, Category in pairs( Categories ) do
self.Filter.Categories[Category] = Category
end
return self
end
--- Builds a set of units of defined unit types.
-- Possible current types are those types known within DCS world.
-- @param #DATABASE self
-- @param #string Types Can take those type strings known within DCS world.
-- @return #DATABASE self
function DATABASE:FilterTypes( Types )
if not self.Filter.Types then
self.Filter.Types = {}
end
if type( Types ) ~= "table" then
Types = { Types }
end
for TypeID, Type in pairs( Types ) do
self.Filter.Types[Type] = Type
end
return self
end
--- Builds a set of units of defined countries.
-- Possible current countries are those known within DCS world.
-- @param #DATABASE self
-- @param #string Countries Can take those country strings known within DCS world.
-- @return #DATABASE self
function DATABASE:FilterCountries( Countries )
if not self.Filter.Countries then
self.Filter.Countries = {}
end
if type( Countries ) ~= "table" then
Countries = { Countries }
end
for CountryID, Country in pairs( Countries ) do
self.Filter.Countries[Country] = Country
end
return self
end
--- Builds a set of units of defined unit prefixes.
-- All the units starting with the given prefixes will be included within the set.
-- @param #DATABASE self
-- @param #string Prefixes The prefix of which the unit name starts with.
-- @return #DATABASE self
function DATABASE:FilterUnitPrefixes( Prefixes )
if not self.Filter.UnitPrefixes then
self.Filter.UnitPrefixes = {}
end
if type( Prefixes ) ~= "table" then
Prefixes = { Prefixes }
end
for PrefixID, Prefix in pairs( Prefixes ) do
self.Filter.UnitPrefixes[Prefix] = Prefix
end
return self
end
--- Builds a set of units of defined group prefixes.
-- All the units starting with the given group prefixes will be included within the set.
-- @param #DATABASE self
-- @param #string Prefixes The prefix of which the group name where the unit belongs to starts with.
-- @return #DATABASE self
function DATABASE:FilterGroupPrefixes( Prefixes )
if not self.Filter.GroupPrefixes then
self.Filter.GroupPrefixes = {}
end
if type( Prefixes ) ~= "table" then
Prefixes = { Prefixes }
end
for PrefixID, Prefix in pairs( Prefixes ) do
self.Filter.GroupPrefixes[Prefix] = Prefix
end
return self
end
--- Starts the filtering.
-- @param #DATABASE self
-- @return #DATABASE self
function DATABASE:FilterStart()
if _DATABASE then
-- OK, we have a _DATABASE
-- Now use the different filters to build the set.
-- We first take ALL of the Units of the _DATABASE.
for UnitRegistrationID, UnitRegistration in pairs( _DATABASE.Units ) do
self:T( UnitRegistration )
local DCSUnit = Unit.getByName( UnitRegistration.UnitName )
if self:_IsIncludeDCSUnit( DCSUnit ) then
self.DCSUnits[DCSUnit:getName()] = DCSUnit
end
if self:_IsAliveDCSUnit( DCSUnit ) then
self.DCSUnitsAlive[DCSUnit:getName()] = DCSUnit
end
end
else
self:E( "There is a structural error in MOOSE. No _DATABASE has been defined! Cannot build this custom DATABASE." )
end
-- Add database with registered clients and already alive players
-- Follow alive players and clients
_EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self )
_EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self )
return self
end
--- Finds a Unit based on the Unit Name.
-- @param #DATABASE self
-- @param #string UnitName
-- @return Unit#UNIT The found Unit.
function DATABASE:FindUnit( UnitName )
local UnitFound = self.UNITS[UnitName]
return UnitFound
end
--- Adds a Unit based on the Unit Name in the DATABASE.
-- @param #DATABASE self
function DATABASE:AddUnit( DCSUnit, DCSUnitName )
self.DCSUnits[DCSUnitName] = DCSUnit
self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName )
end
--- Deletes a Unit from the DATABASE based on the Unit Name.
-- @param #DATABASE self
function DATABASE:DeleteUnit( DCSUnitName )
self.DCSUnits[DCSUnitName] = nil
end
--- Finds a CLIENT based on the ClientName.
-- @param #DATABASE self
-- @param #string ClientName
-- @return Client#CLIENT The found CLIENT.
function DATABASE:FindClient( ClientName )
local ClientFound = self.CLIENTS[ClientName]
return ClientFound
end
--- Adds a CLIENT based on the ClientName in the DATABASE.
-- @param #DATABASE self
function DATABASE:AddClient( ClientName )
self.CLIENTS[ClientName] = CLIENT:Register( ClientName )
self:E( self.CLIENTS[ClientName]:GetClassNameAndID() )
end
--- Finds a GROUP based on the GroupName.
-- @param #DATABASE self
-- @param #string GroupName
-- @return Group#GROUP The found GROUP.
function DATABASE:FindGroup( GroupName )
local GroupFound = self.GROUPS[GroupName]
return GroupFound
end
--- Adds a GROUP based on the GroupName in the DATABASE.
-- @param #DATABASE self
function DATABASE:AddGroup( DCSGroup, GroupName )
self.DCSGroups[GroupName] = DCSGroup
self.GROUPS[GroupName] = GROUP:Register( GroupName )
end
--- Instantiate new Groups within the DCSRTE.
-- This method expects EXACTLY the same structure as a structure within the ME, and needs 2 additional fields defined:
-- SpawnCountryID, SpawnCategoryID
-- This method is used by the SPAWN class.
-- @param #DATABASE self
-- @param #table SpawnTemplate
-- @return #DATABASE self
function DATABASE:Spawn( SpawnTemplate )
self:F( SpawnTemplate.name )
@ -306,7 +249,7 @@ function DATABASE:Spawn( SpawnTemplate )
SpawnTemplate.SpawnCategoryID = SpawnCategoryID
local SpawnGroup = GROUP:New( Group.getByName( SpawnTemplate.name ) )
local SpawnGroup = GROUP:Register( SpawnTemplate.name )
return SpawnGroup
end
@ -315,7 +258,7 @@ end
function DATABASE:SetStatusGroup( GroupName, Status )
self:F( Status )
self.Groups[GroupName].Status = Status
self.Templates.Groups[GroupName].Status = Status
end
@ -323,47 +266,117 @@ end
function DATABASE:GetStatusGroup( GroupName )
self:F( Status )
if self.Groups[GroupName] then
return self.Groups[GroupName].Status
if self.Templates.Groups[GroupName] then
return self.Templates.Groups[GroupName].Status
else
return ""
end
end
--- Registers new Group Templates within the DATABASE Object.
--- Private method that registers new Group Templates within the DATABASE Object.
-- @param #DATABASE self
-- @param #table GroupTemplate
-- @return #DATABASE self
function DATABASE:_RegisterGroup( GroupTemplate )
local GroupTemplateName = env.getValueDictByKey(GroupTemplate.name)
if not self.Groups[GroupTemplateName] then
self.Groups[GroupTemplateName] = {}
self.Groups[GroupTemplateName].Status = nil
if not self.Templates.Groups[GroupTemplateName] then
self.Templates.Groups[GroupTemplateName] = {}
self.Templates.Groups[GroupTemplateName].Status = nil
end
self.Groups[GroupTemplateName].GroupName = GroupTemplateName
self.Groups[GroupTemplateName].Template = GroupTemplate
self.Groups[GroupTemplateName].groupId = GroupTemplate.groupId
self.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
self.Groups[GroupTemplateName].Units = GroupTemplate.units
-- Delete the spans from the route, it is not needed and takes memory.
if GroupTemplate.route and GroupTemplate.route.spans then
GroupTemplate.route.spans = nil
end
self.Templates.Groups[GroupTemplateName].GroupName = GroupTemplateName
self.Templates.Groups[GroupTemplateName].Template = GroupTemplate
self.Templates.Groups[GroupTemplateName].groupId = GroupTemplate.groupId
self.Templates.Groups[GroupTemplateName].UnitCount = #GroupTemplate.units
self.Templates.Groups[GroupTemplateName].Units = GroupTemplate.units
self:T( { "Group", self.Groups[GroupTemplateName].GroupName, self.Groups[GroupTemplateName].UnitCount } )
self:T( { "Group", self.Templates.Groups[GroupTemplateName].GroupName, self.Templates.Groups[GroupTemplateName].UnitCount } )
for unit_num, UnitTemplate in pairs(GroupTemplate.units) do
for unit_num, UnitTemplate in pairs( GroupTemplate.units ) do
local UnitTemplateName = env.getValueDictByKey(UnitTemplate.name)
self.Units[UnitTemplateName] = {}
self.Units[UnitTemplateName].UnitName = UnitTemplateName
self.Units[UnitTemplateName].Template = UnitTemplate
self.Units[UnitTemplateName].GroupName = GroupTemplateName
self.Units[UnitTemplateName].GroupTemplate = GroupTemplate
self.Units[UnitTemplateName].GroupId = GroupTemplate.groupId
self.Templates.Units[UnitTemplateName] = {}
self.Templates.Units[UnitTemplateName].UnitName = UnitTemplateName
self.Templates.Units[UnitTemplateName].Template = UnitTemplate
self.Templates.Units[UnitTemplateName].GroupName = GroupTemplateName
self.Templates.Units[UnitTemplateName].GroupTemplate = GroupTemplate
self.Templates.Units[UnitTemplateName].GroupId = GroupTemplate.groupId
self:E( {"skill",UnitTemplate.skill})
if UnitTemplate.skill and (UnitTemplate.skill == "Client" or UnitTemplate.skill == "Player") then
self.ClientsByName[UnitTemplateName] = UnitTemplate
self.ClientsByID[UnitTemplate.unitId] = UnitTemplate
self.Templates.ClientsByName[UnitTemplateName] = UnitTemplate
self.Templates.ClientsByID[UnitTemplate.unitId] = UnitTemplate
end
self:E( { "Unit", self.Units[UnitTemplateName].UnitName } )
self:E( { "Unit", self.Templates.Units[UnitTemplateName].UnitName } )
end
end
--- Private method that registers all alive players in the mission.
-- @param #DATABASE self
-- @return #DATABASE self
function DATABASE:_RegisterPlayers()
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) }
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
for UnitId, UnitData in pairs( CoalitionData ) do
self:T3( { "UnitData:", UnitData } )
if UnitData and UnitData:isExist() then
local UnitName = UnitData:getName()
if not self.PlayersAlive[UnitName] then
self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } )
self.PlayersAlive[UnitName] = UnitData:getPlayerName()
end
end
end
end
return self
end
--- Private method that registers all datapoints within in the mission.
-- @param #DATABASE self
-- @return #DATABASE self
function DATABASE:_RegisterDatabase()
local CoalitionsData = { GroupsRed = coalition.getGroups( coalition.side.RED ), GroupsBlue = coalition.getGroups( coalition.side.BLUE ) }
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
for DCSGroupId, DCSGroup in pairs( CoalitionData ) do
if DCSGroup:isExist() then
local DCSGroupName = DCSGroup:getName()
self:E( { "Register Group:", DCSGroup, DCSGroupName } )
self:AddGroup( DCSGroup, DCSGroupName )
for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do
local DCSUnitName = DCSUnit:getName()
self:E( { "Register Unit:", DCSUnit, DCSUnitName } )
self:AddUnit( DCSUnit, DCSUnitName )
end
else
self:E( { "Group does not exist: ", DCSGroup } )
end
end
end
for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do
self:E( { "Adding Client:", ClientName } )
self:AddClient( ClientName )
end
return self
end
--- Events
--- Handles the OnBirth event for the alive units set.
-- @param #DATABASE self
-- @param Event#EVENTDATA Event
@ -372,8 +385,9 @@ function DATABASE:_EventOnBirth( Event )
if Event.IniDCSUnit then
if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then
self.DCSUnits[Event.IniDCSUnitName] = Event.IniDCSUnit
self.DCSUnitsAlive[Event.IniDCSUnitName] = Event.IniDCSUnit
self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName )
self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName )
self:_EventOnPlayerEnterUnit( Event )
end
end
end
@ -385,25 +399,61 @@ function DATABASE:_EventOnDeadOrCrash( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self.DCSUnitsAlive[Event.IniDCSUnitName] then
self.DCSUnits[Event.IniDCSUnitName] = nil
self.DCSUnitsAlive[Event.IniDCSUnitName] = nil
if self.DCSUnits[Event.IniDCSUnitName] then
self:DeleteUnit( Event.IniDCSUnitName )
-- add logic to correctly remove a group once all units are destroyed...
end
end
end
--- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters.
--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).
-- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter.
-- @param Event#EVENTDATA Event
function DATABASE:_EventOnPlayerEnterUnit( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then
if not self.PlayersAlive[Event.IniDCSUnitName] then
self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } )
self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName()
self.ClientsAlive[Event.IniDCSUnitName] = self.CLIENTS[ Event.IniDCSUnitName ]
end
end
end
end
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
-- @param #DATABASE self
-- @param Event#EVENTDATA Event
function DATABASE:_EventOnPlayerLeaveUnit( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then
if self.PlayersAlive[Event.IniDCSUnitName] then
self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } )
self.PlayersAlive[Event.IniDCSUnitName] = nil
self.ClientsAlive[Event.IniDCSUnitName] = nil
end
end
end
end
--- Iterators
--- Interate the DATABASE and call an interator function for the given set, providing the Object for each element within the set and optional parameters.
-- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the database.
-- @return #DATABASE self
function DATABASE:ForEachAliveUnit( IteratorFunction, ... )
function DATABASE:ForEach( IteratorFunction, arg, Set )
self:F( arg )
local function CoRoutine()
local Count = 0
for DCSUnitID, DCSUnit in pairs( self.DCSUnitsAlive ) do
self:T2( DCSUnit )
IteratorFunction( DCSUnit, unpack( arg ) )
for ObjectID, Object in pairs( Set ) do
self:T2( Object )
IteratorFunction( Object, unpack( arg ) )
Count = Count + 1
if Count % 10 == 0 then
coroutine.yield( false )
@ -423,20 +473,61 @@ function DATABASE:ForEachAliveUnit( IteratorFunction, ... )
error( res )
end
if res == false then
timer.scheduleFunction( Schedule, {}, timer.getTime() + 0.001 )
return true -- resume next time the loop
end
return false
end
timer.scheduleFunction( Schedule, {}, timer.getTime() + 1 )
local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 )
return self
end
--- Interate the DATABASE and call an interator function for each **alive** unit, providing the Unit and optional parameters.
-- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a UNIT parameter.
-- @return #DATABASE self
function DATABASE:ForEachDCSUnit( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.DCSUnits )
return self
end
--- Interate the DATABASE and call an interator function for each **alive** player, providing the Unit of the player and optional parameters.
-- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a UNIT parameter.
-- @return #DATABASE self
function DATABASE:ForEachPlayer( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.PlayersAlive )
return self
end
--- Interate the DATABASE and call an interator function for each client, providing the Client to the function and optional parameters.
-- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the database. The function needs to accept a CLIENT parameter.
-- @return #DATABASE self
function DATABASE:ForEachClient( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.CLIENTS )
return self
end
function DATABASE:ScanEnvironment()
self:F()
self.Navpoints = {}
self.Units = {}
self.UNITS = {}
--Build routines.db.units and self.Navpoints
for coa_name, coa_data in pairs(env.mission.coalition) do
@ -495,6 +586,9 @@ function DATABASE:ScanEnvironment()
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
end --for coa_name, coa_data in pairs(mission.coalition) do
self:_RegisterDatabase()
self:_RegisterPlayers()
return self
end
@ -582,6 +676,22 @@ function DATABASE:_IsAliveDCSUnit( DCSUnit )
return DCSUnitAlive
end
---
-- @param #DATABASE self
-- @param DCSGroup#Group DCSGroup
-- @return #DATABASE self
function DATABASE:_IsAliveDCSGroup( DCSGroup )
self:F( DCSGroup )
local DCSGroupAlive = false
if DCSGroup and DCSGroup:isExist() then
if self.DCSGroups[DCSGroup:getName()] then
DCSGroupAlive = true
end
end
self:T( DCSGroupAlive )
return DCSGroupAlive
end
--- Traces the current database contents in the log ... (for debug reasons).
-- @param #DATABASE self
@ -590,7 +700,6 @@ function DATABASE:TraceDatabase()
self:F()
self:T( { "DCSUnits:", self.DCSUnits } )
self:T( { "DCSUnitsAlive:", self.DCSUnitsAlive } )
end

View File

@ -635,7 +635,7 @@ function ESCORT._HoldPosition( MenuParam )
routines.removeFunction( self.FollowScheduler )
local PointFrom = {}
local GroupPoint = EscortGroup:GetUnit(1):GetPositionVec3()
local GroupPoint = EscortGroup:GetUnit(1):GetPointVec3()
PointFrom = {}
PointFrom.x = GroupPoint.x
PointFrom.y = GroupPoint.z
@ -977,15 +977,15 @@ function ESCORT:_FollowScheduler( FollowDistance )
local GroupUnit = self.EscortGroup:GetUnit( 1 )
if self.CT1 == 0 and self.GT1 == 0 then
self.CV1 = ClientUnit:GetPositionVec3()
self.CV1 = ClientUnit:GetPointVec3()
self.CT1 = timer.getTime()
self.GV1 = GroupUnit:GetPositionVec3()
self.GV1 = GroupUnit:GetPointVec3()
self.GT1 = timer.getTime()
else
local CT1 = self.CT1
local CT2 = timer.getTime()
local CV1 = self.CV1
local CV2 = ClientUnit:GetPositionVec3()
local CV2 = ClientUnit:GetPointVec3()
self.CT1 = CT2
self.CV1 = CV2
@ -999,7 +999,7 @@ function ESCORT:_FollowScheduler( FollowDistance )
local GT1 = self.GT1
local GT2 = timer.getTime()
local GV1 = self.GV1
local GV2 = GroupUnit:GetPositionVec3()
local GV2 = GroupUnit:GetPointVec3()
self.GT1 = GT2
self.GV1 = GV2
@ -1082,7 +1082,7 @@ function ESCORT:_ReportTargetsScheduler()
self:T( EscortObject )
if EscortObject and EscortObject:isExist() and EscortObject.id_ < 50000000 then
local EscortTargetUnit = UNIT:New( EscortObject )
local EscortTargetUnit = UNIT:Find( EscortObject )
local EscortTargetUnitName = EscortTargetUnit:GetName()
@ -1105,8 +1105,8 @@ function ESCORT:_ReportTargetsScheduler()
-- EscortTargetLastVelocity } )
local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPositionVec3()
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
local EscortTargetUnitPositionVec3 = EscortTargetUnit:GetPointVec3()
local EscortPositionVec3 = self.EscortGroup:GetPointVec3()
local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
@ -1164,8 +1164,8 @@ function ESCORT:_ReportTargetsScheduler()
EscortTargetMessage = EscortTargetMessage .. "Unknown target at "
end
local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPositionVec3()
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
local EscortTargetUnitPositionVec3 = ClientEscortTargetData.AttackUnit:GetPointVec3()
local EscortPositionVec3 = self.EscortGroup:GetPointVec3()
local Distance = ( ( EscortTargetUnitPositionVec3.x - EscortPositionVec3.x )^2 +
( EscortTargetUnitPositionVec3.y - EscortPositionVec3.y )^2 +
( EscortTargetUnitPositionVec3.z - EscortPositionVec3.z )^2
@ -1232,7 +1232,7 @@ function ESCORT:_ReportTargetsScheduler()
local TaskPoints = self:RegisterRoute()
for WayPointID, WayPoint in pairs( TaskPoints ) do
local EscortPositionVec3 = self.EscortGroup:GetPositionVec3()
local EscortPositionVec3 = self.EscortGroup:GetPointVec3()
local Distance = ( ( WayPoint.x - EscortPositionVec3.x )^2 +
( WayPoint.y - EscortPositionVec3.z )^2
) ^ 0.5 / 1000

View File

@ -437,6 +437,32 @@ function EVENT:OnHitForUnit( EventDCSUnitName, EventFunction, EventSelf )
return self
end
--- Set a new listener for an S_EVENT_PLAYER_ENTER_UNIT event.
-- @param #EVENT self
-- @param #function EventFunction The function to be called when the event occurs for the unit.
-- @param Base#BASE EventSelf The self instance of the class for which the event is.
-- @return #EVENT
function EVENT:OnPlayerEnterUnit( EventFunction, EventSelf )
self:F()
self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_ENTER_UNIT )
return self
end
--- Set a new listener for an S_EVENT_PLAYER_LEAVE_UNIT event.
-- @param #EVENT self
-- @param #function EventFunction The function to be called when the event occurs for the unit.
-- @param Base#BASE EventSelf The self instance of the class for which the event is.
-- @return #EVENT
function EVENT:OnPlayerLeaveUnit( EventFunction, EventSelf )
self:F()
self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PLAYER_LEAVE_UNIT )
return self
end
function EVENT:onEvent( Event )
@ -468,6 +494,7 @@ function EVENT:onEvent( Event )
Event.WeaponName = Event.Weapon:getTypeName()
--Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
end
self:E( { _EVENTCODES[Event.id], Event } )
for ClassName, EventData in pairs( self.Events[Event.id] ) do
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
self:T2( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } )

File diff suppressed because it is too large Load Diff

View File

@ -245,3 +245,127 @@ function MENU_CLIENT_COMMAND:Remove()
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end
--- The MENU_COALITION class
-- @type MENU_COALITION
-- @extends Menu#MENU
MENU_COALITION = {
ClassName = "MENU_COALITION"
}
--- Creates a new coalition menu item
-- @param #MENU_COALITION self
-- @param DCSCoalition#coalition.side MenuCoalition The coalition owning the menu.
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu.
-- @return #MENU_COALITION self
function MENU_COALITION:New( MenuCoalition, MenuText, ParentMenu )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self:F( { MenuCoalition, MenuText, ParentMenu } )
self.MenuCoalition = MenuCoalition
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self.Menus = {}
self:T( { MenuParentPath, MenuText } )
self.MenuPath = missionCommands.addSubMenuForCoalition( self.MenuCoalition, MenuText, MenuParentPath )
self:T( { 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_COALITION.
-- @param #MENU_COALITION self
-- @return #MENU_COALITION self
function MENU_COALITION: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_COALITION.
-- @param #MENU_COALITION self
-- @return #MENU_COALITION self
function MENU_COALITION:Remove()
self:F( self.MenuPath )
self:RemoveSubMenus()
missionCommands.removeItemForCoalition( self.MenuCoalition, self.MenuPath )
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end
--- The MENU_COALITION_COMMAND class
-- @type MENU_COALITION_COMMAND
-- @extends Menu#MENU
MENU_COALITION_COMMAND = {
ClassName = "MENU_COALITION_COMMAND"
}
--- Creates a new radio command item for a group
-- @param #MENU_COALITION_COMMAND self
-- @param DCSCoalition#coalition.side MenuCoalition The coalition owning the menu.
-- @param MenuText The text for the menu.
-- @param ParentMenu The parent menu.
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
-- @param CommandMenuArgument An argument for the function.
-- @return #MENU_COALITION_COMMAND self
function MENU_COALITION_COMMAND:New( MenuCoalition, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self.MenuCoalition = MenuCoalition
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self:T( { MenuParentPath, MenuText, CommandMenuFunction, CommandMenuArgument } )
self.MenuPath = missionCommands.addCommandForCoalition( self.MenuCoalition, MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
self.CommandMenuFunction = CommandMenuFunction
self.CommandMenuArgument = CommandMenuArgument
ParentMenu.Menus[self.MenuPath] = self
return self
end
--- Removes a radio command item for a coalition
-- @param #MENU_COALITION_COMMAND self
-- @return #MENU_COALITION_COMMAND self
function MENU_COALITION_COMMAND:Remove()
self:F( self.MenuPath )
missionCommands.removeItemForCoalition( self.MenuCoalition, self.MenuPath )
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end

680
Moose/MissileTrainer.lua Normal file
View File

@ -0,0 +1,680 @@
--- Provides missile training functions.
--
-- @{#MISSILETRAINER} class
-- ========================
-- The @{#MISSILETRAINER} class uses the DCS world messaging system to be alerted of any missiles fired, and when a missile would hit your aircraft,
-- the class will destroy the missile within a certain range, to avoid damage to your aircraft.
-- It suports the following functionality:
--
-- * Track the missiles fired at you and other players, providing bearing and range information of the missiles towards the airplanes.
-- * Provide alerts of missile launches, including detailed information of the units launching, including bearing, range …
-- * Provide alerts when a missile would have killed your aircraft.
-- * Provide alerts when the missile self destructs.
-- * Enable / Disable and Configure the Missile Trainer using the various menu options.
--
-- When running a mission where MISSILETRAINER is used, the following radio menu structure ( 'Radio Menu' -> 'Other (F10)' -> 'MissileTrainer' ) options are available for the players:
--
-- * **Messages**: Menu to configure all messages.
-- * **Messages On**: Show all messages.
-- * **Messages Off**: Disable all messages.
-- * **Tracking**: Menu to configure missile tracking messages.
-- * **To All**: Shows missile tracking messages to all players.
-- * **To Target**: Shows missile tracking messages only to the player where the missile is targetted at.
-- * **Tracking On**: Show missile tracking messages.
-- * **Tracking Off**: Disable missile tracking messages.
-- * **Frequency Increase**: Increases the missile tracking message frequency with one second.
-- * **Frequency Decrease**: Decreases the missile tracking message frequency with one second.
-- * **Alerts**: Menu to configure alert messages.
-- * **To All**: Shows alert messages to all players.
-- * **To Target**: Shows alert messages only to the player where the missile is (was) targetted at.
-- * **Hits On**: Show missile hit alert messages.
-- * **Hits Off**: Disable missile hit alert messages.
-- * **Launches On**: Show missile launch messages.
-- * **Launches Off**: Disable missile launch messages.
-- * **Details**: Menu to configure message details.
-- * **Range On**: Shows range information when a missile is fired to a target.
-- * **Range Off**: Disable range information when a missile is fired to a target.
-- * **Bearing On**: Shows bearing information when a missile is fired to a target.
-- * **Bearing Off**: Disable bearing information when a missile is fired to a target.
-- * **Distance**: Menu to configure the distance when a missile needs to be destroyed when near to a player, during tracking. This will improve/influence hit calculation accuracy, but has the risk of damaging the aircraft when the missile reaches the aircraft before the distance is measured.
-- * **50 meter**: Destroys the missile when the distance to the aircraft is below or equal to 50 meter.
-- * **100 meter**: Destroys the missile when the distance to the aircraft is below or equal to 100 meter.
-- * **150 meter**: Destroys the missile when the distance to the aircraft is below or equal to 150 meter.
-- * **200 meter**: Destroys the missile when the distance to the aircraft is below or equal to 200 meter.
--
--
-- MISSILETRAINER construction methods:
-- ====================================
-- Create a new MISSILETRAINER object with the @{#MISSILETRAINER.New} method:
--
-- * @{#MISSILETRAINER.New}: Creates a new MISSILETRAINER object taking the maximum distance to your aircraft to evaluate when a missile needs to be destroyed.
--
-- MISSILETRAINER will collect each unit declared in the mission with a skill level "Client" and "Player", and will monitor the missiles shot at those.
--
-- MISSILETRAINER initialization methods:
-- ======================================
-- A MISSILETRAINER object will behave differently based on the usage of initialization methods:
--
-- * @{#MISSILETRAINER.InitMessagesOnOff}: Sets by default the display of any message to be ON or OFF.
-- * @{#MISSILETRAINER.InitTrackingToAll}: Sets by default the missile tracking report for all players or only for those missiles targetted to you.
-- * @{#MISSILETRAINER.InitTrackingOnOff}: Sets by default the display of missile tracking report to be ON or OFF.
-- * @{#MISSILETRAINER.InitTrackingFrequency}: Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.
-- * @{#MISSILETRAINER.InitAlertsToAll}: Sets by default the display of alerts to be shown to all players or only to you.
-- * @{#MISSILETRAINER.InitAlertsHitsOnOff}: Sets by default the display of hit alerts ON or OFF.
-- * @{#MISSILETRAINER.InitAlertsLaunchesOnOff}: Sets by default the display of launch alerts ON or OFF.
-- * @{#MISSILETRAINER.InitRangeOnOff}: Sets by default the display of range information of missiles ON of OFF.
-- * @{#MISSILETRAINER.InitBearingOnOff}: Sets by default the display of bearing information of missiles ON of OFF.
-- * @{#MISSILETRAINER.InitMenusOnOff}: Allows to configure the options through the radio menu.
--
-- @module MissileTrainer
-- @author FlightControl
Include.File( "Client" )
Include.File( "Scheduler" )
--- The MISSILETRAINER class
-- @type MISSILETRAINER
-- @extends Base#BASE
MISSILETRAINER = {
ClassName = "MISSILETRAINER",
}
--- Creates the main object which is handling missile tracking.
-- When a missile is fired a SCHEDULER is set off that follows the missile. When near a certain a client player, the missile will be destroyed.
-- @param #MISSILETRAINER self
-- @param #number Distance The distance in meters when a tracked missile needs to be destroyed when close to a player.
-- @param #string Briefing (Optional) Will show a text to the players when starting their mission. Can be used for briefing purposes.
-- @return #MISSILETRAINER
function MISSILETRAINER:New( Distance, Briefing )
local self = BASE:Inherit( self, BASE:New() )
self:F( Distance )
if Briefing then
self.Briefing = Briefing
end
self.Schedulers = {}
self.SchedulerID = 0
self.MessageInterval = 2
self.MessageLastTime = timer.getTime()
self.Distance = Distance / 1000
_EVENTDISPATCHER:OnShot( self._EventShot, self )
self.DB = DATABASE:New():FilterStart()
self.DBClients = self.DB.Clients
self.DBUnits = self.DB.Units
for ClientID, Client in pairs( self.DBClients ) do
local function _Alive( Client )
if self.Briefing then
Client:Message( self.Briefing, 15, "HELLO WORLD", "Trainer" )
end
if self.MenusOnOff == true then
Client:Message( "Use the 'Radio Menu' -> 'Other (F10)' -> 'Missile Trainer' menu options to change the Missile Trainer settings (for all players).", 15, "MENU", "Trainer" )
Client.MainMenu = MENU_CLIENT:New( Client, "Missile Trainer", nil ) -- Menu#MENU_CLIENT
Client.MenuMessages = MENU_CLIENT:New( Client, "Messages", Client.MainMenu )
Client.MenuOn = MENU_CLIENT_COMMAND:New( Client, "Messages On", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = true } )
Client.MenuOff = MENU_CLIENT_COMMAND:New( Client, "Messages Off", Client.MenuMessages, self._MenuMessages, { MenuSelf = self, MessagesOnOff = false } )
Client.MenuTracking = MENU_CLIENT:New( Client, "Tracking", Client.MainMenu )
Client.MenuTrackingToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = true } )
Client.MenuTrackingToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingToAll = false } )
Client.MenuTrackOn = MENU_CLIENT_COMMAND:New( Client, "Tracking On", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = true } )
Client.MenuTrackOff = MENU_CLIENT_COMMAND:New( Client, "Tracking Off", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingOnOff = false } )
Client.MenuTrackIncrease = MENU_CLIENT_COMMAND:New( Client, "Frequency Increase", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = -1 } )
Client.MenuTrackDecrease = MENU_CLIENT_COMMAND:New( Client, "Frequency Decrease", Client.MenuTracking, self._MenuMessages, { MenuSelf = self, TrackingFrequency = 1 } )
Client.MenuAlerts = MENU_CLIENT:New( Client, "Alerts", Client.MainMenu )
Client.MenuAlertsToAll = MENU_CLIENT_COMMAND:New( Client, "To All", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = true } )
Client.MenuAlertsToTarget = MENU_CLIENT_COMMAND:New( Client, "To Target", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsToAll = false } )
Client.MenuHitsOn = MENU_CLIENT_COMMAND:New( Client, "Hits On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = true } )
Client.MenuHitsOff = MENU_CLIENT_COMMAND:New( Client, "Hits Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsHitsOnOff = false } )
Client.MenuLaunchesOn = MENU_CLIENT_COMMAND:New( Client, "Launches On", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = true } )
Client.MenuLaunchesOff = MENU_CLIENT_COMMAND:New( Client, "Launches Off", Client.MenuAlerts, self._MenuMessages, { MenuSelf = self, AlertsLaunchesOnOff = false } )
Client.MenuDetails = MENU_CLIENT:New( Client, "Details", Client.MainMenu )
Client.MenuDetailsDistanceOn = MENU_CLIENT_COMMAND:New( Client, "Range On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = true } )
Client.MenuDetailsDistanceOff = MENU_CLIENT_COMMAND:New( Client, "Range Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsRangeOnOff = false } )
Client.MenuDetailsBearingOn = MENU_CLIENT_COMMAND:New( Client, "Bearing On", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = true } )
Client.MenuDetailsBearingOff = MENU_CLIENT_COMMAND:New( Client, "Bearing Off", Client.MenuDetails, self._MenuMessages, { MenuSelf = self, DetailsBearingOnOff = false } )
Client.MenuDistance = MENU_CLIENT:New( Client, "Set distance to plane", Client.MainMenu )
Client.MenuDistance50 = MENU_CLIENT_COMMAND:New( Client, "50 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 50 / 1000 } )
Client.MenuDistance100 = MENU_CLIENT_COMMAND:New( Client, "100 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 100 / 1000 } )
Client.MenuDistance150 = MENU_CLIENT_COMMAND:New( Client, "150 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 150 / 1000 } )
Client.MenuDistance200 = MENU_CLIENT_COMMAND:New( Client, "200 meter", Client.MenuDistance, self._MenuMessages, { MenuSelf = self, Distance = 200 / 1000 } )
else
if Client.MainMenu then
Client.MainMenu:Remove()
end
end
local ClientID = Client:GetID()
self:T( ClientID )
if not self.TrackingMissiles[ClientID] then
self.TrackingMissiles[ClientID] = {}
end
self.TrackingMissiles[ClientID].Client = Client
if not self.TrackingMissiles[ClientID].MissileData then
self.TrackingMissiles[ClientID].MissileData = {}
end
end
Client:Alive( _Alive )
end
-- self.DB:ForEachClient(
-- --- @param Client#CLIENT Client
-- function( Client )
--
-- ... actions ...
--
-- end
-- )
self.MessagesOnOff = true
self.TrackingToAll = false
self.TrackingOnOff = true
self.TrackingFrequency = 3
self.AlertsToAll = true
self.AlertsHitsOnOff = true
self.AlertsLaunchesOnOff = true
self.DetailsRangeOnOff = true
self.DetailsBearingOnOff = true
self.MenusOnOff = true
self.TrackingMissiles = {}
self.TrackingScheduler = SCHEDULER:New( self, self._TrackMissiles, {}, 0.5, 0.05, 0 )
return self
end
-- Initialization methods.
--- Sets by default the display of any message to be ON or OFF.
-- @param #MISSILETRAINER self
-- @param #boolean MessagesOnOff true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitMessagesOnOff( MessagesOnOff )
self:F( MessagesOnOff )
self.MessagesOnOff = MessagesOnOff
if self.MessagesOnOff == true then
MESSAGE:New( "Messages ON", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Messages OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Sets by default the missile tracking report for all players or only for those missiles targetted to you.
-- @param #MISSILETRAINER self
-- @param #boolean TrackingToAll true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitTrackingToAll( TrackingToAll )
self:F( TrackingToAll )
self.TrackingToAll = TrackingToAll
if self.TrackingToAll == true then
MESSAGE:New( "Missile tracking to all players ON", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Missile tracking to all players OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Sets by default the display of missile tracking report to be ON or OFF.
-- @param #MISSILETRAINER self
-- @param #boolean TrackingOnOff true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitTrackingOnOff( TrackingOnOff )
self:F( TrackingOnOff )
self.TrackingOnOff = TrackingOnOff
if self.TrackingOnOff == true then
MESSAGE:New( "Missile tracking ON", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Missile tracking OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Increases, decreases the missile tracking message display frequency with the provided time interval in seconds.
-- The default frequency is a 3 second interval, so the Tracking Frequency parameter specifies the increase or decrease from the default 3 seconds or the last frequency update.
-- @param #MISSILETRAINER self
-- @param #number TrackingFrequency Provide a negative or positive value in seconds to incraese or decrease the display frequency.
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitTrackingFrequency( TrackingFrequency )
self:F( TrackingFrequency )
self.TrackingFrequency = self.TrackingFrequency + TrackingFrequency
if self.TrackingFrequency < 0.5 then
self.TrackingFrequency = 0.5
end
if self.TrackingFrequency then
MESSAGE:New( "Missile tracking frequency is " .. self.TrackingFrequency .. " seconds.", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Sets by default the display of alerts to be shown to all players or only to you.
-- @param #MISSILETRAINER self
-- @param #boolean AlertsToAll true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitAlertsToAll( AlertsToAll )
self:F( AlertsToAll )
self.AlertsToAll = AlertsToAll
if self.AlertsToAll == true then
MESSAGE:New( "Alerts to all players ON", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Alerts to all players OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Sets by default the display of hit alerts ON or OFF.
-- @param #MISSILETRAINER self
-- @param #boolean AlertsHitsOnOff true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitAlertsHitsOnOff( AlertsHitsOnOff )
self:F( AlertsHitsOnOff )
self.AlertsHitsOnOff = AlertsHitsOnOff
if self.AlertsHitsOnOff == true then
MESSAGE:New( "Alerts Hits ON", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Alerts Hits OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Sets by default the display of launch alerts ON or OFF.
-- @param #MISSILETRAINER self
-- @param #boolean AlertsLaunchesOnOff true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitAlertsLaunchesOnOff( AlertsLaunchesOnOff )
self:F( AlertsLaunchesOnOff )
self.AlertsLaunchesOnOff = AlertsLaunchesOnOff
if self.AlertsLaunchesOnOff == true then
MESSAGE:New( "Alerts Launches ON", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Alerts Launches OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Sets by default the display of range information of missiles ON of OFF.
-- @param #MISSILETRAINER self
-- @param #boolean DetailsRangeOnOff true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitRangeOnOff( DetailsRangeOnOff )
self:F( DetailsRangeOnOff )
self.DetailsRangeOnOff = DetailsRangeOnOff
if self.DetailsRangeOnOff == true then
MESSAGE:New( "Range display ON", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Range display OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Sets by default the display of bearing information of missiles ON of OFF.
-- @param #MISSILETRAINER self
-- @param #boolean DetailsBearingOnOff true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitBearingOnOff( DetailsBearingOnOff )
self:F( DetailsBearingOnOff )
self.DetailsBearingOnOff = DetailsBearingOnOff
if self.DetailsBearingOnOff == true then
MESSAGE:New( "Bearing display OFF", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Bearing display OFF", "Menu", 15, "ID" ):ToAll()
end
return self
end
--- Enables / Disables the menus.
-- @param #MISSILETRAINER self
-- @param #boolean MenusOnOff true or false
-- @return #MISSILETRAINER self
function MISSILETRAINER:InitMenusOnOff( MenusOnOff )
self:F( MenusOnOff )
self.MenusOnOff = MenusOnOff
if self.MenusOnOff == true then
MESSAGE:New( "Menus are ENABLED (only when a player rejoins a slot)", "Menu", 15, "ID" ):ToAll()
else
MESSAGE:New( "Menus are DISABLED", "Menu", 15, "ID" ):ToAll()
end
return self
end
-- Menu functions
function MISSILETRAINER._MenuMessages( MenuParameters )
local self = MenuParameters.MenuSelf
if MenuParameters.MessagesOnOff ~= nil then
self:InitMessagesOnOff( MenuParameters.MessagesOnOff )
end
if MenuParameters.TrackingToAll ~= nil then
self:InitTrackingToAll( MenuParameters.TrackingToAll )
end
if MenuParameters.TrackingOnOff ~= nil then
self:InitTrackingOnOff( MenuParameters.TrackingOnOff )
end
if MenuParameters.TrackingFrequency ~= nil then
self:InitTrackingFrequency( MenuParameters.TrackingFrequency )
end
if MenuParameters.AlertsToAll ~= nil then
self:InitAlertsToAll( MenuParameters.AlertsToAll )
end
if MenuParameters.AlertsHitsOnOff ~= nil then
self:InitAlertsHitsOnOff( MenuParameters.AlertsHitsOnOff )
end
if MenuParameters.AlertsLaunchesOnOff ~= nil then
self:InitAlertsLaunchesOnOff( MenuParameters.AlertsLaunchesOnOff )
end
if MenuParameters.DetailsRangeOnOff ~= nil then
self:InitRangeOnOff( MenuParameters.DetailsRangeOnOff )
end
if MenuParameters.DetailsBearingOnOff ~= nil then
self:InitBearingOnOff( MenuParameters.DetailsBearingOnOff )
end
if MenuParameters.Distance ~= nil then
self.Distance = MenuParameters.Distance
MESSAGE:New( "Hit detection distance set to " .. self.Distance .. " meters", "Menu", 15, "ID" ):ToAll()
end
end
--- Detects if an SA site was shot with an anti radiation missile. In this case, take evasive actions based on the skill level set within the ME.
-- @param #MISSILETRAINER self
-- @param Event#EVENTDATA Event
function MISSILETRAINER:_EventShot( Event )
self:F( { Event } )
local TrainerSourceDCSUnit = Event.IniDCSUnit
local TrainerSourceDCSUnitName = Event.IniDCSUnitName
local TrainerWeapon = Event.Weapon -- Identify the weapon fired
local TrainerWeaponName = Event.WeaponName -- return weapon type
self:T( "Missile Launched = " .. TrainerWeaponName )
local TrainerTargetDCSUnit = TrainerWeapon:getTarget() -- Identify target
local TrainerTargetDCSUnitName = Unit.getName( TrainerTargetDCSUnit )
local TrainerTargetSkill = _DATABASE.Templates.Units[TrainerTargetDCSUnitName].Template.skill
self:T(TrainerTargetDCSUnitName )
local Client = self.DBClients[TrainerTargetDCSUnitName]
if Client then
local TrainerSourceUnit = UNIT:Find( TrainerSourceDCSUnit )
local TrainerTargetUnit = UNIT:Find( TrainerTargetDCSUnit )
if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then
local Message = MESSAGE:New(
string.format( "%s launched a %s",
TrainerSourceUnit:GetTypeName(),
TrainerWeaponName
) .. self:_AddRange( Client, TrainerWeapon ) .. self:_AddBearing( Client, TrainerWeapon ),"Launch Alert", 5, "ID" )
if self.AlertsToAll then
Message:ToAll()
else
Message:ToClient( Client )
end
end
local ClientID = Client:GetID()
local MissileData = {}
MissileData.TrainerSourceUnit = TrainerSourceUnit
MissileData.TrainerWeapon = TrainerWeapon
MissileData.TrainerTargetUnit = TrainerTargetUnit
MissileData.TrainerWeaponTypeName = TrainerWeapon:getTypeName()
MissileData.TrainerWeaponLaunched = true
table.insert( self.TrackingMissiles[ClientID].MissileData, MissileData )
--self:T( self.TrackingMissiles )
end
end
function MISSILETRAINER:_AddRange( Client, TrainerWeapon )
local RangeText = ""
if self.DetailsRangeOnOff then
local PositionMissile = TrainerWeapon:getPoint()
local PositionTarget = Client:GetPointVec3()
local Range = ( ( PositionMissile.x - PositionTarget.x )^2 +
( PositionMissile.y - PositionTarget.y )^2 +
( PositionMissile.z - PositionTarget.z )^2
) ^ 0.5 / 1000
RangeText = string.format( ", at %4.2fkm", Range )
end
return RangeText
end
function MISSILETRAINER:_AddBearing( Client, TrainerWeapon )
local BearingText = ""
if self.DetailsBearingOnOff then
local PositionMissile = TrainerWeapon:getPoint()
local PositionTarget = Client:GetPointVec3()
self:T2( { PositionTarget, PositionMissile })
local DirectionVector = { x = PositionMissile.x - PositionTarget.x, y = PositionMissile.y - PositionTarget.y, z = PositionMissile.z - PositionTarget.z }
local DirectionRadians = math.atan2( DirectionVector.z, DirectionVector.x )
--DirectionRadians = DirectionRadians + routines.getNorthCorrection( PositionTarget )
if DirectionRadians < 0 then
DirectionRadians = DirectionRadians + 2 * math.pi
end
local DirectionDegrees = DirectionRadians * 180 / math.pi
BearingText = string.format( ", %d degrees", DirectionDegrees )
end
return BearingText
end
function MISSILETRAINER:_TrackMissiles()
self:F2()
local ShowMessages = false
if self.MessagesOnOff and self.MessageLastTime + self.TrackingFrequency <= timer.getTime() then
self.MessageLastTime = timer.getTime()
ShowMessages = true
end
-- ALERTS PART
-- Loop for all Player Clients to check the alerts and deletion of missiles.
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
local Client = ClientData.Client
self:T2( { Client:GetName() } )
for MissileDataID, MissileData in pairs( ClientData.MissileData ) do
self:T3( MissileDataID )
local TrainerSourceUnit = MissileData.TrainerSourceUnit
local TrainerWeapon = MissileData.TrainerWeapon
local TrainerTargetUnit = MissileData.TrainerTargetUnit
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
local PositionMissile = TrainerWeapon:getPosition().p
local PositionTarget = Client:GetPointVec3()
local Distance = ( ( PositionMissile.x - PositionTarget.x )^2 +
( PositionMissile.y - PositionTarget.y )^2 +
( PositionMissile.z - PositionTarget.z )^2
) ^ 0.5 / 1000
if Distance <= self.Distance then
-- Hit alert
TrainerWeapon:destroy()
if self.MessagesOnOff == true and self.AlertsHitsOnOff == true then
self:T( "killed" )
local Message = MESSAGE:New(
string.format( "%s launched by %s killed %s",
TrainerWeapon:getTypeName(),
TrainerSourceUnit:GetTypeName(),
TrainerTargetUnit:GetPlayerName()
),"Hit Alert", 15, "ID" )
if self.AlertsToAll == true then
Message:ToAll()
else
Message:ToClient( Client )
end
MissileData = nil
table.remove( ClientData.MissileData, MissileDataID )
self:T(ClientData.MissileData)
end
end
else
if not ( TrainerWeapon and TrainerWeapon:isExist() ) then
if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then
-- Weapon does not exist anymore. Delete from Table
local Message = MESSAGE:New(
string.format( "%s launched by %s self destructed!",
TrainerWeaponTypeName,
TrainerSourceUnit:GetTypeName()
),"Tracking", 5, "ID" )
if self.AlertsToAll == true then
Message:ToAll()
else
Message:ToClient( Client )
end
end
MissileData = nil
table.remove( ClientData.MissileData, MissileDataID )
self:T( ClientData.MissileData )
end
end
end
end
if ShowMessages == true and self.MessagesOnOff == true and self.TrackingOnOff == true then -- Only do this when tracking information needs to be displayed.
-- TRACKING PART
-- For the current client, the missile range and bearing details are displayed To the Player Client.
-- For the other clients, the missile range and bearing details are displayed To the other Player Clients.
-- To achieve this, a cross loop is done for each Player Client <-> Other Player Client missile information.
-- Main Player Client loop
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
local Client = ClientData.Client
self:T2( { Client:GetName() } )
ClientData.MessageToClient = ""
ClientData.MessageToAll = ""
-- Other Players Client loop
for TrackingDataID, TrackingData in pairs( self.TrackingMissiles ) do
for MissileDataID, MissileData in pairs( TrackingData.MissileData ) do
self:T3( MissileDataID )
local TrainerSourceUnit = MissileData.TrainerSourceUnit
local TrainerWeapon = MissileData.TrainerWeapon
local TrainerTargetUnit = MissileData.TrainerTargetUnit
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
if ShowMessages == true then
local TrackingTo
TrackingTo = string.format( " -> %s",
TrainerWeaponTypeName
)
if ClientDataID == TrackingDataID then
if ClientData.MessageToClient == "" then
ClientData.MessageToClient = "Missiles to You:\n"
end
ClientData.MessageToClient = ClientData.MessageToClient .. TrackingTo .. self:_AddRange( ClientData.Client, TrainerWeapon ) .. self:_AddBearing( ClientData.Client, TrainerWeapon ) .. "\n"
else
if self.TrackingToAll == true then
if ClientData.MessageToAll == "" then
ClientData.MessageToAll = "Missiles to other Players:\n"
end
ClientData.MessageToAll = ClientData.MessageToAll .. TrackingTo .. self:_AddRange( ClientData.Client, TrainerWeapon ) .. self:_AddBearing( ClientData.Client, TrainerWeapon ) .. " ( " .. TrainerTargetUnit:GetPlayerName() .. " )\n"
end
end
end
end
end
end
-- Once the Player Client and the Other Player Client tracking messages are prepared, show them.
if ClientData.MessageToClient ~= "" or ClientData.MessageToAll ~= "" then
local Message = MESSAGE:New( ClientData.MessageToClient .. ClientData.MessageToAll, "Tracking", 1, "ID" ):ToClient( Client )
end
end
end
return true
end

View File

@ -231,25 +231,6 @@ function MISSION:AddGoalFunction( GoalFunction )
self.GoalFunction = GoalFunction
end
--- Show the briefing of the MISSION to the CLIENT.
-- @param CLIENT Client to show briefing to.
-- @return CLIENT
function MISSION:ShowBriefing( Client )
self:F( { Client.ClientName } )
if not Client.ClientBriefingShown then
Client.ClientBriefingShown = true
local Briefing = self.MissionBriefing
if Client.ClientBriefing then
Briefing = Briefing .. "\n" .. Client.ClientBriefing
end
Briefing = Briefing .. "\n (Press [LEFT ALT]+[B] to view the graphical documentation.)"
Client:Message( Briefing, 30, self.Name .. '/MissionBriefing', "Command: Mission Briefing" )
end
return Client
end
--- Register a new @{CLIENT} to participate within the mission.
-- @param CLIENT Client is the @{CLIENT} object. The object must have been instantiated with @{CLIENT:New}.
-- @return CLIENT
@ -474,7 +455,9 @@ function MISSIONSCHEDULER.Scheduler()
if Mission.GoalFunction ~= nil then
Mission.GoalFunction( Mission, Client )
end
_DATABASE:_AddMissionTaskScore( Client:GetClientGroupDCSUnit(), Mission.Name, 25 )
if MISSIONSCHEDULER.Scoring then
MISSIONSCHEDULER.Scoring:_AddMissionTaskScore( Client:GetClientGroupDCSUnit(), Mission.Name, 25 )
end
-- if not Mission:IsCompleted() then
-- end

View File

@ -31,7 +31,7 @@ function PICKUPTASK:New( CargoType, OnBoardSide )
self.CargoType = CargoType
self.GoalVerb = CargoType .. " " .. self.GoalVerb
self.OnBoardSide = OnBoardSide
self.IsLandingRequired = false -- required to decide whether the client needs to land or not
self.IsLandingRequired = true -- required to decide whether the client needs to land or not
self.IsSlingLoad = false -- Indicates whether the cargo is a sling load cargo
self.Stages = { STAGE_CARGO_INIT:New(), STAGE_CARGO_LOAD:New(), STAGEBRIEF:New(), STAGESTART:New(), STAGEROUTE:New(), STAGELANDING:New(), STAGELANDED:New(), STAGELOAD:New(), STAGEDONE:New() }
self.SetStage( self, 1 )

View File

@ -1524,6 +1524,47 @@ function routines.IsUnitInZones( TransportUnit, LandingZones )
end
end
function routines.IsUnitNearZonesRadius( TransportUnit, LandingZones, ZoneRadius )
--trace.f("", "routines.IsUnitInZones" )
local TransportZoneResult = nil
local TransportZonePos = nil
local TransportZone = nil
-- fill-up some local variables to support further calculations to determine location of units within the zone.
if TransportUnit then
local TransportUnitPos = TransportUnit:getPosition().p
if type( LandingZones ) == "table" then
for LandingZoneID, LandingZoneName in pairs( LandingZones ) do
TransportZone = trigger.misc.getZone( LandingZoneName )
if TransportZone then
TransportZonePos = {radius = TransportZone.radius, x = TransportZone.point.x, y = TransportZone.point.y, z = TransportZone.point.z}
if ((( TransportUnitPos.x - TransportZonePos.x)^2 + (TransportUnitPos.z - TransportZonePos.z)^2)^0.5 <= ZoneRadius ) then
TransportZoneResult = LandingZoneID
break
end
end
end
else
TransportZone = trigger.misc.getZone( LandingZones )
TransportZonePos = {radius = TransportZone.radius, x = TransportZone.point.x, y = TransportZone.point.y, z = TransportZone.point.z}
if ((( TransportUnitPos.x - TransportZonePos.x)^2 + (TransportUnitPos.z - TransportZonePos.z)^2)^0.5 <= ZoneRadius ) then
TransportZoneResult = 1
end
end
if TransportZoneResult then
--trace.i( "routines", "TransportZone:" .. TransportZoneResult )
else
--trace.i( "routines", "TransportZone:nil logic" )
end
return TransportZoneResult
else
--trace.i( "routines", "TransportZone:nil hard" )
return nil
end
end
function routines.IsStaticInZones( TransportStatic, LandingZones )
--trace.f()
@ -1696,7 +1737,7 @@ function routines.getGroupRoute(groupIdent, task) -- same as getGroupPoints bu
-- refactor to search by groupId and allow groupId and groupName as inputs
local gpId = groupIdent
if type(groupIdent) == 'string' and not tonumber(groupIdent) then
gpId = _DATABASE.Groups[groupIdent].groupId
gpId = _DATABASE.Templates.Groups[groupIdent].groupId
end
for coa_name, coa_data in pairs(env.mission.coalition) do

114
Moose/Scheduler.lua Normal file
View File

@ -0,0 +1,114 @@
--- Models time events calling event handing functions.
-- @module Scheduler
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
Include.File( "Cargo" )
Include.File( "Message" )
--- The SCHEDULER class
-- @type SCHEDULER
-- @extends Base#BASE
SCHEDULER = {
ClassName = "SCHEDULER",
}
--- SCHEDULER constructor.
-- @param #SCHEDULER self
-- @param #table TimeEventObject
-- @param #function TimeEventFunction
-- @param #table TimeEventFunctionArguments
-- @param #number StartSeconds
-- @param #number RepeatSecondsInterval
-- @param #number RandomizationFactor
-- @param #number StopSeconds
-- @return #SCHEDULER
function SCHEDULER:New( TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds )
local self = BASE:Inherit( self, BASE:New() )
self:F( { TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds } )
self.TimeEventObject = TimeEventObject
self.TimeEventFunction = TimeEventFunction
self.TimeEventFunctionArguments = TimeEventFunctionArguments
self.StartSeconds = StartSeconds
if RepeatSecondsInterval then
self.RepeatSecondsInterval = RepeatSecondsInterval
else
self.RepeatSecondsInterval = 0
end
if RandomizationFactor then
self.RandomizationFactor = RandomizationFactor
else
self.RandomizationFactor = 0
end
if StopSeconds then
self.StopSeconds = StopSeconds
end
self.Repeat = false
self.StartTime = timer.getTime()
self:Start()
return self
end
function SCHEDULER:Scheduler()
self:F( self.TimeEventFunctionArguments )
local ErrorHandler = function( errmsg )
env.info( "Error in SCHEDULER function:" .. errmsg )
env.info( debug.traceback() )
return errmsg
end
local Status, Result
if self.TimeEventObject then
Status, Result = xpcall( function() return self.TimeEventFunction( self.TimeEventObject, unpack( self.TimeEventFunctionArguments ) ) end, ErrorHandler )
else
Status, Result = xpcall( function() return self.TimeEventFunction( unpack( self.TimeEventFunctionArguments ) ) end, ErrorHandler )
end
self:T( { Status, Result } )
if Status and Status == true and Result and Result == true then
if self.Repeat and ( not self.StopSeconds or ( self.StopSeconds and timer.getTime() <= self.StartTime + self.StopSeconds ) ) then
timer.scheduleFunction(
self.Scheduler,
self,
timer.getTime() + self.RepeatSecondsInterval + math.random( - ( self.RandomizationFactor * self.RepeatSecondsInterval / 2 ), ( self.RandomizationFactor * self.RepeatSecondsInterval / 2 ) ) + 0.01
)
end
end
end
function SCHEDULER:Start()
self:F( self.TimeEventObject )
self.Repeat = true
timer.scheduleFunction( self.Scheduler, self, timer.getTime() + self.StartSeconds + .01 )
return self
end
function SCHEDULER:Stop()
self:F( self.TimeEventObject )
self.Repeat = false
end

View File

@ -197,7 +197,7 @@ end
function SCORING:_AddPlayerFromUnit( UnitData )
self:F( UnitData )
if UnitData:isExist() then
if UnitData and UnitData:isExist() then
local UnitName = UnitData:getName()
local PlayerName = UnitData:getPlayerName()
local UnitDesc = UnitData:getDesc()
@ -324,7 +324,7 @@ function SCORING:_EventOnHit( Event )
local InitUnitName = ""
local InitGroup = nil
local InitGroupName = ""
local InitPlayerName = "dummy"
local InitPlayerName = nil
local InitCoalition = nil
local InitCategory = nil

View File

@ -67,7 +67,7 @@ function SEAD:EventShot( Event )
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
local _targetMimgroupName = _targetMimgroup:getName()
local _targetMimcont= _targetMimgroup:getController()
local _targetskill = _DATABASE.Units[_targetMimname].Template.skill
local _targetskill = _DATABASE.Templates.Units[_targetMimname].Template.skill
self:T( self.SEADGroupPrefixes )
self:T( _targetMimgroupName )
local SEADGroupFound = false

758
Moose/Set.lua Normal file
View File

@ -0,0 +1,758 @@
--- Manage sets of units and groups.
--
-- @{#Set} class
-- ==================
-- Mission designers can use the SET class to build sets of units belonging to certain:
--
-- * Coalitions
-- * Categories
-- * Countries
-- * Unit types
-- * Starting with certain prefix strings.
--
-- This list will grow over time. Planned developments are to include filters and iterators.
-- Additional filters will be added around @{Zone#ZONEs}, Radiuses, Active players, ...
-- More iterators will be implemented in the near future ...
--
-- Administers the Initial Sets of the Mission Templates as defined within the Mission Editor.
--
-- SET construction methods:
-- =================================
-- Create a new SET object with the @{#SET.New} method:
--
-- * @{#SET.New}: Creates a new SET object.
--
--
-- SET filter criteria:
-- =========================
-- You can set filter criteria to define the set of units within the SET.
-- Filter criteria are defined by:
--
-- * @{#SET.FilterCoalitions}: Builds the SET with the units belonging to the coalition(s).
-- * @{#SET.FilterCategories}: Builds the SET with the units belonging to the category(ies).
-- * @{#SET.FilterTypes}: Builds the SET with the units belonging to the unit type(s).
-- * @{#SET.FilterCountries}: Builds the SET with the units belonging to the country(ies).
-- * @{#SET.FilterUnitPrefixes}: Builds the SET with the units starting with the same prefix string(s).
--
-- Once the filter criteria have been set for the SET, you can start filtering using:
--
-- * @{#SET.FilterStart}: Starts the filtering of the units within the SET.
--
-- Planned filter criteria within development are (so these are not yet available):
--
-- * @{#SET.FilterGroupPrefixes}: Builds the SET with the groups of the units starting with the same prefix string(s).
-- * @{#SET.FilterZones}: Builds the SET with the units within a @{Zone#ZONE}.
--
--
-- SET iterators:
-- ===================
-- Once the filters have been defined and the SET has been built, you can iterate the SET with the available iterator methods.
-- The iterator methods will walk the SET set, and call for each element within the set a function that you provide.
-- The following iterator methods are currently available within the SET:
--
-- * @{#SET.ForEachAliveUnit}: Calls a function for each alive unit it finds within the SET.
--
-- Planned iterators methods in development are (so these are not yet available):
--
-- * @{#SET.ForEachUnit}: Calls a function for each unit contained within the SET.
-- * @{#SET.ForEachGroup}: Calls a function for each group contained within the SET.
-- * @{#SET.ForEachUnitInZone}: Calls a function for each unit within a certain zone contained within the SET.
--
-- ====
-- @module Set
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
Include.File( "Menu" )
Include.File( "Group" )
Include.File( "Unit" )
Include.File( "Event" )
Include.File( "Client" )
--- SET class
-- @type SET
-- @extends Base#BASE
SET = {
ClassName = "SET",
Templates = {
Units = {},
Groups = {},
ClientsByName = {},
ClientsByID = {},
},
DCSUnits = {},
DCSUnitsAlive = {},
DCSGroups = {},
DCSGroupsAlive = {},
Units = {},
UnitsAlive = {},
Groups = {},
GroupsAlive = {},
NavPoints = {},
Statics = {},
Players = {},
PlayersAlive = {},
Clients = {},
ClientsAlive = {},
Filter = {
Coalitions = nil,
Categories = nil,
Types = nil,
Countries = nil,
UnitPrefixes = nil,
GroupPrefixes = nil,
},
FilterMeta = {
Coalitions = {
red = coalition.side.RED,
blue = coalition.side.BLUE,
neutral = coalition.side.NEUTRAL,
},
Categories = {
plane = Unit.Category.AIRPLANE,
helicopter = Unit.Category.HELICOPTER,
ground = Unit.Category.GROUND_UNIT,
ship = Unit.Category.SHIP,
structure = Unit.Category.STRUCTURE,
},
},
}
local _DATABASECoalition =
{
[1] = "Red",
[2] = "Blue",
}
local _DATABASECategory =
{
[Unit.Category.AIRPLANE] = "Plane",
[Unit.Category.HELICOPTER] = "Helicopter",
[Unit.Category.GROUND_UNIT] = "Vehicle",
[Unit.Category.SHIP] = "Ship",
[Unit.Category.STRUCTURE] = "Structure",
}
--- Creates a new SET object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
-- @param #SET self
-- @return #SET
-- @usage
-- -- Define a new SET Object. This DBObject will contain a reference to all Group and Unit Templates defined within the ME and the DCSRTE.
-- DBObject = SET:New()
function SET:New()
-- Inherits from BASE
local self = BASE:Inherit( self, BASE:New() )
_EVENTDISPATCHER:OnBirth( self._EventOnBirth, self )
_EVENTDISPATCHER:OnDead( self._EventOnDeadOrCrash, self )
_EVENTDISPATCHER:OnCrash( self._EventOnDeadOrCrash, self )
-- Add SET with registered clients and already alive players
-- Follow alive players and clients
_EVENTDISPATCHER:OnPlayerEnterUnit( self._EventOnPlayerEnterUnit, self )
_EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventOnPlayerLeaveUnit, self )
return self
end
--- Finds a Unit based on the Unit Name.
-- @param #SET self
-- @param #string UnitName
-- @return Unit#UNIT The found Unit.
function SET:FindUnit( UnitName )
local UnitFound = self.Units[UnitName]
return UnitFound
end
--- Finds a Unit based on the Unit Name.
-- @param #SET self
-- @param Unit#UNIT UnitToAdd
-- @return Unit#UNIT The added Unit.
function SET:AddUnit( UnitToAdd )
self.Units[UnitToAdd.UnitName] = UnitToAdd
return self.Units[UnitToAdd.UnitName]
end
--- Builds a set of units of coalitons.
-- Possible current coalitions are red, blue and neutral.
-- @param #SET self
-- @param #string Coalitions Can take the following values: "red", "blue", "neutral".
-- @return #SET self
function SET:FilterCoalitions( Coalitions )
if not self.Filter.Coalitions then
self.Filter.Coalitions = {}
end
if type( Coalitions ) ~= "table" then
Coalitions = { Coalitions }
end
for CoalitionID, Coalition in pairs( Coalitions ) do
self.Filter.Coalitions[Coalition] = Coalition
end
return self
end
--- Builds a set of units out of categories.
-- Possible current categories are plane, helicopter, ground, ship.
-- @param #SET self
-- @param #string Categories Can take the following values: "plane", "helicopter", "ground", "ship".
-- @return #SET self
function SET:FilterCategories( Categories )
if not self.Filter.Categories then
self.Filter.Categories = {}
end
if type( Categories ) ~= "table" then
Categories = { Categories }
end
for CategoryID, Category in pairs( Categories ) do
self.Filter.Categories[Category] = Category
end
return self
end
--- Builds a set of units of defined unit types.
-- Possible current types are those types known within DCS world.
-- @param #SET self
-- @param #string Types Can take those type strings known within DCS world.
-- @return #SET self
function SET:FilterTypes( Types )
if not self.Filter.Types then
self.Filter.Types = {}
end
if type( Types ) ~= "table" then
Types = { Types }
end
for TypeID, Type in pairs( Types ) do
self.Filter.Types[Type] = Type
end
return self
end
--- Builds a set of units of defined countries.
-- Possible current countries are those known within DCS world.
-- @param #SET self
-- @param #string Countries Can take those country strings known within DCS world.
-- @return #SET self
function SET:FilterCountries( Countries )
if not self.Filter.Countries then
self.Filter.Countries = {}
end
if type( Countries ) ~= "table" then
Countries = { Countries }
end
for CountryID, Country in pairs( Countries ) do
self.Filter.Countries[Country] = Country
end
return self
end
--- Builds a set of units of defined unit prefixes.
-- All the units starting with the given prefixes will be included within the set.
-- @param #SET self
-- @param #string Prefixes The prefix of which the unit name starts with.
-- @return #SET self
function SET:FilterUnitPrefixes( Prefixes )
if not self.Filter.UnitPrefixes then
self.Filter.UnitPrefixes = {}
end
if type( Prefixes ) ~= "table" then
Prefixes = { Prefixes }
end
for PrefixID, Prefix in pairs( Prefixes ) do
self.Filter.UnitPrefixes[Prefix] = Prefix
end
return self
end
--- Builds a set of units of defined group prefixes.
-- All the units starting with the given group prefixes will be included within the set.
-- @param #SET self
-- @param #string Prefixes The prefix of which the group name where the unit belongs to starts with.
-- @return #SET self
function SET:FilterGroupPrefixes( Prefixes )
if not self.Filter.GroupPrefixes then
self.Filter.GroupPrefixes = {}
end
if type( Prefixes ) ~= "table" then
Prefixes = { Prefixes }
end
for PrefixID, Prefix in pairs( Prefixes ) do
self.Filter.GroupPrefixes[Prefix] = Prefix
end
return self
end
--- Starts the filtering.
-- @param #SET self
-- @return #SET self
function SET:FilterStart()
if _DATABASE then
-- OK, we have a _DATABASE
-- Now use the different filters to build the set.
-- We first take ALL of the Units of the _DATABASE.
self:E( { "Adding Set Datapoints with filters" } )
for DCSUnitName, DCSUnit in pairs( _DATABASE.DCSUnits ) do
if self:_IsIncludeDCSUnit( DCSUnit ) then
self:E( { "Adding Unit:", DCSUnitName } )
self.DCSUnits[DCSUnitName] = _DATABASE.DCSUnits[DCSUnitName]
self.Units[DCSUnitName] = _DATABASE:FindUnit( DCSUnitName )
if _DATABASE.DCSUnitsAlive[DCSUnitName] then
self.DCSUnitsAlive[DCSUnitName] = _DATABASE.DCSUnitsAlive[DCSUnitName]
self.UnitsAlive[DCSUnitName] = _DATABASE.UnitsAlive[DCSUnitName]
end
end
end
for DCSGroupName, DCSGroup in pairs( _DATABASE.DCSGroups ) do
--if self:_IsIncludeDCSGroup( DCSGroup ) then
self:E( { "Adding Group:", DCSGroupName } )
self.DCSGroups[DCSGroupName] = _DATABASE.DCSGroups[DCSGroupName]
self.Groups[DCSGroupName] = _DATABASE:FindGroups( DCSGroupName )
--end
if _DATABASE.DCSGroupsAlive[DCSGroupName] then
self.DCSGroupsAlive[DCSGroupName] = _DATABASE.DCSGroupsAlive[DCSGroupName]
self.GroupsAlive[DCSGroupName] = _DATABASE.GroupsAlive[DCSGroupName]
end
end
for DCSUnitName, Client in pairs( _DATABASE.CLIENTS ) do
self:E( { "Adding Client for Unit:", DCSUnitName } )
self.Clients[DCSUnitName] = _DATABASE.Clients[DCSUnitName]
end
else
self:E( "There is a structural error in MOOSE. No _DATABASE has been defined! Cannot build this custom SET." )
end
return self
end
--- Private method that registers all alive players in the mission.
-- @param #SET self
-- @return #SET self
function SET:_RegisterPlayers()
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) }
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
for UnitId, UnitData in pairs( CoalitionData ) do
self:T3( { "UnitData:", UnitData } )
if UnitData and UnitData:isExist() then
local UnitName = UnitData:getName()
if not self.PlayersAlive[UnitName] then
self:E( { "Add player for unit:", UnitName, UnitData:getPlayerName() } )
self.PlayersAlive[UnitName] = UnitData:getPlayerName()
end
end
end
end
return self
end
--- Private method that registers all datapoints within in the mission.
-- @param #SET self
-- @return #SET self
function SET:_RegisterDatabase()
local CoalitionsData = { AlivePlayersRed = coalition.getGroups( coalition.side.RED ), AlivePlayersBlue = coalition.getGroups( coalition.side.BLUE ) }
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
for DCSGroupId, DCSGroup in pairs( CoalitionData ) do
if DCSGroup:isExist() then
local DCSGroupName = DCSGroup:getName()
self:E( { "Register Group:", DCSGroup, DCSGroupName } )
self.DCSGroups[DCSGroupName] = DCSGroup
self.Groups[DCSGroupName] = GROUP:New( DCSGroup )
if self:_IsAliveDCSGroup(DCSGroup) then
self:E( { "Register Alive Group:", DCSGroup, DCSGroupName } )
self.DCSGroupsAlive[DCSGroupName] = DCSGroup
self.GroupsAlive[DCSGroupName] = self.Groups[DCSGroupName]
end
for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do
local DCSUnitName = DCSUnit:getName()
self:E( { "Register Unit:", DCSUnit, DCSUnitName } )
self.DCSUnits[DCSUnitName] = DCSUnit
self:AddUnit( UNIT:Find( DCSUnit ) )
--self.Units[DCSUnitName] = UNIT:Register( DCSUnit )
if self:_IsAliveDCSUnit(DCSUnit) then
self:E( { "Register Alive Unit:", DCSUnit, DCSUnitName } )
self.DCSUnitsAlive[DCSUnitName] = DCSUnit
self.UnitsAlive[DCSUnitName] = self.Units[DCSUnitName]
end
end
else
self:E( "Group does not exist: " .. DCSGroup )
end
for ClientName, ClientTemplate in pairs( self.Templates.ClientsByName ) do
self.Clients[ClientName] = CLIENT:Find( ClientName )
end
end
end
return self
end
--- Events
--- Handles the OnBirth event for the alive units set.
-- @param #SET self
-- @param Event#EVENTDATA Event
function SET:_EventOnBirth( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then
self.DCSUnits[Event.IniDCSUnitName] = Event.IniDCSUnit
self.DCSUnitsAlive[Event.IniDCSUnitName] = Event.IniDCSUnit
self:AddUnit( UNIT:Register( Event.IniDCSUnit ) )
--self.Units[Event.IniDCSUnitName] = UNIT:Register( Event.IniDCSUnit )
--if not self.DCSGroups[Event.IniDCSGroupName] then
-- self.DCSGroups[Event.IniDCSGroupName] = Event.IniDCSGroupName
-- self.DCSGroupsAlive[Event.IniDCSGroupName] = Event.IniDCSGroupName
-- self.Groups[Event.IniDCSGroupName] = GROUP:New( Event.IniDCSGroup )
--end
self:_EventOnPlayerEnterUnit( Event )
end
end
end
--- Handles the OnDead or OnCrash event for alive units set.
-- @param #SET self
-- @param Event#EVENTDATA Event
function SET:_EventOnDeadOrCrash( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self.DCSUnitsAlive[Event.IniDCSUnitName] then
self.DCSUnits[Event.IniDCSUnitName] = nil
self.DCSUnitsAlive[Event.IniDCSUnitName] = nil
end
end
end
--- Handles the OnPlayerEnterUnit event to fill the active players table (with the unit filter applied).
-- @param #SET self
-- @param Event#EVENTDATA Event
function SET:_EventOnPlayerEnterUnit( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then
if not self.PlayersAlive[Event.IniDCSUnitName] then
self:E( { "Add player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } )
self.PlayersAlive[Event.IniDCSUnitName] = Event.IniDCSUnit:getPlayerName()
self.ClientsAlive[Event.IniDCSUnitName] = _DATABASE.Clients[ Event.IniDCSUnitName ]
end
end
end
end
--- Handles the OnPlayerLeaveUnit event to clean the active players table.
-- @param #SET self
-- @param Event#EVENTDATA Event
function SET:_EventOnPlayerLeaveUnit( Event )
self:F( { Event } )
if Event.IniDCSUnit then
if self:_IsIncludeDCSUnit( Event.IniDCSUnit ) then
if self.PlayersAlive[Event.IniDCSUnitName] then
self:E( { "Cleaning player for unit:", Event.IniDCSUnitName, Event.IniDCSUnit:getPlayerName() } )
self.PlayersAlive[Event.IniDCSUnitName] = nil
self.ClientsAlive[Event.IniDCSUnitName] = nil
end
end
end
end
--- Iterators
--- Interate the SET and call an interator function for the given set, providing the Object for each element within the set and optional parameters.
-- @param #SET self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the SET.
-- @return #SET self
function SET:ForEach( IteratorFunction, arg, Set )
self:F( arg )
local function CoRoutine()
local Count = 0
for ObjectID, Object in pairs( Set ) do
self:T2( Object )
IteratorFunction( Object, unpack( arg ) )
Count = Count + 1
if Count % 10 == 0 then
coroutine.yield( false )
end
end
return true
end
local co = coroutine.create( CoRoutine )
local function Schedule()
local status, res = coroutine.resume( co )
self:T( { status, res } )
if status == false then
error( res )
end
if res == false then
return true -- resume next time the loop
end
return false
end
local Scheduler = SCHEDULER:New( self, Schedule, {}, 0.001, 0.001, 0 )
return self
end
--- Interate the SET and call an interator function for each **alive** unit, providing the Unit and optional parameters.
-- @param #SET self
-- @param #function IteratorFunction The function that will be called when there is an alive unit in the SET. The function needs to accept a UNIT parameter.
-- @return #SET self
function SET:ForEachDCSUnitAlive( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.DCSUnitsAlive )
return self
end
--- Interate the SET and call an interator function for each **alive** player, providing the Unit of the player and optional parameters.
-- @param #SET self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a UNIT parameter.
-- @return #SET self
function SET:ForEachPlayer( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.PlayersAlive )
return self
end
--- Interate the SET and call an interator function for each client, providing the Client to the function and optional parameters.
-- @param #SET self
-- @param #function IteratorFunction The function that will be called when there is an alive player in the SET. The function needs to accept a CLIENT parameter.
-- @return #SET self
function SET:ForEachClient( IteratorFunction, ... )
self:F( arg )
self:ForEach( IteratorFunction, arg, self.Clients )
return self
end
function SET:ScanEnvironment()
self:F()
self.Navpoints = {}
self.Units = {}
--Build routines.db.units and self.Navpoints
for coa_name, coa_data in pairs(env.mission.coalition) do
if (coa_name == 'red' or coa_name == 'blue') and type(coa_data) == 'table' then
--self.Units[coa_name] = {}
----------------------------------------------
-- build nav points DB
self.Navpoints[coa_name] = {}
if coa_data.nav_points then --navpoints
for nav_ind, nav_data in pairs(coa_data.nav_points) do
if type(nav_data) == 'table' then
self.Navpoints[coa_name][nav_ind] = routines.utils.deepCopy(nav_data)
self.Navpoints[coa_name][nav_ind]['name'] = nav_data.callsignStr -- name is a little bit more self-explanatory.
self.Navpoints[coa_name][nav_ind]['point'] = {} -- point is used by SSE, support it.
self.Navpoints[coa_name][nav_ind]['point']['x'] = nav_data.x
self.Navpoints[coa_name][nav_ind]['point']['y'] = 0
self.Navpoints[coa_name][nav_ind]['point']['z'] = nav_data.y
end
end
end
-------------------------------------------------
if coa_data.country then --there is a country table
for cntry_id, cntry_data in pairs(coa_data.country) do
local countryName = string.lower(cntry_data.name)
--self.Units[coa_name][countryName] = {}
--self.Units[coa_name][countryName]["countryId"] = cntry_data.id
if type(cntry_data) == 'table' then --just making sure
for obj_type_name, obj_type_data in pairs(cntry_data) do
if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then --should be an unncessary check
local category = obj_type_name
if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then --there's a group!
--self.Units[coa_name][countryName][category] = {}
for group_num, GroupTemplate in pairs(obj_type_data.group) do
if GroupTemplate and GroupTemplate.units and type(GroupTemplate.units) == 'table' then --making sure again- this is a valid group
self:_RegisterGroup( GroupTemplate )
end --if GroupTemplate and GroupTemplate.units then
end --for group_num, GroupTemplate in pairs(obj_type_data.group) do
end --if ((type(obj_type_data) == 'table') and obj_type_data.group and (type(obj_type_data.group) == 'table') and (#obj_type_data.group > 0)) then
end --if obj_type_name == "helicopter" or obj_type_name == "ship" or obj_type_name == "plane" or obj_type_name == "vehicle" or obj_type_name == "static" then
end --for obj_type_name, obj_type_data in pairs(cntry_data) do
end --if type(cntry_data) == 'table' then
end --for cntry_id, cntry_data in pairs(coa_data.country) do
end --if coa_data.country then --there is a country table
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
end --for coa_name, coa_data in pairs(mission.coalition) do
self:_RegisterDatabase()
self:_RegisterPlayers()
return self
end
---
-- @param #SET self
-- @param DCSUnit#Unit DCSUnit
-- @return #SET self
function SET:_IsIncludeDCSUnit( DCSUnit )
self:F( DCSUnit )
local DCSUnitInclude = true
if self.Filter.Coalitions then
local DCSUnitCoalition = false
for CoalitionID, CoalitionName in pairs( self.Filter.Coalitions ) do
self:T( { "Coalition:", DCSUnit:getCoalition(), self.FilterMeta.Coalitions[CoalitionName], CoalitionName } )
if self.FilterMeta.Coalitions[CoalitionName] and self.FilterMeta.Coalitions[CoalitionName] == DCSUnit:getCoalition() then
DCSUnitCoalition = true
end
end
DCSUnitInclude = DCSUnitInclude and DCSUnitCoalition
end
if self.Filter.Categories then
local DCSUnitCategory = false
for CategoryID, CategoryName in pairs( self.Filter.Categories ) do
self:T( { "Category:", DCSUnit:getDesc().category, self.FilterMeta.Categories[CategoryName], CategoryName } )
if self.FilterMeta.Categories[CategoryName] and self.FilterMeta.Categories[CategoryName] == DCSUnit:getDesc().category then
DCSUnitCategory = true
end
end
DCSUnitInclude = DCSUnitInclude and DCSUnitCategory
end
if self.Filter.Types then
local DCSUnitType = false
for TypeID, TypeName in pairs( self.Filter.Types ) do
self:T( { "Type:", DCSUnit:getTypeName(), TypeName } )
if TypeName == DCSUnit:getTypeName() then
DCSUnitType = true
end
end
DCSUnitInclude = DCSUnitInclude and DCSUnitType
end
if self.Filter.Countries then
local DCSUnitCountry = false
for CountryID, CountryName in pairs( self.Filter.Countries ) do
self:T( { "Country:", DCSUnit:getCountry(), CountryName } )
if country.id[CountryName] == DCSUnit:getCountry() then
DCSUnitCountry = true
end
end
DCSUnitInclude = DCSUnitInclude and DCSUnitCountry
end
if self.Filter.UnitPrefixes then
local DCSUnitPrefix = false
for UnitPrefixId, UnitPrefix in pairs( self.Filter.UnitPrefixes ) do
self:T( { "Unit Prefix:", string.find( DCSUnit:getName(), UnitPrefix, 1 ), UnitPrefix } )
if string.find( DCSUnit:getName(), UnitPrefix, 1 ) then
DCSUnitPrefix = true
end
end
DCSUnitInclude = DCSUnitInclude and DCSUnitPrefix
end
self:T( DCSUnitInclude )
return DCSUnitInclude
end
---
-- @param #SET self
-- @param DCSUnit#Unit DCSUnit
-- @return #SET self
function SET:_IsAliveDCSUnit( DCSUnit )
self:F( DCSUnit )
local DCSUnitAlive = false
if DCSUnit and DCSUnit:isExist() and DCSUnit:isActive() then
if self.DCSUnits[DCSUnit:getName()] then
DCSUnitAlive = true
end
end
self:T( DCSUnitAlive )
return DCSUnitAlive
end
---
-- @param #SET self
-- @param DCSGroup#Group DCSGroup
-- @return #SET self
function SET:_IsAliveDCSGroup( DCSGroup )
self:F( DCSGroup )
local DCSGroupAlive = false
if DCSGroup and DCSGroup:isExist() then
if self.DCSGroups[DCSGroup:getName()] then
DCSGroupAlive = true
end
end
self:T( DCSGroupAlive )
return DCSGroupAlive
end
--- Traces the current SET contents in the log ... (for debug reasons).
-- @param #SET self
-- @return #SET self
function SET:TraceDatabase()
self:F()
self:T( { "DCSUnits:", self.DCSUnits } )
self:T( { "DCSUnitsAlive:", self.DCSUnitsAlive } )
end

View File

@ -43,7 +43,7 @@
-- * @{#SPAWN.RandomizeTemplate}: Randomize the group templates so that when a new group is spawned, a random group template is selected from one of the templates defined.
-- * @{#SPAWN.Uncontrolled}: Spawn plane groups uncontrolled.
-- * @{#SPAWN.Array}: Make groups visible before they are actually activated, and order these groups like a batallion in an array.
-- * @{#SPAWN.Repeat}: Re-spawn groups when they land at the home base. Similar functions are @{#SPAWN.RepeatOnLanding} and @{#SPAWN.RepeatOnEngineShutDown}.
-- * @{#SPAWN.InitRepeat}: Re-spawn groups when they land at the home base. Similar functions are @{#SPAWN.InitRepeatOnLanding} and @{#SPAWN.InitRepeatOnEngineShutDown}.
--
-- SPAWN spawning methods:
-- =======================
@ -80,6 +80,7 @@ Include.File( "Database" )
Include.File( "Group" )
Include.File( "Zone" )
Include.File( "Event" )
Include.File( "Scheduler" )
--- SPAWN Class
-- @type SPAWN
@ -115,7 +116,7 @@ function SPAWN:New( SpawnTemplatePrefix )
self.AliveUnits = 0 -- Contains the counter how many units are currently alive
self.SpawnIsScheduled = false -- Reflects if the spawning for this SpawnTemplatePrefix is going to be scheduled or not.
self.SpawnTemplate = self._GetTemplate( self, SpawnTemplatePrefix ) -- Contains the template structure for a Group Spawn from the Mission Editor. Note that this group must have lateActivation always on!!!
self.SpawnRepeat = false -- Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.
self.Repeat = false -- Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.
self.UnControlled = false -- When working in UnControlled mode, all planes are Spawned in UnControlled mode before the scheduler starts.
self.SpawnMaxUnitsAlive = 0 -- The maximum amount of groups that can be alive of SpawnTemplatePrefix at the same time.
self.SpawnMaxGroups = 0 -- The maximum amount of groups that can be spawned.
@ -152,7 +153,7 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
self.AliveUnits = 0 -- Contains the counter how many units are currently alive
self.SpawnIsScheduled = false -- Reflects if the spawning for this SpawnTemplatePrefix is going to be scheduled or not.
self.SpawnTemplate = self._GetTemplate( self, SpawnTemplatePrefix ) -- Contains the template structure for a Group Spawn from the Mission Editor. Note that this group must have lateActivation always on!!!
self.SpawnRepeat = false -- Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.
self.Repeat = false -- Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.
self.UnControlled = false -- When working in UnControlled mode, all planes are Spawned in UnControlled mode before the scheduler starts.
self.SpawnMaxUnitsAlive = 0 -- The maximum amount of groups that can be alive of SpawnTemplatePrefix at the same time.
self.SpawnMaxGroups = 0 -- The maximum amount of groups that can be spawned.
@ -274,36 +275,37 @@ end
-- -- RU Su-34 - AI Ship Attack
-- -- Re-SPAWN the Group(s) after each landing and Engine Shut-Down automatically.
-- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()
function SPAWN:Repeat()
function SPAWN:InitRepeat()
self:F( { self.SpawnTemplatePrefix, self.SpawnIndex } )
self.SpawnRepeat = true
self.Repeat = true
self.RepeatOnEngineShutDown = false
self.RepeatOnLanding = true
return self
end
--- Same as the @{Repeat) method.
-- @return SPAWN
-- @see Repeat
function SPAWN:RepeatOnLanding()
--- Respawn group after landing.
-- @param #SPAWN self
-- @return #SPAWN self
function SPAWN:InitRepeatOnLanding()
self:F( { self.SpawnTemplatePrefix } )
self:Repeat()
self:InitRepeat()
self.RepeatOnEngineShutDown = false
self.RepeatOnLanding = true
return self
end
--- Same as the @{#SPAWN.Repeat) method, but now the Group will respawn after its engines have shut down.
-- @return SPAWN
function SPAWN:RepeatOnEngineShutDown()
--- Respawn after landing when its engines have shut down.
-- @param #SPAWN self
-- @return #SPAWN self
function SPAWN:InitRepeatOnEngineShutDown()
self:F( { self.SpawnTemplatePrefix } )
self:Repeat()
self:InitRepeat()
self.RepeatOnEngineShutDown = true
self.RepeatOnLanding = false
@ -322,8 +324,8 @@ function SPAWN:CleanUp( SpawnCleanUpInterval )
self.SpawnCleanUpInterval = SpawnCleanUpInterval
self.SpawnCleanUpTimeStamps = {}
self.CleanUpFunction = routines.scheduleFunction( self._SpawnCleanUpScheduler, { self }, timer.getTime() + 1, SpawnCleanUpInterval )
--self.CleanUpFunction = routines.scheduleFunction( self._SpawnCleanUpScheduler, { self }, timer.getTime() + 1, SpawnCleanUpInterval )
self.CleanUpScheduler = SCHEDULER:New( self, self._SpawnCleanUpScheduler, {}, 1, SpawnCleanUpInterval, 0.2 )
return self
end
@ -378,10 +380,8 @@ function SPAWN:Array( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
_EVENTDISPATCHER:OnCrashForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self )
_EVENTDISPATCHER:OnDeadForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnDeadOrCrash, self )
if self.SpawnRepeat then
if self.Repeat then
_EVENTDISPATCHER:OnTakeOffForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnTakeOff, self )
end
if self.RepeatOnLanding then
_EVENTDISPATCHER:OnLandForTemplate( self.SpawnGroups[SpawnGroupID].SpawnTemplate, self._OnLand, self )
end
if self.RepeatOnEngineShutDown then
@ -450,15 +450,15 @@ function SPAWN:SpawnWithIndex( SpawnIndex )
_EVENTDISPATCHER:OnCrashForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self )
_EVENTDISPATCHER:OnDeadForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnDeadOrCrash, self )
if self.SpawnRepeat then
if self.Repeat then
_EVENTDISPATCHER:OnTakeOffForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnTakeOff, self )
end
if self.RepeatOnLanding then
_EVENTDISPATCHER:OnLandForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnLand, self )
end
if self.RepeatOnEngineShutDown then
_EVENTDISPATCHER:OnEngineShutDownForTemplate( self.SpawnGroups[self.SpawnIndex].SpawnTemplate, self._OnEngineShutDown, self )
end
self:T( self.SpawnGroups[self.SpawnIndex].SpawnTemplate )
self.SpawnGroups[self.SpawnIndex].Group = _DATABASE:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate )
@ -467,7 +467,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex )
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
--if self.Repeat then
-- _DATABASE:SetStatusGroup( SpawnTemplate.name, "ReSpawn" )
--end
end
@ -500,23 +500,29 @@ end
function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation )
self:F( { SpawnTime, SpawnTimeVariation } )
self.SpawnCurrentTimer = 0 -- The internal timer counter to trigger a scheduled spawning of SpawnTemplatePrefix.
self.SpawnSetTimer = 0 -- The internal timer value when a scheduled spawning of SpawnTemplatePrefix occurs.
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
self:SpawnScheduleStart()
self.SpawnScheduler = SCHEDULER:New( self, self._Scheduler, {}, 1, SpawnTime, SpawnTimeVariation )
end
self:T( { self.SpawnLowTimer, self.SpawnHighTimer } )
return self
end
--- Will re-start the spawning scheduler.
-- Note: This function is only required to be called when the schedule was stopped.
function SPAWN:SpawnScheduleStart()
self:F( { self.SpawnTemplatePrefix } )
self.SpawnScheduler:Start()
end
--- Will stop the scheduled spawning scheduler.
function SPAWN:SpawnScheduleStop()
self:F( { self.SpawnTemplatePrefix } )
self.SpawnScheduler:Stop()
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.
@ -538,30 +544,6 @@ end
--- Will start the spawning scheduler.
-- Note: This function is called automatically when @{#SPAWN.Scheduled} is called.
function SPAWN:SpawnScheduleStart()
self:F( { self.SpawnTemplatePrefix } )
--local ClientUnit = #AlivePlayerUnits()
self.AliveFactor = 10 -- ( 10 - ClientUnit ) / 10
if self.SpawnIsScheduled == false then
self.SpawnIsScheduled = true
self.SpawnInit = true
self.SpawnSetTimer = math.random( self.SpawnLowTimer * self.AliveFactor / 10 , self.SpawnHighTimer * self.AliveFactor / 10 )
self.SpawnFunction = routines.scheduleFunction( self._Scheduler, { self }, timer.getTime() + 1, 1 )
end
end
--- Will stop the scheduled spawning scheduler.
function SPAWN:SpawnScheduleStop()
self:F( { self.SpawnTemplatePrefix } )
self.SpawnIsScheduled = false
end
--- Will spawn a group from a hosting unit. This function is mostly advisable to be used if you want to simulate spawning from air units, like helicopters, which are dropping infantry into a defined Landing Zone.
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
@ -590,6 +572,9 @@ function SPAWN:SpawnFromUnit( HostUnit, OuterRadius, InnerRadius, SpawnIndex )
if SpawnTemplate then
local UnitPoint = HostUnit:GetPointVec2()
self:T( { "Current point of ", self.SpawnTemplatePrefix, UnitPoint } )
--for PointID, Point in pairs( SpawnTemplate.route.points ) do
--Point.x = UnitPoint.x
--Point.y = UnitPoint.y
@ -597,9 +582,6 @@ function SPAWN:SpawnFromUnit( HostUnit, OuterRadius, InnerRadius, SpawnIndex )
--Point.alt_type = nil
--end
SpawnTemplate.route.points = nil
SpawnTemplate.route.points = {}
SpawnTemplate.route.points[1] = {}
SpawnTemplate.route.points[1].x = UnitPoint.x
SpawnTemplate.route.points[1].y = UnitPoint.y
@ -680,8 +662,9 @@ function SPAWN:SpawnInZone( Zone, ZoneRandomize, SpawnIndex )
-- Apply SpawnFormation
for UnitID = 1, #SpawnTemplate.units do
SpawnTemplate.units[UnitID].x = ZonePoint.x
SpawnTemplate.units[UnitID].y = ZonePoint.y
local ZonePointUnit = Zone:GetRandomPointVec2()
SpawnTemplate.units[UnitID].x = ZonePointUnit.x
SpawnTemplate.units[UnitID].y = ZonePointUnit.y
self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
end
@ -910,7 +893,6 @@ function SPAWN:_InitializeSpawnGroups( SpawnIndex )
self.SpawnGroups[SpawnIndex].Visible = false
self.SpawnGroups[SpawnIndex].Spawned = false
self.SpawnGroups[SpawnIndex].UnControlled = false
self.SpawnGroups[SpawnIndex].Spawned = false
self.SpawnGroups[SpawnIndex].SpawnTime = 0
self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix = self.SpawnTemplatePrefix
@ -964,12 +946,15 @@ end
--- Gets the Group Template from the ME environment definition.
-- This method used the @{DATABASE} object, which contains ALL initial and new spawned object in MOOSE.
-- @param #SPAWN self
-- @param #string SpawnTemplatePrefix
-- @return @SPAWN self
function SPAWN:_GetTemplate( SpawnTemplatePrefix )
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnTemplatePrefix } )
local SpawnTemplate = nil
SpawnTemplate = routines.utils.deepCopy( _DATABASE.Groups[SpawnTemplatePrefix].Template )
SpawnTemplate = routines.utils.deepCopy( _DATABASE.Templates.Groups[SpawnTemplatePrefix].Template )
if SpawnTemplate == nil then
error( 'No Template returned for SpawnTemplatePrefix = ' .. SpawnTemplatePrefix )
@ -984,6 +969,10 @@ function SPAWN:_GetTemplate( SpawnTemplatePrefix )
end
--- Prepares the new Group Template.
-- @param #SPAWN self
-- @param #string SpawnTemplatePrefix
-- @param #number SpawnIndex
-- @return #SPAWN self
function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex )
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
@ -994,6 +983,7 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex )
SpawnTemplate.lateActivation = false
if SpawnTemplate.SpawnCategoryID == Group.Category.GROUND then
self:T( "For ground units, visible needs to be false..." )
SpawnTemplate.visible = false
end
@ -1013,7 +1003,7 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex )
end
--- Internal function randomizing the routes.
--- Private method randomizing the routes.
-- @param #SPAWN self
-- @param #number SpawnIndex The index of the group to be spawned.
-- @return #SPAWN
@ -1037,7 +1027,10 @@ function SPAWN:_RandomizeRoute( SpawnIndex )
return self
end
--- Private method that randomizes the template of the group.
-- @param #SPAWN self
-- @param #number SpawnIndex
-- @return #SPAWN self
function SPAWN:_RandomizeTemplate( SpawnIndex )
self:F( { self.SpawnTemplatePrefix, SpawnIndex } )
@ -1047,6 +1040,7 @@ function SPAWN:_RandomizeTemplate( SpawnIndex )
self.SpawnGroups[SpawnIndex].SpawnTemplate.route = routines.utils.deepCopy( self.SpawnTemplate.route )
self.SpawnGroups[SpawnIndex].SpawnTemplate.x = self.SpawnTemplate.x
self.SpawnGroups[SpawnIndex].SpawnTemplate.y = self.SpawnTemplate.y
self.SpawnGroups[SpawnIndex].SpawnTemplate.start_time = self.SpawnTemplate.start_time
for UnitID = 1, #self.SpawnGroups[SpawnIndex].SpawnTemplate.units do
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].heading = self.SpawnTemplate.units[1].heading
end
@ -1229,19 +1223,10 @@ end
function SPAWN:_Scheduler()
self:F( { "_Scheduler", self.SpawnTemplatePrefix, self.SpawnAliasPrefix, self.SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxUnitsAlive } )
if self.SpawnInit or self.SpawnCurrentTimer == self.SpawnSetTimer then
-- Validate if there are still groups left in the batch...
self:Spawn()
self.SpawnInit = false
if self.SpawnIsScheduled == true then
--local ClientUnit = #AlivePlayerUnits()
self.AliveFactor = 1 -- ( 10 - ClientUnit ) / 10
self.SpawnCurrentTimer = 0
self.SpawnSetTimer = math.random( self.SpawnLowTimer * self.AliveFactor , self.SpawnHighTimer * self.AliveFactor )
end
else
self.SpawnCurrentTimer = self.SpawnCurrentTimer + 1
end
-- Validate if there are still groups left in the batch...
self:Spawn()
return true
end
function SPAWN:_SpawnCleanUpScheduler()
@ -1273,4 +1258,6 @@ function SPAWN:_SpawnCleanUpScheduler()
end
return true -- Repeat
end

View File

@ -36,7 +36,7 @@ end
function STAGE:Execute( Mission, Client, Task )
local Valid = true
return Valid
end
@ -46,7 +46,7 @@ end
function STAGE:Validate( Mission, Client, Task )
local Valid = true
return Valid
end
@ -69,7 +69,7 @@ end
function STAGEBRIEF:Execute( Mission, Client, Task )
local Valid = BASE:Inherited(self):Execute( Mission, Client, Task )
self:F()
Mission:ShowBriefing( Client )
Client:ShowBriefing()
self.StageBriefingTime = timer.getTime()
return Valid
end
@ -255,7 +255,7 @@ function STAGEROUTE:Validate( Mission, Client, Task )
-- check if the Client is in the landing zone
self:T( Task.LandingZones.LandingZoneNames )
Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupDCSUnit(), Task.LandingZones.LandingZoneNames )
Task.CurrentLandingZoneName = routines.IsUnitNearZonesRadius( Client:GetClientGroupDCSUnit(), Task.LandingZones.LandingZoneNames, 500 )
if Task.CurrentLandingZoneName then
@ -268,9 +268,11 @@ function STAGEROUTE:Validate( Mission, Client, Task )
end
end
self:T( 1 )
return 1
end
self:T( 0 )
return 0
end
@ -345,8 +347,17 @@ function STAGELANDING:Execute( Mission, Client, Task )
else
HostMessage = "Use the Radio menu and F6 to find the cargo, then fly or land near the cargo and " .. Task.TEXT[1] .. " " .. Task.CargoNames .. "."
end
local Host = "Command"
if Task.HostUnitName then
Host = Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")"
else
if Client:IsMultiSeated() then
Host = "Co-Pilot"
end
end
Client:Message( HostMessage, self.MSG.TIME, Mission.Name .. "/STAGELANDING.EXEC." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")", 10 )
Client:Message( HostMessage, self.MSG.TIME, Mission.Name .. "/STAGELANDING.EXEC." .. Host, Host, 10 )
end
end
@ -354,7 +365,7 @@ end
function STAGELANDING:Validate( Mission, Client, Task )
self:F()
Task.CurrentLandingZoneName = routines.IsUnitInZones( Client:GetClientGroupDCSUnit(), Task.LandingZones.LandingZoneNames )
Task.CurrentLandingZoneName = routines.IsUnitNearZonesRadius( Client:GetClientGroupDCSUnit(), Task.LandingZones.LandingZoneNames, 500 )
if Task.CurrentLandingZoneName then
-- Client is in de landing zone.
@ -377,14 +388,34 @@ function STAGELANDING:Validate( Mission, Client, Task )
end
Task.Signalled = false
Task:RemoveCargoMenus( Client )
self:T( -1 )
return -1
end
if Task.IsLandingRequired and Client:GetClientGroupDCSUnit():inAir() then
return 0
end
local DCSUnitVelocityVec3 = Client:GetClientGroupDCSUnit():getVelocity()
local DCSUnitVelocity = ( DCSUnitVelocityVec3.x ^2 + DCSUnitVelocityVec3.y ^2 + DCSUnitVelocityVec3.z ^2 ) ^ 0.5
local DCSUnitPointVec3 = Client:GetClientGroupDCSUnit():getPoint()
local LandHeight = land.getHeight( { x = DCSUnitPointVec3.x, y = DCSUnitPointVec3.z } )
local DCSUnitHeight = DCSUnitPointVec3.y - LandHeight
self:T( { Task.IsLandingRequired, Client:GetClientGroupDCSUnit():inAir() } )
if Task.IsLandingRequired and not Client:GetClientGroupDCSUnit():inAir() then
self:T( 1 )
Task.IsInAirTestRequired = true
return 1
end
return 1
self:T( { DCSUnitVelocity, DCSUnitHeight, LandHeight, Task.CurrentCargoZone.SignalHeight } )
if Task.IsLandingRequired and DCSUnitVelocity <= 0.05 and DCSUnitHeight <= Task.CurrentCargoZone.SignalHeight then
self:T( 1 )
Task.IsInAirTestRequired = false
return 1
end
self:T( 0 )
return 0
end
STAGELANDED = {
@ -405,9 +436,20 @@ function STAGELANDED:Execute( Mission, Client, Task )
self:F()
if Task.IsLandingRequired then
Client:Message( 'You have landed within the landing zone. Use the radio menu (F10) to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType .. '.',
self.MSG.TIME, Mission.Name .. "/STAGELANDED.EXEC." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
if not self.MenusAdded then
local Host = "Command"
if Task.HostUnitName then
Host = Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")"
else
if Client:IsMultiSeated() then
Host = "Co-Pilot"
end
end
Client:Message( 'You have landed within the landing zone. Use the radio menu (F10) to ' .. Task.TEXT[1] .. ' the ' .. Task.CargoType .. '.',
self.MSG.TIME, Mission.Name .. "/STAGELANDED.EXEC" .. Host, Host )
if not self.MenusAdded then
Task.Cargo = nil
Task:RemoveCargoMenus( Client )
Task:AddCargoMenus( Client, CARGOS, 250 )
@ -420,26 +462,44 @@ end
function STAGELANDED:Validate( Mission, Client, Task )
self:F()
if not routines.IsUnitInZones( Client:GetClientGroupDCSUnit(), Task.CurrentLandingZoneName ) then
if not routines.IsUnitNearZonesRadius( Client:GetClientGroupDCSUnit(), Task.CurrentLandingZoneName, 500 ) then
self:T( "Client is not anymore in the landing zone, go back to stage Route, and remove cargo menus." )
Task.Signalled = false
Task:RemoveCargoMenus( Client )
self:T( -2 )
return -2
end
local DCSUnitVelocityVec3 = Client:GetClientGroupDCSUnit():getVelocity()
local DCSUnitVelocity = ( DCSUnitVelocityVec3.x ^2 + DCSUnitVelocityVec3.y ^2 + DCSUnitVelocityVec3.z ^2 ) ^ 0.5
if Task.IsLandingRequired and Client:GetClientGroupDCSUnit():inAir() then
self:T( "Client went back in the air. Go back to stage Landing." )
Task.Signalled = false
return -1
end
local DCSUnitPointVec3 = Client:GetClientGroupDCSUnit():getPoint()
local LandHeight = land.getHeight( { x = DCSUnitPointVec3.x, y = DCSUnitPointVec3.z } )
local DCSUnitHeight = DCSUnitPointVec3.y - LandHeight
self:T( { Task.IsLandingRequired, Client:GetClientGroupDCSUnit():inAir() } )
if Task.IsLandingRequired and Task.IsInAirTestRequired == true and Client:GetClientGroupDCSUnit():inAir() then
self:T( "Client went back in the air. Go back to stage Landing." )
self:T( -1 )
return -1
end
self:T( { DCSUnitVelocity, DCSUnitHeight, LandHeight, Task.CurrentCargoZone.SignalHeight } )
if Task.IsLandingRequired and Task.IsInAirTestRequired == false and DCSUnitVelocity >= 2 and DCSUnitHeight >= Task.CurrentCargoZone.SignalHeight then
self:T( "It seems the Client went back in the air and over the boundary limits. Go back to stage Landing." )
self:T( -1 )
return -1
end
-- Wait until cargo is selected from the menu.
if Task.IsLandingRequired then
if not Task.Cargo then
self:T( 0 )
return 0
end
end
self:T( 1 )
return 1
end
@ -503,7 +563,7 @@ function STAGEUNLOAD:Validate( Mission, Client, Task )
self:F()
env.info( 'STAGEUNLOAD:Validate()' )
if routines.IsUnitInZones( Client:GetClientGroupDCSUnit(), Task.CurrentLandingZoneName ) then
if routines.IsUnitNearZonesRadius( Client:GetClientGroupDCSUnit(), Task.CurrentLandingZoneName, 500 ) then
else
Task.ExecuteStage = _TransportExecuteStage.FAILED
Task:RemoveCargoMenus( Client )
@ -562,10 +622,21 @@ function STAGELOAD:Execute( Mission, Client, Task )
self:F()
if not Task.IsSlingLoad then
local Host = "Command"
if Task.HostUnitName then
Host = Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")"
else
if Client:IsMultiSeated() then
Host = "Co-Pilot"
end
end
Client:Message( 'The ' .. Task.CargoType .. ' are being ' .. Task.TEXT[2] .. ' within the landing zone. Wait until the helicopter is ' .. Task.TEXT[3] .. '.',
_TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.EXEC." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
_TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.EXEC." .. Host, Host )
-- Route the cargo to the Carrier
Task.Cargo:OnBoard( Client, Task.CurrentCargoZone, Task.OnBoardSide )
Task.ExecuteStage = _TransportExecuteStage.EXECUTING
else
@ -578,6 +649,14 @@ function STAGELOAD:Executing( Mission, Client, Task )
-- If the Cargo is ready to be loaded, load it into the Client.
local Host = "Command"
if Task.HostUnitName then
Host = Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")"
else
if Client:IsMultiSeated() then
Host = "Co-Pilot"
end
end
if not Task.IsSlingLoad then
self:T( Task.Cargo.CargoName)
@ -589,14 +668,14 @@ function STAGELOAD:Executing( Mission, Client, Task )
-- Message to the pilot that cargo has been loaded.
Client:Message( "The cargo " .. Task.Cargo.CargoName .. " has been loaded in our helicopter.",
20, Mission.Name .. "/STAGELANDING.LOADING1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
20, Mission.Name .. "/STAGELANDING.LOADING1." .. Host, Host )
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
Client:ShowCargo()
end
else
Client:Message( "Hook the " .. Task.CargoNames .. " onto the helicopter " .. Task.TEXT[3] .. " within the landing zone.",
_TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.LOADING.1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")", 10 )
_TransportStageMsgTime.EXECUTING, Mission.Name .. "/STAGELOAD.LOADING.1." .. Host, Host , 10 )
for CargoID, Cargo in pairs( CARGOS ) do
self:T( "Cargo.CargoName = " .. Cargo.CargoName )
@ -612,7 +691,7 @@ function STAGELOAD:Executing( Mission, Client, Task )
Cargo:StatusLoaded()
Task.Cargo = Cargo
Client:Message( 'The Cargo has been successfully hooked onto the helicopter and is now being sling loaded. Fly outside the landing zone.',
self.MSG.TIME, Mission.Name .. "/STAGELANDING.LOADING.2." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
self.MSG.TIME, Mission.Name .. "/STAGELANDING.LOADING.2." .. Host, Host )
Task.ExecuteStage = _TransportExecuteStage.SUCCESS
break
end
@ -630,32 +709,61 @@ function STAGELOAD:Validate( Mission, Client, Task )
self:T( "Task.CurrentLandingZoneName = " .. Task.CurrentLandingZoneName )
local Host = "Command"
if Task.HostUnitName then
Host = Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")"
else
if Client:IsMultiSeated() then
Host = "Co-Pilot"
end
end
if not Task.IsSlingLoad then
if not routines.IsUnitInZones( Client:GetClientGroupDCSUnit(), Task.CurrentLandingZoneName ) then
if not routines.IsUnitNearZonesRadius( Client:GetClientGroupDCSUnit(), Task.CurrentLandingZoneName, 500 ) then
Task:RemoveCargoMenus( Client )
Task.ExecuteStage = _TransportExecuteStage.FAILED
Task.CargoName = nil
Client:Message( "The " .. Task.CargoType .. " loading has been aborted. You flew outside the pick-up zone while loading. ",
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.1." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.1." .. Host, Host )
self:T( -1 )
return -1
end
if not Client:GetClientGroupDCSUnit():inAir() then
else
-- The carrier is back in the air, undo the loading process.
Task:RemoveCargoMenus( Client )
Task.ExecuteStage = _TransportExecuteStage.NONE
Task.CargoName = nil
Client:Message( "The " .. Task.CargoType .. " loading has been aborted. Re-start the " .. Task.TEXT[3] .. " process. Don't fly outside the pick-up zone.",
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.2." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
return -1
end
local DCSUnitVelocityVec3 = Client:GetClientGroupDCSUnit():getVelocity()
local DCSUnitVelocity = ( DCSUnitVelocityVec3.x ^2 + DCSUnitVelocityVec3.y ^2 + DCSUnitVelocityVec3.z ^2 ) ^ 0.5
local DCSUnitPointVec3 = Client:GetClientGroupDCSUnit():getPoint()
local LandHeight = land.getHeight( { x = DCSUnitPointVec3.x, y = DCSUnitPointVec3.z } )
local DCSUnitHeight = DCSUnitPointVec3.y - LandHeight
self:T( { Task.IsLandingRequired, Client:GetClientGroupDCSUnit():inAir() } )
if Task.IsLandingRequired and Task.IsInAirTestRequired == true and Client:GetClientGroupDCSUnit():inAir() then
Task:RemoveCargoMenus( Client )
Task.ExecuteStage = _TransportExecuteStage.FAILED
Task.CargoName = nil
Client:Message( "The " .. Task.CargoType .. " loading has been aborted. Re-start the " .. Task.TEXT[3] .. " process. Don't fly outside the pick-up zone.",
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.1." .. Host, Host )
self:T( -1 )
return -1
end
self:T( { DCSUnitVelocity, DCSUnitHeight, LandHeight, Task.CurrentCargoZone.SignalHeight } )
if Task.IsLandingRequired and Task.IsInAirTestRequired == false and DCSUnitVelocity >= 2 and DCSUnitHeight >= Task.CurrentCargoZone.SignalHeight then
Task:RemoveCargoMenus( Client )
Task.ExecuteStage = _TransportExecuteStage.FAILED
Task.CargoName = nil
Client:Message( "The " .. Task.CargoType .. " loading has been aborted. Re-start the " .. Task.TEXT[3] .. " process. Don't fly outside the pick-up zone.",
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.1." .. Host, Host )
self:T( -1 )
return -1
end
if Task.ExecuteStage == _TransportExecuteStage.SUCCESS then
Task:RemoveCargoMenus( Client )
Client:Message( "Good Job. The " .. Task.CargoType .. " has been sucessfully " .. Task.TEXT[3] .. " within the landing zone.",
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.3." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.3." .. Host, Host )
Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.CargoName, 1 )
self:T( 1 )
return 1
end
@ -664,8 +772,9 @@ function STAGELOAD:Validate( Mission, Client, Task )
CargoStatic = StaticObject.getByName( Task.Cargo.CargoStaticName )
if CargoStatic and not routines.IsStaticInZones( CargoStatic, Task.CurrentLandingZoneName ) then
Client:Message( "Good Job. The " .. Task.CargoType .. " has been sucessfully " .. Task.TEXT[3] .. " and flown outside of the landing zone.",
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.4." .. Task.HostUnitName, Task.HostUnitName .. " (" .. Task.HostUnitTypeName .. ")" )
self.MSG.TIME, Mission.Name .. "/STAGELANDING.VALIDATE.4." .. Host, Host )
Task.MissionTask:AddGoalCompletion( Task.MissionTask.GoalVerb, Task.Cargo.CargoName, 1 )
self:T( 1 )
return 1
end
end
@ -673,6 +782,7 @@ function STAGELOAD:Validate( Mission, Client, Task )
end
self:T( 0 )
return 0
end

View File

@ -1,5 +1,77 @@
--- UNIT Classes
--- UNIT Class
--
-- @{UNIT} class
-- ==============
-- The @{UNIT} class is a wrapper class to handle the DCS Unit objects:
--
-- * Support all DCS Unit APIs.
-- * Enhance with Unit specific APIs not in the DCS Unit API set.
-- * Handle local Unit Controller.
-- * Manage the "state" of the DCS Unit.
--
--
-- UNIT reference methods
-- ======================
-- For each DCS Unit object alive within a running mission, a UNIT wrapper object (instance) will be created within the _@{DATABASE} object.
-- This is done at the beginning of the mission (when the mission starts), and dynamically when new DCS Unit objects are spawned (using the @{SPAWN} class).
--
-- The UNIT class **does not contain a :New()** method, rather it provides **:Find()** methods to retrieve the object reference
-- using the DCS Unit or the DCS UnitName.
--
-- Another thing to know is that UNIT objects do not "contain" the DCS Unit object.
-- The UNIT methods will reference the DCS Unit object by name when it is needed during API execution.
-- If the DCS Unit object does not exist or is nil, the UNIT methods will return nil and log an exception in the DCS.log file.
--
-- The UNIT class provides the following functions to retrieve quickly the relevant UNIT instance:
--
-- * @{#UNIT.Find}(): Find a UNIT instance from the _DATABASE object using a DCS Unit object.
-- * @{#UNIT.FindByName}(): Find a UNIT instance from the _DATABASE object using a DCS Unit name.
--
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these UNIT OBJECT REFERENCES! (make the UNIT object references nil).
--
-- DCS UNIT APIs
-- =============
-- The DCS Unit APIs are used extensively within MOOSE. The UNIT class has for each DCS Unit API a corresponding method.
-- To be able to distinguish easily in your code the difference between a UNIT API call and a DCS Unit API call,
-- the first letter of the method is also capitalized. So, by example, the DCS Unit method @{DCSUnit#Unit.getName}()
-- is implemented in the UNIT class as @{#UNIT.GetName}().
--
-- Additional UNIT APIs
-- ====================
-- The UNIT class comes with additional methods. Find below a summary.
--
-- Smoke, Flare Units
-- ------------------
-- The UNIT class provides methods to smoke or flare units easily.
-- The @{#UNIT.SmokeBlue}(), @{#UNIT.SmokeGreen}(),@{#UNIT.SmokeOrange}(), @{#UNIT.SmokeRed}(), @{#UNIT.SmokeRed}() methods
-- will smoke the unit in the corresponding color. Note that smoking a unit is done at the current position of the DCS Unit.
-- When the DCS Unit moves for whatever reason, the smoking will still continue!
-- The @{#UNIT.FlareGreen}(), @{#UNIT.FlareRed}(), @{#UNIT.FlareWhite}(), @{#UNIT.FlareYellow}()
-- methods will fire off a flare in the air with the corresponding color. Note that a flare is a one-off shot and its effect is of very short duration.
--
-- Position, Point
-- ---------------
-- The UNIT class provides methods to obtain the current point or position of the DCS Unit.
-- The @{#UNIT.GetPointVec2}(), @{#UNIT.GetPointVec3}() will obtain the current location of the DCS Unit in a Vec2 (2D) or a Vec3 (3D) vector respectively.
-- If you want to obtain the complete 3D position including oriëntation and direction vectors, consult the @{#UNIT.GetPositionVec3}() method respectively.
--
-- Alive
-- -----
-- The @{#UNIT.IsAlive}(), @{#UNIT.IsActive}() methods determines if the DCS Unit is alive, meaning, it is existing and active.
--
-- Test for other units in radius
-- ------------------------------
-- One can test if another DCS Unit is within a given radius of the current DCS Unit, by using the @{#UNIT.OtherUnitInRadius}() method.
--
-- More functions will be added
-- ----------------------------
-- During the MOOSE development, more functions will be added. A complete list of the current functions is below.
--
--
--
--
-- @module Unit
-- @author FlightControl
Include.File( "Routines" )
Include.File( "Base" )
@ -7,7 +79,7 @@ Include.File( "Message" )
--- The UNIT class
-- @type UNIT
-- @Extends Base#BASE
-- @extends Base#BASE
-- @field #UNIT.FlareColor FlareColor
-- @field #UNIT.SmokeColor SmokeColor
UNIT = {
@ -48,192 +120,639 @@ UNIT = {
-- @field White
-- @field Orange
-- @field Blue
-- Registration.
--- Create a new UNIT from DCSUnit.
-- @param #UNIT self
-- @param DCSUnit#Unit DCSUnit
-- @param Database#DATABASE Database
-- @return Unit#UNIT
function UNIT:New( DCSUnit )
local self = BASE:Inherit( self, BASE:New() )
self:F( DCSUnit:getName() )
function UNIT:Register( UnitName )
self.DCSUnit = DCSUnit
self.UnitName = DCSUnit:getName()
self.UnitID = DCSUnit:getID()
return self
local self = BASE:Inherit( self, BASE:New() )
self:F2( UnitName )
self.UnitName = UnitName
return self
end
function UNIT:IsAlive()
self:F( self.UnitName )
return ( self.DCSUnit and self.DCSUnit:isExist() )
-- Reference methods.
--- Finds a UNIT from the _DATABASE using a DCSUnit object.
-- @param #UNIT self
-- @param DCSUnit#Unit DCSUnit An existing DCS Unit object reference.
-- @return Unit#UNIT self
function UNIT:Find( DCSUnit )
local UnitName = DCSUnit:getName()
local UnitFound = _DATABASE:FindUnit( UnitName )
return UnitFound
end
--- Find a UNIT in the _DATABASE using the name of an existing DCS Unit.
-- @param #UNIT self
-- @param #string UnitName The Unit Name.
-- @return Unit#UNIT self
function UNIT:FindByName( UnitName )
local UnitFound = _DATABASE:FindUnit( UnitName )
return UnitFound
end
function UNIT:GetDCSUnit()
self:F( self.DCSUnit )
return self.DCSUnit
local DCSUnit = Unit.getByName( self.UnitName )
if DCSUnit then
return DCSUnit
end
return nil
end
function UNIT:GetID()
self:F( self.UnitID )
return self.UnitID
--- Returns coalition of the Unit.
-- @param Unit#UNIT self
-- @return DCSCoalitionObject#coalition.side The side of the coalition.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetCoalition()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitCoalition = DCSUnit:getCoalition()
self:T3( UnitCoalition )
return UnitCoalition
end
return nil
end
--- Returns country of the Unit.
-- @param Unit#UNIT self
-- @return DCScountry#country.id The country identifier.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetCountry()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitCountry = DCSUnit:getCountry()
self:T3( UnitCountry )
return UnitCountry
end
return nil
end
--- Returns DCS Unit object name.
-- The function provides access to non-activated units too.
-- @param Unit#UNIT self
-- @return #string The name of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetName()
self:F( self.UnitName )
return self.UnitName
end
self:F2( self.UnitName )
function UNIT:GetTypeName()
self:F( self.UnitName )
return self.DCSUnit:getTypeName()
end
function UNIT:GetPrefix()
self:F( self.UnitName )
local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 )
self:T( UnitPrefix )
return UnitPrefix
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitName = self.UnitName
return UnitName
end
return nil
end
function UNIT:GetCallSign()
self:F( self.UnitName )
--- Returns if the unit is alive.
-- @param Unit#UNIT self
-- @return #boolean true if Unit is alive.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:IsAlive()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitIsAlive = DCSUnit:isExist()
return UnitIsAlive
end
return self.DCSUnit:getCallsign()
end
function UNIT:GetPointVec2()
self:F( self.UnitName )
local UnitPos = self.DCSUnit:getPosition().p
local UnitPoint = {}
UnitPoint.x = UnitPos.x
UnitPoint.y = UnitPos.z
self:T( UnitPoint )
return UnitPoint
end
function UNIT:GetPositionVec3()
self:F( self.UnitName )
local UnitPos = self.DCSUnit:getPosition().p
self:T( UnitPos )
return UnitPos
end
function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
self:F( { self.UnitName, AwaitUnit.UnitName, Radius } )
local UnitPos = self:GetPositionVec3()
local AwaitUnitPos = AwaitUnit:GetPositionVec3()
if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then
self:T( "true" )
return true
else
self:T( "false" )
return false
end
self:T( "false" )
return false
end
--- Returns if the unit is activated.
-- @param Unit#UNIT self
-- @return #boolean true if Unit is activated.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:IsActive()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitIsActive = DCSUnit:isActive()
return UnitIsActive
end
return nil
end
--- Returns name of the player that control the unit or nil if the unit is controlled by A.I.
-- @param Unit#UNIT self
-- @return #string Player Name
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetPlayerName()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local PlayerName = DCSUnit:getPlayerName()
if PlayerName == nil then
PlayerName = ""
end
return PlayerName
end
return nil
end
--- Returns the unit's unique identifier.
-- @param Unit#UNIT self
-- @return DCSUnit#Unit.ID Unit ID
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetID()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitID = DCSUnit:getID()
return UnitID
end
return nil
end
--- Returns the unit's number in the group.
-- The number is the same number the unit has in ME.
-- It may not be changed during the mission.
-- If any unit in the group is destroyed, the numbers of another units will not be changed.
-- @param Unit#UNIT self
-- @return #number The Unit number.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetNumber()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitNumber = DCSUnit:getNumber()
return UnitNumber
end
return nil
end
--- Returns the unit's group if it exist and nil otherwise.
-- @param Unit#UNIT self
-- @return Group#GROUP The Group of the Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetGroup()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitGroup = DCSUnit:getGroup()
return UnitGroup
end
return nil
end
--- Returns the unit's callsign - the localized string.
-- @param Unit#UNIT self
-- @return #string The Callsign of the Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetCallSign()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitCallSign = DCSUnit:getCallsign()
return UnitCallSign
end
return nil
end
--- Returns the unit's health. Dead units has health <= 1.0.
-- @param Unit#UNIT self
-- @return #number The Unit's health value.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetLife()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitLife = DCSUnit:getLife()
return UnitLife
end
return nil
end
--- Returns the Unit's initial health.
-- @param Unit#UNIT self
-- @return #number The Unit's initial health value.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetLife0()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitLife0 = DCSUnit:getLife0()
return UnitLife0
end
return nil
end
--- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0.
-- @param Unit#UNIT self
-- @return #number The relative amount of fuel (from 0.0 to 1.0).
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetFuel()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitFuel = DCSUnit:getFuel()
return UnitFuel
end
return nil
end
--- Returns the Unit's ammunition.
-- @param Unit#UNIT self
-- @return DCSUnit#Unit.Ammo
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetAmmo()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitAmmo = DCSUnit:getAmmo()
return UnitAmmo
end
return nil
end
--- Returns the unit sensors.
-- @param Unit#UNIT self
-- @return DCSUnit#Unit.Sensors
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetSensors()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitSensors = DCSUnit:getSensors()
return UnitSensors
end
return nil
end
-- Need to add here a function per sensortype
-- unit:hasSensors(Unit.SensorType.RADAR, Unit.RadarType.AS)
--- Returns two values:
--
-- * First value indicates if at least one of the unit's radar(s) is on.
-- * Second value is the object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target.
-- @param Unit#UNIT self
-- @return #boolean Indicates if at least one of the unit's radar(s) is on.
-- @return DCSObject#Object The object of the radar's interest. Not nil only if at least one radar of the unit is tracking a target.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetRadar()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitRadarOn, UnitRadarObject = DCSUnit:getRadar()
return UnitRadarOn, UnitRadarObject
end
return nil, nil
end
-- Need to add here functions to check if radar is on and which object etc.
--- Returns unit descriptor. Descriptor type depends on unit category.
-- @param Unit#UNIT self
-- @return DCSUnit#Unit.Desc The Unit descriptor.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetDesc()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitDesc = DCSUnit:getDesc()
return UnitDesc
end
return nil
end
--- Returns the type name of the DCS Unit.
-- @param Unit#UNIT self
-- @return #string The type name of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetTypeName()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitTypeName = DCSUnit:getTypeName()
self:T3( UnitTypeName )
return UnitTypeName
end
return nil
end
--- Returns the prefix name of the DCS Unit. A prefix name is a part of the name before a '#'-sign.
-- DCS Units spawned with the @{SPAWN} class contain a '#'-sign to indicate the end of the (base) DCS Unit name.
-- The spawn sequence number and unit number are contained within the name after the '#' sign.
-- @param Unit#UNIT self
-- @return #string The name of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetPrefix()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 )
self:T3( UnitPrefix )
return UnitPrefix
end
return nil
end
--- Returns the @{DCSTypes#Vec2} vector indicating the point in 2D of the DCS Unit within the mission.
-- @param Unit#UNIT self
-- @return DCSTypes#Vec2 The 2D point vector of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetPointVec2()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitPointVec3 = DCSUnit:getPosition().p
local UnitPointVec2 = {}
UnitPointVec2.x = UnitPointVec3.x
UnitPointVec2.y = UnitPointVec3.z
self:T3( UnitPointVec2 )
return UnitPointVec2
end
return nil
end
--- Returns the @{DCSTypes#Vec3} vector indicating the point in 3D of the DCS Unit within the mission.
-- @param Unit#UNIT self
-- @return DCSTypes#Vec3 The 3D point vector of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetPointVec3()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitPointVec3 = DCSUnit:getPosition().p
self:T3( UnitPointVec3 )
return UnitPointVec3
end
return nil
end
--- Returns the @{DCSTypes#Position3} position vectors indicating the point and direction vectors in 3D of the DCS Unit within the mission.
-- @param Unit#UNIT self
-- @return DCSTypes#Position The 3D position vectors of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetPositionVec3()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitPosition = DCSUnit:getPosition()
self:T3( UnitPosition )
return UnitPosition
end
return nil
end
--- Returns the DCS Unit velocity vector.
-- @param Unit#UNIT self
-- @return DCSTypes#Vec3 The velocity vector
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetVelocity()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitVelocityVec3 = DCSUnit:getVelocity()
self:T3( UnitVelocityVec3 )
return UnitVelocityVec3
end
return nil
end
--- Returns true if the DCS Unit is in the air.
-- @param Unit#UNIT self
-- @return #boolean true if in the air.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:InAir()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitInAir = DCSUnit:inAir()
self:T3( UnitInAir )
return UnitInAir
end
return nil
end
--- Returns the altitude of the DCS Unit.
-- @param Unit#UNIT self
-- @return DCSTypes#Distance The altitude of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:GetAltitude()
self:F2()
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitPointVec3 = DCSUnit:getPoint() --DCSTypes#Vec3
return UnitPointVec3.y
end
return nil
end
--- Returns true if there is an **other** DCS Unit within a radius of the current 2D point of the DCS Unit.
-- @param Unit#UNIT self
-- @param Unit#UNIT AwaitUnit The other UNIT wrapper object.
-- @param Radius The radius in meters with the DCS Unit in the centre.
-- @return true If the other DCS Unit is within the radius of the 2D point of the DCS Unit.
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:OtherUnitInRadius( AwaitUnit, Radius )
self:F2( { self.UnitName, AwaitUnit.UnitName, Radius } )
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitPos = self:GetPointVec3()
local AwaitUnitPos = AwaitUnit:GetPointVec3()
if (((UnitPos.x - AwaitUnitPos.x)^2 + (UnitPos.z - AwaitUnitPos.z)^2)^0.5 <= Radius) then
self:T3( "true" )
return true
else
self:T3( "false" )
return false
end
end
return nil
end
--- Returns the DCS Unit category name as defined within the DCS Unit Descriptor.
-- @param Unit#UNIT self
-- @return #string The DCS Unit Category Name
function UNIT:GetCategoryName()
return self.CategoryName[ self.DCSUnit:getDesc().category ]
local DCSUnit = self:GetDCSUnit()
if DCSUnit then
local UnitCategoryName = self.CategoryName[ self:GetDesc().category ]
return UnitCategoryName
end
return nil
end
--- Signal a flare at the position of the UNIT.
-- @param #UNIT self
function UNIT:Flare( FlareColor )
self:F()
trigger.action.signalFlare( self:GetPositionVec3(), FlareColor , 0 )
self:F2()
trigger.action.signalFlare( self:GetPointVec3(), FlareColor , 0 )
end
--- Signal a white flare at the position of the UNIT.
-- @param #UNIT self
function UNIT:FlareWhite()
self:F()
trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.White , 0 )
self:F2()
trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.White , 0 )
end
--- Signal a yellow flare at the position of the UNIT.
-- @param #UNIT self
function UNIT:FlareYellow()
self:F()
trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Yellow , 0 )
self:F2()
trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Yellow , 0 )
end
--- Signal a green flare at the position of the UNIT.
-- @param #UNIT self
function UNIT:FlareGreen()
self:F()
trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Green , 0 )
self:F2()
trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Green , 0 )
end
--- Signal a red flare at the position of the UNIT.
-- @param #UNIT self
function UNIT:FlareRed()
self:F()
trigger.action.signalFlare( self:GetPositionVec3(), trigger.flareColor.Red, 0 )
self:F2()
trigger.action.signalFlare( self:GetPointVec3(), trigger.flareColor.Red, 0 )
end
--- Smoke the UNIT.
-- @param #UNIT self
function UNIT:Smoke( SmokeColor )
self:F()
trigger.action.smoke( self:GetPositionVec3(), SmokeColor )
self:F2()
trigger.action.smoke( self:GetPointVec3(), SmokeColor )
end
--- Smoke the UNIT Green.
-- @param #UNIT self
function UNIT:SmokeGreen()
self:F()
trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Green )
self:F2()
trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Green )
end
--- Smoke the UNIT Red.
-- @param #UNIT self
function UNIT:SmokeRed()
self:F()
trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Red )
self:F2()
trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Red )
end
--- Smoke the UNIT White.
-- @param #UNIT self
function UNIT:SmokeWhite()
self:F()
trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.White )
self:F2()
trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.White )
end
--- Smoke the UNIT Orange.
-- @param #UNIT self
function UNIT:SmokeOrange()
self:F()
trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Orange )
self:F2()
trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Orange )
end
--- Smoke the UNIT Blue.
-- @param #UNIT self
function UNIT:SmokeBlue()
self:F()
trigger.action.smoke( self:GetPositionVec3(), trigger.smokeColor.Blue )
self:F2()
trigger.action.smoke( self:GetPointVec3(), trigger.smokeColor.Blue )
end
-- Is methods
@ -243,14 +762,14 @@ end
-- @param #UNIT self
-- @return #boolean Air category evaluation result.
function UNIT:IsAir()
self:F()
self:F2()
local UnitDescriptor = self.DCSUnit:getDesc()
self:T( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } )
self:T3( { UnitDescriptor.category, Unit.Category.AIRPLANE, Unit.Category.HELICOPTER } )
local IsAirResult = ( UnitDescriptor.category == Unit.Category.AIRPLANE ) or ( UnitDescriptor.category == Unit.Category.HELICOPTER )
self:T( IsAirResult )
self:T3( IsAirResult )
return IsAirResult
end

View File

@ -40,6 +40,17 @@ function ZONE:GetPointVec2()
return Point
end
function ZONE:GetPointVec3( Height )
self:F( self.ZoneName )
local Zone = trigger.misc.getZone( self.ZoneName )
local Point = { x = Zone.point.x, y = land.getHeight( self:GetPointVec2() ) + Height, z = Zone.point.z }
self:T( { Zone, Point } )
return Point
end
function ZONE:GetRandomPointVec2()
self:F( self.ZoneName )

Binary file not shown.

View File

@ -12,7 +12,7 @@ Include.File( "Event" )
do
local Mission = MISSION:New( 'Destroy Gound', 'Ground', 'Briefing', 'CCCP' )
Mission:AddClient( CLIENT:New( 'Client Plane', "Just wait and observe the SU-25T destoying targets. Your mission goal should increase..." ) )
Mission:AddClient( CLIENT:FindByName( 'Client Plane', "Just wait and observe the SU-25T destoying targets. Your mission goal should increase..." ) )
local DESTROYGROUPSTASK = DESTROYGROUPSTASK:New( 'Ground Vehicle', 'Ground Vehicles', { 'DESTROY Test 1' }, 100 ) -- 75% of a patriot battery needs to be destroyed to achieve mission success...
DESTROYGROUPSTASK:SetGoalTotal( 1 )
@ -25,7 +25,7 @@ end
do
local Mission = MISSION:New( 'Destroy Helicopters', 'Helicopters', 'Briefing', 'CCCP' )
Mission:AddClient( CLIENT:New( 'Client Plane', "Just wait and observe the SU-25T destoying the helicopters. The helicopter mission goal should increase once all are destroyed ..." ) )
Mission:AddClient( CLIENT:FindByName( 'Client Plane', "Just wait and observe the SU-25T destoying the helicopters. The helicopter mission goal should increase once all are destroyed ..." ) )
local DESTROYGROUPSTASK = DESTROYGROUPSTASK:New( 'Helicopter', 'Helicopters', { 'DESTROY Test 2' }, 50 )
DESTROYGROUPSTASK:SetGoalTotal( 2 )

View File

@ -53,8 +53,8 @@ do
SpawnEscortGround = SPAWN:New( "Escort Ground" )
SpawnEscortShip = SPAWN:New( "Escort Ship" )
EscortClientHeli = CLIENT:New( "Lead Helicopter", "Fly around and observe the behaviour of the escort helicopter" ):Alive( EventAliveHelicopter )
EscortClientPlane = CLIENT:New( "Lead Plane", "Fly around and observe the behaviour of the escort airplane. Select Navigate->Joun-Up and airplane should follow you. Change speed and directions." )
EscortClientHeli = CLIENT:FindByName( "Lead Helicopter", "Fly around and observe the behaviour of the escort helicopter" ):Alive( EventAliveHelicopter )
EscortClientPlane = CLIENT:FindByName( "Lead Plane", "Fly around and observe the behaviour of the escort airplane. Select Navigate->Joun-Up and airplane should follow you. Change speed and directions." )
:Alive( EventAlivePlane )
end

View File

@ -0,0 +1,20 @@
-- Only use Include.File when developing new MOOSE classes.
-- When using Moose.lua in the DO SCIPTS FILE initialization box,
-- these Include.File statements are not needed, because all classes within Moose will be loaded.
Include.File("MissileTrainer")
-- This is an example of a global
local Trainer = MISSILETRAINER
:New( 200, "Trainer: Welcome to the missile training, trainee! Missiles will be fired at you. Try to evade them. Good luck!" )
:InitMessagesOnOff(true)
:InitAlertsToAll(true)
:InitAlertsHitsOnOff(true)
:InitAlertsLaunchesOnOff(false) -- I'll put it on below ...
:InitBearingOnOff(true)
:InitRangeOnOff(true)
:InitTrackingOnOff(true)
:InitTrackingToAll(true)
:InitMenusOnOff(false)
Trainer:InitAlertsToAll(true) -- Now alerts are also on

View File

@ -26,7 +26,7 @@ Group_Vehicle6 = Spawn_Vehicle:Spawn()
Group_Vehicle1:TaskRouteToZone( ZONE:New( "Landing Zone" ), true, 40, "Cone" )
-- Now land the spawned plane on to the Vinson, by copying the route of another object.
Route_Plane = GROUP:NewFromName( "Spawn Helicopter Route Copy" ):CopyRoute( 1, 0 )
Route_Plane = GROUP:FindByName( "Spawn Helicopter Route Copy" ):CopyRoute( 1, 0 )
Group_Plane:Route( Route_Plane )
@ -46,15 +46,15 @@ Spawn_Helicopter_Scheduled = SPAWN:New( "Spawn Helicopter Scheduled" ):SpawnSche
Spawn_Ship_Scheduled = SPAWN:New( "Spawn Ship Scheduled" ):SpawnScheduled( 30, 0.5 )
Spawn_Vehicle_Scheduled = SPAWN:New( "Spawn Vehicle Scheduled" ):SpawnScheduled( 30, 0.5 )
-- Tests Tbilisi: Limited Spawning
-- -------------------------------
-- Tests Tbilisi: Limited Spawning and repeat
-- ------------------------------------------
-- Spawing one group, and respawning the same group when it lands ...
Spawn_Plane_Limited_Repeat = SPAWN:New( "Spawn Plane Limited Repeat" ):Limit( 1, 1 ):Repeat():Spawn()
Spawn_Plane_Limited_RepeatOnLanding = SPAWN:New( "Spawn Plane Limited RepeatOnLanding" ):Limit( 1, 1 ):Repeat():Spawn()
Spawn_Plane_Limited_RepeatOnEngineShutDown = SPAWN:New( "Spawn Plane Limited RepeatOnEngineShutDown" ):Limit( 1, 1 ):Repeat():Spawn()
Spawn_Helicopter_Limited_Repeat = SPAWN:New( "Spawn Helicopter Limited Repeat" ):Limit( 1, 1 ):Repeat():Spawn()
Spawn_Helicopter_Limited_RepeatOnLanding = SPAWN:New( "Spawn Helicopter Limited RepeatOnLanding" ):Limit( 1, 1 ):Repeat():Spawn()
Spawn_Helicopter_Limited_RepeatOnEngineShutDown = SPAWN:New( "Spawn Helicopter Limited RepeatOnEngineShutDown" ):Limit( 1, 1 ):Repeat():Spawn()
Spawn_Plane_Limited_Repeat = SPAWN:New( "Spawn Plane Limited Repeat" ):Limit( 1, 1 ):InitRepeat():Spawn()
Spawn_Plane_Limited_RepeatOnLanding = SPAWN:New( "Spawn Plane Limited RepeatOnLanding" ):Limit( 1, 1 ):InitRepeatOnLanding():Spawn()
Spawn_Plane_Limited_RepeatOnEngineShutDown = SPAWN:New( "Spawn Plane Limited RepeatOnEngineShutDown" ):Limit( 1, 1 ):InitRepeatOnEngineShutDown():Spawn()
Spawn_Helicopter_Limited_Repeat = SPAWN:New( "Spawn Helicopter Limited Repeat" ):Limit( 1, 1 ):InitRepeat():Spawn()
Spawn_Helicopter_Limited_RepeatOnLanding = SPAWN:New( "Spawn Helicopter Limited RepeatOnLanding" ):Limit( 1, 1 ):InitRepeatOnLanding():Spawn()
Spawn_Helicopter_Limited_RepeatOnEngineShutDown = SPAWN:New( "Spawn Helicopter Limited RepeatOnEngineShutDown" ):Limit( 1, 1 ):InitRepeatOnEngineShutDown():Spawn()
-- Tests Soganlug
@ -67,8 +67,8 @@ Spawn_Ground_Limited_Scheduled = SPAWN:New( "Spawn Vehicle Limited Scheduled" ):
-- Tests Sukhumi
-- -------------
-- Limited spawning of groups, scheduled every seconds with route randomization.
Spawn_Plane_Limited_Scheduled_RandomizeRoute = SPAWN:New( "Spawn Plane Limited Scheduled RandomizeRoute" ):Limit( 2, 10 ):RandomizeRoute( 1, 1, 4000 ):SpawnScheduled( 30, 0 )
Spawn_Helicopter_Limited_Scheduled_RandomizeRoute = SPAWN:New( "Spawn Helicopter Limited Scheduled RandomizeRoute" ):Limit( 2, 10 ):RandomizeRoute( 1, 1, 4000 ):SpawnScheduled( 30, 0 )
Spawn_Plane_Limited_Scheduled_RandomizeRoute = SPAWN:New( "Spawn Plane Limited Scheduled RandomizeRoute" ):Limit( 5, 10 ):RandomizeRoute( 1, 1, 4000 ):SpawnScheduled( 2, 0 )
Spawn_Helicopter_Limited_Scheduled_RandomizeRoute = SPAWN:New( "Spawn Helicopter Limited Scheduled RandomizeRoute" ):Limit( 5, 10 ):RandomizeRoute( 1, 1, 4000 ):SpawnScheduled( 2, 0 )
Spawn_Vehicle_Limited_Scheduled_RandomizeRoute = SPAWN:New( "Spawn Vehicle Limited Scheduled RandomizeRoute" ):Limit( 10, 10 ):RandomizeRoute( 1, 1, 1000 ):SpawnScheduled( 1, 0 )
@ -85,7 +85,7 @@ Spawn_Vehicle_Scheduled_CleanUp = SPAWN:New( "Spawn Vehicle Scheduled CleanUp" )
-- Creates arrays of groups ready to be spawned and dynamic spawning of groups from another group.
-- SpawnTestVisible creates an array of 200 groups, every 20 groups with 20 meters space in between, and will activate a group of the array every 10 seconds with a 0.2 time randomization.
SpawnTestVisible = SPAWN:New( "Spawn Vehicle Visible Scheduled" ):Limit( 200, 200 ):Array( 59, 20, 20, 10 ):SpawnScheduled( 10, 0.2 )
SpawnTestVisible = SPAWN:New( "Spawn Vehicle Visible Scheduled" ):Limit( 200, 200 ):Array( 59, 20, 30, 30 ):SpawnScheduled( 10, 0.2 )
-- Spawn_Templates_Visible contains different templates...
Spawn_Templates_Visible = { "Spawn Vehicle Visible Template A",

View File

@ -12,10 +12,6 @@
Include.File("Spawn")
BASE:TraceClass("GROUP")
BASE:TraceClass("SPAWN")
BASE:TraceClass("DATABASE")
do
-- Declare SPAWN objects
@ -27,21 +23,21 @@ do
-- Choose repeat functionality
-- Repeat on landing
Spawn_KA_50:RepeatOnLanding()
Spawn_C_101EB:RepeatOnLanding()
Spawn_KA_50:InitRepeatOnLanding()
Spawn_C_101EB:InitRepeatOnLanding()
-- Repeat on enging shutdown (when landed on the airport)
Spawn_MI_8MTV2:RepeatOnEngineShutDown()
Spawn_A_10C:RepeatOnEngineShutDown()
Spawn_MI_8MTV2:InitRepeatOnEngineShutDown()
Spawn_A_10C:InitRepeatOnEngineShutDown()
-- Now SPAWN the GROUPs
Spawn_KA_50:Spawn()
Spawn_KA_50:Spawn()
Spawn_C_101EB:Spawn()
Spawn_C_101EB:Spawn()
Spawn_MI_8MTV2:Spawn()
Spawn_MI_8MTV2:Spawn()
Spawn_A_10C:Spawn()
Spawn_KA_50:Spawn()
Spawn_C_101EB:Spawn()
Spawn_MI_8MTV2:Spawn()
Spawn_A_10C:Spawn()
-- Now run the mission and observe the behaviour.

View File

@ -14,8 +14,8 @@ Include.File( "CleanUp" )
do
local Mission = MISSION:New( 'Pickup', 'Operational', 'Pickup Troops', 'NATO' )
Mission:AddClient( CLIENT:New( 'DE Pickup Test 1' ):Transport() )
Mission:AddClient( CLIENT:New( 'DE Pickup Test 2' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'DE Pickup Test 1' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'DE Pickup Test 2' ):Transport() )
local CargoTable = {}
@ -62,7 +62,7 @@ end
do
local Mission = MISSION:New( 'Deliver secret letter', 'Operational', 'Pickup letter to the commander.', 'NATO' )
Client_Package_1 = CLIENT:New( 'BE Package Test 1' ):Transport()
Client_Package_1 = CLIENT:FindByName( 'BE Package Test 1' ):Transport()
Mission:AddClient( Client_Package_1 )
@ -95,8 +95,8 @@ end
do
local Mission = MISSION:New( 'Sling load Cargo', 'Operational', 'Sling Load Cargo to Deploy Zone.', 'NATO' )
Mission:AddClient( CLIENT:New( 'Sling Load Test Client 1' ):Transport() )
Mission:AddClient( CLIENT:New( 'Sling Load Test Client 2' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'Sling Load Test Client 1' ):Transport() )
Mission:AddClient( CLIENT:FindByName( 'Sling Load Test Client 2' ):Transport() )
Sling_Load_Pickup_Zone = CARGO_ZONE:New( 'Sling Load Pickup Zone', 'Sling Load Guard' ):RedSmoke()

View File

@ -0,0 +1,39 @@
Include.File( "Group" )
Include.File( "Unit" )
Include.File( "Client" )
BASE:TraceClass( "UNIT" )
BASE:TraceClass( "GROUP" )
BASE:TraceClass( "CLIENT" )
UnitTankAI1 = _DATABASE:FindUnit( "Smoke Test 1" )
UnitTankAI2 = _DATABASE:FindUnit( "Smoke Test 2" )
UnitTankAI3 = UNIT:FindByName( "Smoke Test 3" )
UnitTankAI4 = _DATABASE:FindUnit( "Smoke Test 4" )
UnitTankAI1:SmokeBlue()
UnitTankAI3:SmokeOrange()
UnitTankAI2:T( UnitTankAI2:GetAmmo() )
GroupTanks = GROUP:FindByName( "Smoke Test" )
GroupTanks:T( GroupTanks:OptionROEOpenFirePossible() )
GroupTanks:OptionROEOpenFire()
local function ClientAlive( Client, ClientNumber )
GroupTanks:MessageToClient( "Hello Client " .. ClientNumber .. "! We are reporting to you on our way...", 5, Client )
end
ClientHeli = CLIENT:FindByName( "Client Test 1", "Fly slowly to waypoint 3 of the Command Post!" ):Alive( ClientAlive, 1 )
ClientHeli2 = CLIENT:FindByName( "Client Test 2", "Fly slowly to waypoint 3 of the Command Post!" ):Alive( ClientAlive, 2 )

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Some files were not shown because too many files have changed in this diff Show More