mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge pull request #583 from FlightControl-Master/562-AI-A2A-Dispatcher
562 ai a2a dispatcher
This commit is contained in:
commit
f89964d8ba
@ -566,6 +566,9 @@ do -- AI_A2A_DISPATCHER
|
||||
self.Detection:FilterCategories( Unit.Category.AIRPLANE, Unit.Category.HELICOPTER )
|
||||
--self.Detection:InitDetectRadar( true )
|
||||
self.Detection:SetDetectionInterval( 30 )
|
||||
|
||||
self:SetEngageRadius()
|
||||
self:SetGciRadius()
|
||||
|
||||
self:AddTransition( "Started", "Assign", "Started" )
|
||||
|
||||
@ -736,20 +739,52 @@ do -- AI_A2A_DISPATCHER
|
||||
-- If too small, more intercept missions may be triggered upon detected target areas.
|
||||
-- If too large, any airborne cap may not be able to reach the detected target area in time, because it is too far.
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #number FriendliesRadius The radius to report friendlies near the target.
|
||||
-- @param #number EngageRadius (Optional, Default = 100000) The radius to report friendlies near the target.
|
||||
-- @return #AI_A2A_DISPATCHER
|
||||
-- @usage
|
||||
--
|
||||
-- -- Set 100km as the radius to engage any target by airborne friendlies.
|
||||
-- Dispatcher:InitDetectionFriendiesRadius( 100000 )
|
||||
-- -- Set 50km as the radius to engage any target by airborne friendlies.
|
||||
-- Dispatcher:SetEngageRadius( 50000 )
|
||||
--
|
||||
function AI_A2A_DISPATCHER:SetEngageRadius( FriendliesRadius )
|
||||
-- -- Set 100km as the radius to engage any target by airborne friendlies.
|
||||
-- Dispatcher:SetEngageRadius() -- 100000 is the default value.
|
||||
--
|
||||
function AI_A2A_DISPATCHER:SetEngageRadius( EngageRadius )
|
||||
|
||||
self.Detection:SetFriendliesRange( FriendliesRadius )
|
||||
self.Detection:SetFriendliesRange( EngageRadius )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Define the radius to check if a target can be engaged by an ground controlled intercept.
|
||||
-- So, if there is a target area detected and reported,
|
||||
-- and a GCI is to be executed,
|
||||
-- then it will be check if the target is within the GCI from the nearest airbase.
|
||||
-- For example, if 150000 is given as a value, then any airbase within 150km from the detected target,
|
||||
-- will be considered to receive the command to GCI.
|
||||
-- You need to evaluate the value of this parameter carefully.
|
||||
-- If too small, intercept missions may be triggered too late.
|
||||
-- If too large, intercept missions may be triggered when the detected target is too far.
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #number GciRadius (Optional, Default = 200000) The radius to ground control intercept detected targets from the nearest airbase.
|
||||
-- @return #AI_A2A_DISPATCHER
|
||||
-- @usage
|
||||
--
|
||||
-- -- Set 100km as the radius to ground control intercept detected targets from the nearest airbase.
|
||||
-- Dispatcher:SetGciRadius( 100000 )
|
||||
--
|
||||
-- -- Set 200km as the radius to ground control intercept.
|
||||
-- Dispatcher:SetGciRadius() -- 200000 is the default value.
|
||||
--
|
||||
function AI_A2A_DISPATCHER:SetGciRadius( GciRadius )
|
||||
|
||||
self.GciRadius = GciRadius or 200000
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Define a border area to simulate a **cold war** scenario.
|
||||
-- A **cold war** is one where CAP aircraft patrol their territory but will not attack enemy aircraft or launch GCI aircraft unless enemy aircraft enter their territory. In other words the EWR may detect an enemy aircraft but will only send aircraft to attack it if it crosses the border.
|
||||
-- A **hot war** is one where CAP aircraft will intercept any detected enemy aircraft and GCI aircraft will launch against detected enemy aircraft without regard for territory. In other words if the ground radar can detect the enemy aircraft then it will send CAP and GCI aircraft to attack it.
|
||||
@ -794,7 +829,7 @@ do -- AI_A2A_DISPATCHER
|
||||
-- @return #number, Core.CommandCenter#REPORT
|
||||
function AI_A2A_DISPATCHER:GetAIFriendliesNearBy( DetectedItem )
|
||||
|
||||
local FriendliesNearBy = self.Detection:GetFriendliesNearBy( DetectedItem )
|
||||
local FriendliesNearBy = self.Detection:GetFriendliesDistance( DetectedItem )
|
||||
|
||||
return FriendliesNearBy
|
||||
end
|
||||
@ -927,7 +962,8 @@ do -- AI_A2A_DISPATCHER
|
||||
DefenderSquadron.Resources = Resources
|
||||
|
||||
self:SetSquadronOverhead( SquadronName, 1 )
|
||||
self:SetSquadronTakeoffFromParkingHot( SquadronName )
|
||||
self:SetSquadronTakeoffInAir( SquadronName )
|
||||
self:SetSquadronLandingNearAirbase(SquadronName)
|
||||
|
||||
return self
|
||||
end
|
||||
@ -1652,9 +1688,6 @@ do -- AI_A2A_DISPATCHER
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
function AI_A2A_DISPATCHER:onafterGCI( From, Event, To, Target, DefendersMissing, AIGroups )
|
||||
|
||||
local ClosestDistance = 0
|
||||
local ClosestDefenderSquadronName = nil
|
||||
|
||||
local AttackerCount = Target.Set:Count()
|
||||
local DefendersCount = 0
|
||||
|
||||
@ -1669,6 +1702,10 @@ do -- AI_A2A_DISPATCHER
|
||||
end
|
||||
|
||||
DefendersCount = DefendersMissing
|
||||
|
||||
local ClosestDistance = 0
|
||||
local ClosestDefenderSquadronName = nil
|
||||
|
||||
while( DefendersCount > 0 ) do
|
||||
|
||||
for SquadronName, DefenderSquadron in pairs( self.DefenderSquadrons or {} ) do
|
||||
@ -1677,10 +1714,14 @@ do -- AI_A2A_DISPATCHER
|
||||
local SpawnCoord = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE
|
||||
local TargetCoord = Target.Set:GetFirst():GetCoordinate()
|
||||
local Distance = SpawnCoord:Get2DDistance( TargetCoord )
|
||||
|
||||
|
||||
if ClosestDistance == 0 or Distance < ClosestDistance then
|
||||
ClosestDistance = Distance
|
||||
ClosestDefenderSquadronName = SquadronName
|
||||
|
||||
-- Only intercept if the distance to target is smaller or equal to the GciRadius limit.
|
||||
if Distance <= self.GciRadius then
|
||||
ClosestDistance = Distance
|
||||
ClosestDefenderSquadronName = SquadronName
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1752,6 +1793,9 @@ do -- AI_A2A_DISPATCHER
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- There isn't any closest airbase anymore, break the loop.
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1120,6 +1120,14 @@ do -- DETECTION_BASE
|
||||
return DetectedItem.FriendliesNearBy
|
||||
end
|
||||
|
||||
--- Returns friendly units nearby the FAC units sorted per distance ...
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #map<#number,Wrapper.Unit#UNIT> The map of Friendly UNITs.
|
||||
function DETECTION_BASE:GetFriendliesDistance( DetectedItem )
|
||||
|
||||
return DetectedItem.FriendliesDistance
|
||||
end
|
||||
|
||||
--- Returns if there are friendlies nearby the FAC units ...
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #boolean trhe if there are friendlies nearby
|
||||
@ -1183,8 +1191,11 @@ do -- DETECTION_BASE
|
||||
if FoundUnitCoalition ~= EnemyCoalition and FoundUnitInReportSetGroup == false then
|
||||
DetectedItem.FriendliesNearBy = DetectedItem.FriendliesNearBy or {}
|
||||
local FriendlyUnit = UNIT:Find( FoundDCSUnit )
|
||||
local FriendlyUnitName = FriendlyUnit:GetName()
|
||||
DetectedItem.FriendliesNearBy[FriendlyUnitName] = FriendlyUnit
|
||||
local Distance = CenterCoord:Get2DDistance( FriendlyUnit:GetCoordinate() )
|
||||
DetectedItem.FriendliesNearBy[Distance] = FriendlyUnit
|
||||
DetectedItem.FriendliesDistance = DetectedItem.FriendliesDistance or {}
|
||||
DetectedItem.FriendliesDistance[Distance] = FriendlyUnit
|
||||
return true
|
||||
end
|
||||
|
||||
@ -1200,13 +1211,22 @@ do -- DETECTION_BASE
|
||||
--- @param Wrapper.Unit#UNIT PlayerUnit
|
||||
function( PlayerUnitName )
|
||||
local PlayerUnit = UNIT:FindByName( PlayerUnitName )
|
||||
|
||||
if PlayerUnit and PlayerUnit:IsInZone(DetectionZone) then
|
||||
|
||||
DetectedItem.FriendliesNearBy = DetectedItem.FriendliesNearBy or {}
|
||||
local PlayerUnitName = PlayerUnit:GetName()
|
||||
|
||||
DetectedItem.PlayersNearBy = DetectedItem.PlayersNearBy or {}
|
||||
DetectedItem.PlayersNearBy[PlayerUnitName] = PlayerUnit
|
||||
|
||||
DetectedItem.FriendliesNearBy = DetectedItem.FriendliesNearBy or {}
|
||||
DetectedItem.FriendliesNearBy[PlayerUnitName] = PlayerUnit
|
||||
|
||||
local CenterCoord = DetectedUnit:GetCoordinate()
|
||||
local Distance = CenterCoord:Get2DDistance( PlayerUnit:GetCoordinate() )
|
||||
DetectedItem.FriendliesDistance = DetectedItem.FriendliesDistance or {}
|
||||
DetectedItem.FriendliesDistance[Distance] = PlayerUnit
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
@ -258,6 +258,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_A2A_DISPATCHER).GCI">AI_A2A_DISPATCHER:GCI()</a></td>
|
||||
<td class="summary">
|
||||
<p>GCI Trigger for AI<em>A2A</em>DISPATCHER</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_A2A_DISPATCHER).GciRadius">AI_A2A_DISPATCHER.GciRadius</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -441,9 +447,15 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_A2A_DISPATCHER).SetEngageRadius">AI_A2A_DISPATCHER:SetEngageRadius(FriendliesRadius)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_A2A_DISPATCHER).SetEngageRadius">AI_A2A_DISPATCHER:SetEngageRadius(EngageRadius)</a></td>
|
||||
<td class="summary">
|
||||
<p>Define the radius to engage any target by airborne friendlies, which are executing cap or returning from an intercept mission.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_A2A_DISPATCHER).SetGciRadius">AI_A2A_DISPATCHER:SetGciRadius(GciRadius)</a></td>
|
||||
<td class="summary">
|
||||
<p>Define the radius to check if a target can be engaged by an ground controlled intercept.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -1640,6 +1652,19 @@ If there are no targets to be set.</p>
|
||||
|
||||
<p>GCI Trigger for AI<em>A2A</em>DISPATCHER</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_A2A_DISPATCHER).GciRadius" >
|
||||
<strong>AI_A2A_DISPATCHER.GciRadius</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@ -2516,7 +2541,7 @@ An object derived from ZONE_BASE, that defines a zone between</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_A2A_DISPATCHER).SetEngageRadius" >
|
||||
<strong>AI_A2A_DISPATCHER:SetEngageRadius(FriendliesRadius)</strong>
|
||||
<strong>AI_A2A_DISPATCHER:SetEngageRadius(EngageRadius)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -2537,8 +2562,8 @@ If too large, any airborne cap may not be able to reach the detected target area
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number FriendliesRadius </em></code>:
|
||||
The radius to report friendlies near the target.</p>
|
||||
<p><code><em>#number EngageRadius </em></code>:
|
||||
(Optional, Default = 100000) The radius to report friendlies near the target.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
@ -2549,8 +2574,57 @@ The radius to report friendlies near the target.</p>
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<pre class="example"><code>
|
||||
-- Set 50km as the radius to engage any target by airborne friendlies.
|
||||
Dispatcher:SetEngageRadius( 50000 )
|
||||
|
||||
-- Set 100km as the radius to engage any target by airborne friendlies.
|
||||
Dispatcher:InitDetectionFriendiesRadius( 100000 )
|
||||
Dispatcher:SetEngageRadius() -- 100000 is the default value.
|
||||
</code></pre>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_A2A_DISPATCHER).SetGciRadius" >
|
||||
<strong>AI_A2A_DISPATCHER:SetGciRadius(GciRadius)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Define the radius to check if a target can be engaged by an ground controlled intercept.</p>
|
||||
|
||||
|
||||
<p>So, if there is a target area detected and reported,
|
||||
and a GCI is to be executed,
|
||||
then it will be check if the target is within the GCI from the nearest airbase.
|
||||
For example, if 150000 is given as a value, then any airbase within 150km from the detected target,
|
||||
will be considered to receive the command to GCI.
|
||||
You need to evaluate the value of this parameter carefully.
|
||||
If too small, intercept missions may be triggered too late.
|
||||
If too large, intercept missions may be triggered when the detected target is too far.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number GciRadius </em></code>:
|
||||
(Optional, Default = 200000) The radius to ground control intercept detected targets from the nearest airbase.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(AI_A2A_DISPATCHER)">#AI<em>A2A</em>DISPATCHER</a>:</em></p>
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<pre class="example"><code>
|
||||
-- Set 100km as the radius to ground control intercept detected targets from the nearest airbase.
|
||||
Dispatcher:SetGciRadius( 100000 )
|
||||
|
||||
-- Set 200km as the radius to ground control intercept.
|
||||
Dispatcher:SetGciRadius() -- 200000 is the default value.
|
||||
</code></pre>
|
||||
|
||||
</dd>
|
||||
|
||||
@ -607,6 +607,12 @@ The different values of Unit.Category can be:</p>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).GetDetectionSetGroup">DETECTION_BASE:GetDetectionSetGroup()</a></td>
|
||||
<td class="summary">
|
||||
<p>Get the detection Groups.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(DETECTION_BASE).GetFriendliesDistance">DETECTION_BASE:GetFriendliesDistance(DetectedItem)</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns friendly units nearby the FAC units sorted per distance ...</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -2971,6 +2977,32 @@ DetectedSet</p>
|
||||
<p><em><a href="Core.Set.html##(SET_GROUP)">Core.Set#SET_GROUP</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(DETECTION_BASE).GetFriendliesDistance" >
|
||||
<strong>DETECTION_BASE:GetFriendliesDistance(DetectedItem)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns friendly units nearby the FAC units sorted per distance ...</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> DetectedItem </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(map)">#map</a>:</em></p>
|
||||
<h1>number,Wrapper.Unit#UNIT> The map of Friendly UNITs.</h1>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
|
||||
@ -1604,7 +1604,7 @@ A string defining the start state.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<em>#string</em>
|
||||
<a id="#(FSM)._StartState" >
|
||||
<strong>FSM._StartState</strong>
|
||||
</a>
|
||||
@ -1903,7 +1903,6 @@ A string defining the start state.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(FSM).current" >
|
||||
<strong>FSM.current</strong>
|
||||
</a>
|
||||
|
||||
@ -227,7 +227,6 @@ on defined intervals (currently every minute).</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(MOVEMENT).AliveUnits" >
|
||||
<strong>MOVEMENT.AliveUnits</strong>
|
||||
</a>
|
||||
@ -236,9 +235,6 @@ on defined intervals (currently every minute).</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> Contains the counter how many units are currently alive</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
|
||||
@ -2799,6 +2799,7 @@ The y coordinate.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(POINT_VEC2).z" >
|
||||
<strong>POINT_VEC2.z</strong>
|
||||
</a>
|
||||
|
||||
@ -822,12 +822,6 @@ and any spaces before and after the resulting name are removed.</p>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SPAWN)._TranslateRotate">SPAWN:_TranslateRotate(SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, SpawnY, SpawnAngle)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(SPAWN).uncontrolled">SPAWN.uncontrolled</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -2735,9 +2729,6 @@ when nothing was spawned.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> Overwrite unit names by default with group name.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@ -2752,6 +2743,9 @@ when nothing was spawned.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> By default, no InitLimit</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@ -2787,7 +2781,7 @@ when nothing was spawned.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<em>#number</em>
|
||||
<a id="#(SPAWN).SpawnMaxGroups" >
|
||||
<strong>SPAWN.SpawnMaxGroups</strong>
|
||||
</a>
|
||||
@ -2804,7 +2798,7 @@ when nothing was spawned.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<em>#number</em>
|
||||
<a id="#(SPAWN).SpawnMaxUnitsAlive" >
|
||||
<strong>SPAWN.SpawnMaxUnitsAlive</strong>
|
||||
</a>
|
||||
@ -3156,7 +3150,7 @@ Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
|
||||
|
||||
|
||||
|
||||
<p> When the first Spawn executes, all the Groups need to be made visible before start.</p>
|
||||
<p> Flag that indicates if all the Groups of the SpawnGroup need to be visible when Spawned.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
@ -3736,20 +3730,6 @@ True = Continue Scheduler</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(SPAWN).uncontrolled" >
|
||||
<strong>SPAWN.uncontrolled</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
@ -510,7 +510,7 @@ based on the tasking capabilities defined in <a href="Task.html##(TASK)">Task#TA
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="Core.Cargo.html##(CARGO)">Core.Cargo#CARGO</a></em>
|
||||
<em></em>
|
||||
<a id="#(FSM_PROCESS).Cargo" >
|
||||
<strong>FSM_PROCESS.Cargo</strong>
|
||||
</a>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user