mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Finalized AI_DESIGNATE
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
--- **AI (Release 2.1)** -- Management of target designation.
|
||||
--
|
||||
-- --
|
||||
-- --
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -14,8 +14,27 @@ do -- AI_DESIGNATE
|
||||
|
||||
--- # AI_DESIGNATE class, extends @{Fsm#FSM}
|
||||
--
|
||||
-- AI_DESIGNATE is orchestrating the designation of potential targets, and communicate these to a dedicated attacking group
|
||||
-- of players, so that following a dynamically generated menu system, each detected set of potential targets can be lased or smoked...
|
||||
-- AI_DESIGNATE is orchestrating the designation of potential targets executed by a Recce group,
|
||||
-- and communicates these to a dedicated attacking group of players,
|
||||
-- so that following a dynamically generated menu system,
|
||||
-- each detected set of potential targets can be lased or smoked...
|
||||
--
|
||||
-- The Recce group is detecting as part of the DETECTION_ class continuously targets.
|
||||
-- Once targets have been detected, they will be reported. The AI_DESIGNATE object will fire the **Detect** event in this case!
|
||||
-- As part of the reporting, the following happens:
|
||||
--
|
||||
-- * A message is sent to each GROUP of the Attack SET_GROUP, containing the threat level and the target composition.
|
||||
-- * A menu is created and updated for each GROUP of the Attack SET_GROUP, containing the the treat level and the target composition.
|
||||
--
|
||||
-- One of the players in one of the Attack GROUPs, can then select a Target Set by selecting one of the menu options.
|
||||
-- Each menu option has two modes:
|
||||
--
|
||||
-- * If the Target Set is not being designated, then the Designate menu for the target Set will provide options to Lase or Smoke the targets.
|
||||
-- * If the Target Set is being designated, then the Designate menu will provide an option to cancel the designation.
|
||||
--
|
||||
-- In this way, the AI can assist players to designate ground targets for a coordinated attack!
|
||||
--
|
||||
-- Have FUN!
|
||||
--
|
||||
-- ## 1. AI_DESIGNATE constructor
|
||||
--
|
||||
@@ -35,7 +54,27 @@ do -- AI_DESIGNATE
|
||||
-- * **@{#AI_DESIGNATE.LaseOn}**: Lase the targets with the specified Index.
|
||||
-- * **@{#AI_DESIGNATE.LaseOff}**: Stop lasing the targets with the specified Index.
|
||||
-- * **@{#AI_DESIGNATE.Smoke}**: Smoke the targets with the specified Index.
|
||||
-- * **@{#AI_DESIGNATE.}Status**: Report designation status.
|
||||
-- * **@{#AI_DESIGNATE.Status}**: Report designation status.
|
||||
--
|
||||
-- ## 3. Set laser codes
|
||||
--
|
||||
-- An array of laser codes can be provided, that will be used by the AI_DESIGNATE when lasing.
|
||||
-- The laser code is communicated by the Recce when it is lasing a larget.
|
||||
-- Note that the default laser code is 1113.
|
||||
-- Working known laser codes are: 1113,1462,1483,1537,1362,1214,1131,1182,1644,1614,1515,1411,1621,1138,1542,1678,1573,1314,1643,1257,1467,1375,1341,1275,1237
|
||||
--
|
||||
-- Use the method @{#AI_DESIGNATE.SetLaserCodes}() to set the possible laser codes to be selected from.
|
||||
-- One laser code can be given or an sequence of laser codes through an table...
|
||||
--
|
||||
-- AIDesignate:SetLaserCodes( 1214 )
|
||||
--
|
||||
-- The above sets one laser code with the value 1214.
|
||||
--
|
||||
-- AIDesignate:SetLaserCodes( { 1214, 1131, 1614, 1138 } )
|
||||
--
|
||||
-- The above sets a collection of possible laser codes that can be assigned. **Note the { } notation!**
|
||||
--
|
||||
--
|
||||
--
|
||||
-- @field #AI_DESIGNATE
|
||||
--
|
||||
@@ -55,21 +94,168 @@ do -- AI_DESIGNATE
|
||||
|
||||
self:SetStartState( "Designating" )
|
||||
self:AddTransition( "*", "Detect", "*" )
|
||||
|
||||
--- Detect Handler OnBefore for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE] OnBeforeDetect
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Detect Handler OnAfter for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE] OnAfterDetect
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Detect Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE] Detect
|
||||
-- @param #AI_DESIGNATE self
|
||||
|
||||
--- Detect Asynchronous Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE] __Detect
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #number Delay
|
||||
|
||||
self:AddTransition( "*", "LaseOn", "*" )
|
||||
|
||||
--- LaseOn Handler OnBefore for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnBeforeLaseOn
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- LaseOn Handler OnAfter for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnAfterLaseOn
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- LaseOn Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] LaseOn
|
||||
-- @param #AI_DESIGNATE self
|
||||
|
||||
--- LaseOn Asynchronous Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] __LaseOn
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
|
||||
self:AddTransition( "*", "LaseOff", "*" )
|
||||
|
||||
--- LaseOff Handler OnBefore for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnBeforeLaseOff
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- LaseOff Handler OnAfter for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnAfterLaseOff
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- LaseOff Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] LaseOff
|
||||
-- @param #AI_DESIGNATE self
|
||||
|
||||
--- LaseOff Asynchronous Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] __LaseOff
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
|
||||
self:AddTransition( "*", "Smoke", "*" )
|
||||
|
||||
--- Smoke Handler OnBefore for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnBeforeSmoke
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Smoke Handler OnAfter for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnAfterSmoke
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Smoke Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] Smoke
|
||||
-- @param #AI_DESIGNATE self
|
||||
|
||||
--- Smoke Asynchronous Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] __Smoke
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
|
||||
self:AddTransition( "*", "Status", "*" )
|
||||
|
||||
|
||||
--- Status Handler OnBefore for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnBeforeStatus
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Status Handler OnAfter for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] OnAfterStatus
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Status Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] Status
|
||||
-- @param #AI_DESIGNATE self
|
||||
|
||||
--- Status Asynchronous Trigger for AI_DESIGNATE
|
||||
-- @function [parent=#AI_DESIGNATE ] __Status
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #number Delay
|
||||
|
||||
self.Detection = Detection
|
||||
self.GroupSet = GroupSet
|
||||
self.RecceSet = Detection:GetDetectionSetGroup()
|
||||
self.Spots = {}
|
||||
|
||||
self:SetLaserCodes( 1113 )
|
||||
|
||||
self.Detection:__Start( 2 )
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set an array of possible laser codes.
|
||||
-- Each new lase will select a code from this table.
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @param #list<#number> LaserCodes
|
||||
-- @return #AI_DESIGNATE
|
||||
function AI_DESIGNATE:SetLaserCodes( LaserCodes )
|
||||
|
||||
self.LaserCodes = ( type( LaserCodes ) == "table" ) and LaserCodes or { LaserCodes }
|
||||
self:E(self.LaserCodes)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #AI_DESIGNATE self
|
||||
@@ -78,75 +264,112 @@ do -- AI_DESIGNATE
|
||||
|
||||
self:__Detect( -60 )
|
||||
|
||||
self:SendStatus()
|
||||
self:SetDesignateMenu()
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sends the status to the Attack Groups.
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @return #AI_DESIGNATE
|
||||
function AI_DESIGNATE:SendStatus()
|
||||
|
||||
local DetectedReport = REPORT:New( "Targets ready to be designated:" )
|
||||
local DetectedItems = self.Detection:GetDetectedItems()
|
||||
|
||||
for Index, DetectedItemData in pairs( DetectedItems ) do
|
||||
|
||||
local Report = self.Detection:DetectedItemReportSummary( Index )
|
||||
DetectedReport:Add(" - " .. Report)
|
||||
end
|
||||
|
||||
local RecceLeader = self.RecceSet:GetFirst() -- Wrapper.Group#GROUP
|
||||
|
||||
self.GroupSet:ForEachGroup(
|
||||
|
||||
--- @param Wrapper.Group#GROUP GroupReport
|
||||
function( GroupReport )
|
||||
|
||||
self:E(GroupReport:GetName())
|
||||
|
||||
local DesignateMenu = GroupReport:GetState( GroupReport, "DesignateMenu" ) -- Core.Menu#MENU_GROUP
|
||||
function( AttackGroup )
|
||||
RecceLeader:MessageToGroup( DetectedReport:Text( "\n" ), 15, AttackGroup )
|
||||
end
|
||||
)
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Sets the Designate Menu.
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @return #AI_DESIGNATE
|
||||
function AI_DESIGNATE:SetDesignateMenu()
|
||||
|
||||
self.GroupSet:ForEachGroup(
|
||||
|
||||
--- @param Wrapper.Group#GROUP GroupReport
|
||||
function( AttackGroup )
|
||||
local DesignateMenu = AttackGroup:GetState( AttackGroup, "DesignateMenu" ) -- Core.Menu#MENU_GROUP
|
||||
if DesignateMenu then
|
||||
DesignateMenu:Remove()
|
||||
DesignateMenu = nil
|
||||
self:E("Remove Menu")
|
||||
end
|
||||
DesignateMenu = MENU_GROUP:New( GroupReport, "Designate Targets" )
|
||||
DesignateMenu = MENU_GROUP:New( AttackGroup, "Designate Targets" )
|
||||
self:E(DesignateMenu)
|
||||
GroupReport:SetState( GroupReport, "DesignateMenu", DesignateMenu )
|
||||
AttackGroup:SetState( AttackGroup, "DesignateMenu", DesignateMenu )
|
||||
|
||||
|
||||
local DetectedItems = self.Detection:GetDetectedItems()
|
||||
|
||||
for Index, DetectedItemData in pairs( DetectedItems ) do
|
||||
|
||||
local DetectedReport = self.Detection:DetectedItemReportSummary( Index )
|
||||
|
||||
GroupReport:MessageToAll( DetectedReport, 15, "Detected" )
|
||||
local Report = self.Detection:DetectedItemReportSummary( Index )
|
||||
|
||||
local DetectedMenu = MENU_GROUP:New(
|
||||
GroupReport,
|
||||
DetectedReport,
|
||||
AttackGroup,
|
||||
Report,
|
||||
DesignateMenu
|
||||
)
|
||||
|
||||
if self.Spots[Index] then
|
||||
|
||||
MENU_GROUP_COMMAND:New(
|
||||
GroupReport,
|
||||
AttackGroup,
|
||||
"Switch laser Off",
|
||||
DetectedMenu,
|
||||
self.MenuLaseOff,
|
||||
self,
|
||||
AttackGroup,
|
||||
Index
|
||||
)
|
||||
else
|
||||
MENU_GROUP_COMMAND:New(
|
||||
GroupReport,
|
||||
AttackGroup,
|
||||
"Lase target 60 secs",
|
||||
DetectedMenu,
|
||||
self.MenuLaseOn,
|
||||
self,
|
||||
AttackGroup,
|
||||
Index,
|
||||
60
|
||||
)
|
||||
MENU_GROUP_COMMAND:New(
|
||||
GroupReport,
|
||||
AttackGroup,
|
||||
"Lase target 120 secs",
|
||||
DetectedMenu,
|
||||
self.MenuLaseOn,
|
||||
self,
|
||||
AttackGroup,
|
||||
Index,
|
||||
120
|
||||
)
|
||||
end
|
||||
|
||||
MENU_GROUP_COMMAND:New(
|
||||
GroupReport,
|
||||
AttackGroup,
|
||||
"Smoke",
|
||||
DetectedMenu,
|
||||
self.MenuSmoke,
|
||||
self,
|
||||
AttackGroup,
|
||||
Index
|
||||
)
|
||||
|
||||
@@ -154,41 +377,41 @@ do -- AI_DESIGNATE
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
---
|
||||
-- @param #AI_DESIGNATE self
|
||||
function AI_DESIGNATE:MenuSmoke( Index )
|
||||
function AI_DESIGNATE:MenuSmoke( AttackGroup, Index )
|
||||
|
||||
self:E("Designate through Smoke")
|
||||
|
||||
self:__Smoke( 1, Index )
|
||||
self:__Smoke( 1, AttackGroup, Index )
|
||||
end
|
||||
|
||||
---
|
||||
-- @param #AI_DESIGNATE self
|
||||
function AI_DESIGNATE:MenuLaseOn( Index, Duration )
|
||||
function AI_DESIGNATE:MenuLaseOn( AttackGroup, Index, Duration )
|
||||
|
||||
self:E("Designate through Lase")
|
||||
|
||||
self:__LaseOn( 1, Index, Duration )
|
||||
self:__LaseOn( 1, AttackGroup, Index, Duration )
|
||||
end
|
||||
|
||||
---
|
||||
-- @param #AI_DESIGNATE self
|
||||
function AI_DESIGNATE:MenuLaseOff( Index, Duration )
|
||||
function AI_DESIGNATE:MenuLaseOff( AttackGroup, Index, Duration )
|
||||
|
||||
self:E("Lasing off")
|
||||
|
||||
self:__LaseOff( 1, Index )
|
||||
self:__LaseOff( 1, AttackGroup, Index )
|
||||
end
|
||||
|
||||
---
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @return #AI_DESIGNATE
|
||||
function AI_DESIGNATE:onafterLaseOn( From, Event, To, Index, Duration )
|
||||
function AI_DESIGNATE:onafterLaseOn( From, Event, To, AttackGroup, Index, Duration )
|
||||
|
||||
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
|
||||
|
||||
@@ -203,7 +426,12 @@ do -- AI_DESIGNATE
|
||||
for UnitID, UnitData in pairs( NearestRecceGroup:GetUnits() or {} ) do
|
||||
local RecceUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
if RecceUnit:IsLasing() == false then
|
||||
self.Spots[Index] = RecceUnit:LaseUnit( SmokeUnit, nil, Duration )
|
||||
self.Spots[Index] = self.Spots[Index] or {}
|
||||
local Spots = self.Spots[Index]
|
||||
local LaserCode = self.LaserCodes[math.random(1, #self.LaserCodes)]
|
||||
local Spot = RecceUnit:LaseUnit( SmokeUnit, LaserCode, Duration )
|
||||
Spots[#Spots+1] = Spot
|
||||
RecceUnit:MessageToGroup( "Lasing " .. SmokeUnit:GetTypeName() .. " for " .. Duration .. " seconds. Laser Code: " .. Spot.LaserCode, 15, AttackGroup )
|
||||
break
|
||||
end
|
||||
end
|
||||
@@ -212,25 +440,37 @@ do -- AI_DESIGNATE
|
||||
--end
|
||||
end
|
||||
)
|
||||
|
||||
self:SetDesignateMenu()
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @return #AI_DESIGNATE
|
||||
function AI_DESIGNATE:onafterLaseOff( From, Event, To, Index )
|
||||
function AI_DESIGNATE:onafterLaseOff( From, Event, To, AttackGroup, Index )
|
||||
|
||||
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
|
||||
|
||||
self.Spots[Index]:LaseOff()
|
||||
local Spots = self.Spots[Index]
|
||||
|
||||
for SpotID, SpotData in pairs( Spots ) do
|
||||
local Spot = SpotData -- Core.Spot#SPOT
|
||||
Spot.Recce:MessageToGroup( "Stopped lasing " .. Spot.Target:GetTypeName() .. ".", 15, AttackGroup )
|
||||
Spot:LaseOff()
|
||||
end
|
||||
|
||||
Spots = nil
|
||||
self.Spots[Index] = nil
|
||||
|
||||
self:SetDesignateMenu()
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #AI_DESIGNATE self
|
||||
-- @return #AI_DESIGNATE
|
||||
function AI_DESIGNATE:onafterSmoke( From, Event, To, Index )
|
||||
function AI_DESIGNATE:onafterSmoke( From, Event, To, AttackGroup, Index )
|
||||
|
||||
|
||||
local TargetSetUnit = self.Detection:GetDetectedSet( Index )
|
||||
|
||||
@@ -568,7 +568,7 @@ do -- DETECTION_BASE
|
||||
|
||||
local DetectedUnitCategory = DetectedObject:getDesc().category
|
||||
|
||||
self:T( { "Detected Target:", DetectionGroupName, DetectedObjectName, Distance, DetectedUnitCategory, DetectedCategory } )
|
||||
self:T( { "Detected Target:", DetectionGroupName, DetectedObjectName, Distance, DetectedUnitCategory } )
|
||||
|
||||
-- Calculate Acceptance
|
||||
|
||||
|
||||
@@ -311,7 +311,8 @@ function POSITIONABLE:GetMessage( Message, Duration, Name )
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
Name = Name or self:GetTypeName()
|
||||
return MESSAGE:New( Message, Duration, self:GetCallsign() .. " (" .. Name .. ")" )
|
||||
local Callsign = self:GetCallsign() ~= "" and self:GetCallsign() or self:GetName()
|
||||
return MESSAGE:New( Message, Duration, Callsign .. " (" .. Name .. ")" )
|
||||
end
|
||||
|
||||
return nil
|
||||
@@ -456,7 +457,7 @@ end
|
||||
-- @param #POSITIONABLE Target
|
||||
-- @param #number LaserCode
|
||||
-- @param #number Duration
|
||||
-- @return Spot
|
||||
-- @return Core.Spot#SPOT
|
||||
function POSITIONABLE:LaseUnit( Target, LaserCode, Duration )
|
||||
self:F2()
|
||||
|
||||
@@ -467,7 +468,7 @@ function POSITIONABLE:LaseUnit( Target, LaserCode, Duration )
|
||||
|
||||
self:E("bulding spot")
|
||||
self.Spot = SPOT:New( self )
|
||||
self.Spot:LaseOn( Target:GetPointVec3(), LaserCode, Duration)
|
||||
self.Spot:LaseOn( Target, LaserCode, Duration)
|
||||
|
||||
return self.Spot
|
||||
|
||||
|
||||
Reference in New Issue
Block a user