Merge branch 'master' into funkyfranky

This commit is contained in:
funkyfranky
2017-10-06 18:28:34 +02:00
119 changed files with 37995 additions and 1467 deletions

View File

@@ -4,7 +4,7 @@
--
-- ===
--
-- AI CAP classes makes AI Controllables execute a Combat Air Patrol.
-- AI CAP classes makes AI Groups execute a Combat Air Patrol.
--
-- There are the following types of CAP classes defined:
--
@@ -34,7 +34,7 @@
--- # AI_A2A_CAP class, extends @{AI_CAP#AI_PATROL_ZONE}
--
-- The AI_A2A_CAP class implements the core functions to patrol a @{Zone} by an AI @{Controllable} or @{Group}
-- The AI_A2A_CAP class implements the core functions to patrol a @{Zone} by an AI @{Group} or @{Group}
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
--
-- ![Process](..\Presentations\AI_CAP\Dia3.JPG)
@@ -120,20 +120,20 @@ AI_A2A_CAP = {
--- Creates a new AI_A2A_CAP object
-- @param #AI_A2A_CAP self
-- @param Wrapper.Group#GROUP AIGroup
-- @param Wrapper.Group#GROUP AICap
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Dcs.DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
-- @param Dcs.DCSTypes#Speed EngageMinSpeed The minimum speed of the @{Controllable} in km/h when engaging a target.
-- @param Dcs.DCSTypes#Speed EngageMaxSpeed The maximum speed of the @{Controllable} in km/h when engaging a target.
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h.
-- @param Dcs.DCSTypes#Speed EngageMinSpeed The minimum speed of the @{Group} in km/h when engaging a target.
-- @param Dcs.DCSTypes#Speed EngageMaxSpeed The maximum speed of the @{Group} in km/h when engaging a target.
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
-- @return #AI_A2A_CAP
function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, PatrolAltType )
function AI_A2A_CAP:New( AICap, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, EngageMinSpeed, EngageMaxSpeed, PatrolAltType )
-- Inherits from BASE
local self = BASE:Inherit( self, AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2A_CAP
local self = BASE:Inherit( self, AI_A2A_PATROL:New( AICap, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2A_CAP
self.Accomplished = false
self.Engaging = false
@@ -146,7 +146,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnBefore Transition Handler for Event Engage.
-- @function [parent=#AI_A2A_CAP] OnBeforeEngage
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -155,7 +155,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnAfter Transition Handler for Event Engage.
-- @function [parent=#AI_A2A_CAP] OnAfterEngage
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -172,7 +172,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnLeave Transition Handler for State Engaging.
-- @function [parent=#AI_A2A_CAP] OnLeaveEngaging
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -181,7 +181,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnEnter Transition Handler for State Engaging.
-- @function [parent=#AI_A2A_CAP] OnEnterEngaging
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -191,7 +191,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnBefore Transition Handler for Event Fired.
-- @function [parent=#AI_A2A_CAP] OnBeforeFired
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -200,7 +200,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnAfter Transition Handler for Event Fired.
-- @function [parent=#AI_A2A_CAP] OnAfterFired
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -219,7 +219,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnBefore Transition Handler for Event Destroy.
-- @function [parent=#AI_A2A_CAP] OnBeforeDestroy
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -228,7 +228,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnAfter Transition Handler for Event Destroy.
-- @function [parent=#AI_A2A_CAP] OnAfterDestroy
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -248,7 +248,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnBefore Transition Handler for Event Abort.
-- @function [parent=#AI_A2A_CAP] OnBeforeAbort
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -257,7 +257,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnAfter Transition Handler for Event Abort.
-- @function [parent=#AI_A2A_CAP] OnAfterAbort
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -276,7 +276,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnBefore Transition Handler for Event Accomplish.
-- @function [parent=#AI_A2A_CAP] OnBeforeAccomplish
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -285,7 +285,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
--- OnAfter Transition Handler for Event Accomplish.
-- @function [parent=#AI_A2A_CAP] OnAfterAccomplish
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -304,13 +304,13 @@ end
--- onafter State Transition for Event Patrol.
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_CAP:onafterStart( AIGroup, From, Event, To )
function AI_A2A_CAP:onafterStart( AICap, From, Event, To )
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
AICap:HandleEvent( EVENTS.Takeoff, nil, self )
end
@@ -344,36 +344,36 @@ end
--- onafter State Transition for Event Patrol.
-- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The AI Group managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_CAP:onafterPatrol( AIGroup, From, Event, To )
function AI_A2A_CAP:onafterPatrol( AICap, From, Event, To )
-- Call the parent Start event handler
self:GetParent(self).onafterPatrol( self, AIGroup, From, Event, To )
self:GetParent(self).onafterPatrol( self, AICap, From, Event, To )
self:HandleEvent( EVENTS.Dead )
end
-- todo: need to fix this global function
--- @param Wrapper.Group#GROUP AIGroup
function AI_A2A_CAP.AttackRoute( AIGroup, Fsm )
--- @param Wrapper.Group#GROUP AICap
function AI_A2A_CAP.AttackRoute( AICap, Fsm )
AIGroup:F( { "AI_A2A_CAP.AttackRoute:", AIGroup:GetName() } )
AICap:F( { "AI_A2A_CAP.AttackRoute:", AICap:GetName() } )
if AIGroup:IsAlive() then
if AICap:IsAlive() then
Fsm:__Engage( 0.5 )
end
end
--- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_CAP:onbeforeEngage( AIGroup, From, Event, To )
function AI_A2A_CAP:onbeforeEngage( AICap, From, Event, To )
if self.Accomplished == true then
return false
@@ -381,24 +381,24 @@ function AI_A2A_CAP:onbeforeEngage( AIGroup, From, Event, To )
end
--- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The AI Group managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_CAP:onafterAbort( AIGroup, From, Event, To )
AIGroup:ClearTasks()
function AI_A2A_CAP:onafterAbort( AICap, From, Event, To )
AICap:ClearTasks()
self:__Route( 0.5 )
end
--- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The AICap Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
function AI_A2A_CAP:onafterEngage( AICap, From, Event, To, AttackSetUnit )
self:F( { AIGroup, From, Event, To, AttackSetUnit} )
self:F( { AICap, From, Event, To, AttackSetUnit} )
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
@@ -406,12 +406,12 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
if FirstAttackUnit and FirstAttackUnit:IsAlive() then -- If there is no attacker anymore, stop the engagement.
if AIGroup:IsAlive() then
if AICap:IsAlive() then
local EngageRoute = {}
--- Calculate the target route point.
local CurrentCoord = AIGroup:GetCoordinate()
local CurrentCoord = AICap:GetCoordinate()
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
local ToInterceptAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
@@ -437,7 +437,7 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
self:T( { "Attacking Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
AttackTasks[#AttackTasks+1] = AICap:TaskAttackUnit( AttackUnit )
end
end
@@ -445,14 +445,14 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
self:E("No targets found -> Going back to Patrolling")
self:__Abort( 0.5 )
else
AIGroup:OptionROEOpenFire()
AIGroup:OptionROTPassiveDefense()
AICap:OptionROEOpenFire()
AICap:OptionROTEvadeFire()
AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( "AI_A2A_CAP.AttackRoute", self )
EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( AttackTasks )
AttackTasks[#AttackTasks+1] = AICap:TaskFunction( "AI_A2A_CAP.AttackRoute", self )
EngageRoute[#EngageRoute].task = AICap:TaskCombo( AttackTasks )
end
AIGroup:Route( EngageRoute, 0.5 )
AICap:Route( EngageRoute, 0.5 )
end
else
self:E("No targets found -> Going back to Patrolling")
@@ -461,22 +461,22 @@ function AI_A2A_CAP:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
end
--- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_CAP:onafterAccomplish( Controllable, From, Event, To )
function AI_A2A_CAP:onafterAccomplish( AICap, From, Event, To )
self.Accomplished = true
self:SetDetectionOff()
end
--- @param #AI_A2A_CAP self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AICap The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Core.Event#EVENTDATA EventData
function AI_A2A_CAP:onafterDestroy( Controllable, From, Event, To, EventData )
function AI_A2A_CAP:onafterDestroy( AICap, From, Event, To, EventData )
if EventData.IniUnit then
self.AttackUnits[EventData.IniUnit] = nil
@@ -495,12 +495,12 @@ function AI_A2A_CAP:OnEventDead( EventData )
end
end
--- @param Wrapper.Group#GROUP AIGroup
function AI_A2A_CAP.Resume( AIGroup )
--- @param Wrapper.Group#GROUP AICap
function AI_A2A_CAP.Resume( AICap )
AIGroup:F( { "AI_A2A_CAP.Resume:", AIGroup:GetName() } )
if AIGroup:IsAlive() then
local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A
AICap:F( { "AI_A2A_CAP.Resume:", AICap:GetName() } )
if AICap:IsAlive() then
local _AI_A2A = AICap:GetState( AICap, "AI_A2A" ) -- #AI_A2A
_AI_A2A:__Reset( 1 )
_AI_A2A:__Route( 5 )
end

View File

@@ -117,12 +117,12 @@ AI_A2A_GCI = {
--- Creates a new AI_A2A_GCI object
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup
-- @param Wrapper.Group#GROUP AIIntercept
-- @return #AI_A2A_GCI
function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
function AI_A2A_GCI:New( AIIntercept, EngageMinSpeed, EngageMaxSpeed )
-- Inherits from BASE
local self = BASE:Inherit( self, AI_A2A:New( AIGroup ) ) -- #AI_A2A_GCI
local self = BASE:Inherit( self, AI_A2A:New( AIIntercept ) ) -- #AI_A2A_GCI
self.Accomplished = false
self.Engaging = false
@@ -139,7 +139,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnBefore Transition Handler for Event Engage.
-- @function [parent=#AI_A2A_GCI] OnBeforeEngage
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -148,7 +148,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnAfter Transition Handler for Event Engage.
-- @function [parent=#AI_A2A_GCI] OnAfterEngage
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -165,7 +165,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnLeave Transition Handler for State Engaging.
-- @function [parent=#AI_A2A_GCI] OnLeaveEngaging
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -174,7 +174,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnEnter Transition Handler for State Engaging.
-- @function [parent=#AI_A2A_GCI] OnEnterEngaging
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -184,7 +184,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnBefore Transition Handler for Event Fired.
-- @function [parent=#AI_A2A_GCI] OnBeforeFired
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -193,7 +193,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnAfter Transition Handler for Event Fired.
-- @function [parent=#AI_A2A_GCI] OnAfterFired
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -212,7 +212,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnBefore Transition Handler for Event Destroy.
-- @function [parent=#AI_A2A_GCI] OnBeforeDestroy
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -221,7 +221,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnAfter Transition Handler for Event Destroy.
-- @function [parent=#AI_A2A_GCI] OnAfterDestroy
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -241,7 +241,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnBefore Transition Handler for Event Abort.
-- @function [parent=#AI_A2A_GCI] OnBeforeAbort
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -250,7 +250,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnAfter Transition Handler for Event Abort.
-- @function [parent=#AI_A2A_GCI] OnAfterAbort
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -269,7 +269,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnBefore Transition Handler for Event Accomplish.
-- @function [parent=#AI_A2A_GCI] OnBeforeAccomplish
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -278,7 +278,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
--- OnAfter Transition Handler for Event Accomplish.
-- @function [parent=#AI_A2A_GCI] OnAfterAccomplish
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -297,13 +297,13 @@ end
--- onafter State Transition for Event Patrol.
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_GCI:onafterStart( AIGroup, From, Event, To )
function AI_A2A_GCI:onafterStart( AIIntercept, From, Event, To )
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
AIIntercept:HandleEvent( EVENTS.Takeoff, nil, self )
end
@@ -311,11 +311,11 @@ end
--- onafter State Transition for Event Patrol.
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To )
function AI_A2A_GCI:onafterEngage( AIIntercept, From, Event, To )
self:HandleEvent( EVENTS.Dead )
@@ -324,24 +324,24 @@ end
-- todo: need to fix this global function
--- @param Wrapper.Group#GROUP AIControllable
function AI_A2A_GCI.InterceptRoute( AIGroup, Fsm )
function AI_A2A_GCI.InterceptRoute( AIIntercept, Fsm )
AIGroup:F( { "AI_A2A_GCI.InterceptRoute:", AIGroup:GetName() } )
AIIntercept:F( { "AI_A2A_GCI.InterceptRoute:", AIIntercept:GetName() } )
if AIGroup:IsAlive() then
if AIIntercept:IsAlive() then
Fsm:__Engage( 0.5 )
--local Task = AIGroup:TaskOrbitCircle( 4000, 400 )
--AIGroup:SetTask( Task )
--local Task = AIIntercept:TaskOrbitCircle( 4000, 400 )
--AIIntercept:SetTask( Task )
end
end
--- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_GCI:onbeforeEngage( AIGroup, From, Event, To )
function AI_A2A_GCI:onbeforeEngage( AIIntercept, From, Event, To )
if self.Accomplished == true then
return false
@@ -349,25 +349,25 @@ function AI_A2A_GCI:onbeforeEngage( AIGroup, From, Event, To )
end
--- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_GCI:onafterAbort( AIGroup, From, Event, To )
AIGroup:ClearTasks()
function AI_A2A_GCI:onafterAbort( AIIntercept, From, Event, To )
AIIntercept:ClearTasks()
self:Return()
self:__RTB( 0.5 )
end
--- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The GroupGroup managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
function AI_A2A_GCI:onafterEngage( AIIntercept, From, Event, To, AttackSetUnit )
self:F( { AIGroup, From, Event, To, AttackSetUnit} )
self:F( { AIIntercept, From, Event, To, AttackSetUnit} )
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
@@ -375,15 +375,15 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
if FirstAttackUnit and FirstAttackUnit:IsAlive() then
if AIGroup:IsAlive() then
if AIIntercept:IsAlive() then
local EngageRoute = {}
local CurrentCoord = AIGroup:GetCoordinate()
local CurrentCoord = AIIntercept:GetCoordinate()
--- Calculate the target route point.
local CurrentCoord = AIGroup:GetCoordinate()
local CurrentCoord = AIIntercept:GetCoordinate()
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
@@ -412,7 +412,7 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
self:T( { "Intercepting Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
AttackTasks[#AttackTasks+1] = AIIntercept:TaskAttackUnit( AttackUnit )
end
end
@@ -421,14 +421,14 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
self:Return()
self:__RTB( 0.5 )
else
AIGroup:OptionROEOpenFire()
AIGroup:OptionROTPassiveDefense()
AIIntercept:OptionROEOpenFire()
AIIntercept:OptionROTEvadeFire()
AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( "AI_A2A_GCI.InterceptRoute", self )
EngageRoute[#EngageRoute].task = AIGroup:TaskCombo( AttackTasks )
AttackTasks[#AttackTasks+1] = AIIntercept:TaskFunction( "AI_A2A_GCI.InterceptRoute", self )
EngageRoute[#EngageRoute].task = AIIntercept:TaskCombo( AttackTasks )
end
AIGroup:Route( EngageRoute, 0.5 )
AIIntercept:Route( EngageRoute, 0.5 )
end
else
@@ -439,22 +439,22 @@ function AI_A2A_GCI:onafterEngage( AIGroup, From, Event, To, AttackSetUnit )
end
--- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_GCI:onafterAccomplish( AIGroup, From, Event, To )
function AI_A2A_GCI:onafterAccomplish( AIIntercept, From, Event, To )
self.Accomplished = true
self:SetDetectionOff()
end
--- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIIntercept The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
-- @param Core.Event#EVENTDATA EventData
function AI_A2A_GCI:onafterDestroy( AIGroup, From, Event, To, EventData )
function AI_A2A_GCI:onafterDestroy( AIIntercept, From, Event, To, EventData )
if EventData.IniUnit then
self.AttackUnits[EventData.IniUnit] = nil

View File

@@ -4,7 +4,7 @@
--
-- ===
--
-- AI PATROL classes makes AI Controllables execute an Patrol.
-- AI PATROL classes makes AI Groups execute an Patrol.
--
-- There are the following types of PATROL classes defined:
--
@@ -44,7 +44,7 @@
--- # AI_A2A_PATROL class, extends @{Fsm#FSM_CONTROLLABLE}
--
-- The AI_A2A_PATROL class implements the core functions to patrol a @{Zone} by an AI @{Controllable} or @{Group}.
-- The AI_A2A_PATROL class implements the core functions to patrol a @{Zone} by an AI @{Group} or @{Group}.
--
-- ![Process](..\Presentations\AI_PATROL\Dia3.JPG)
--
@@ -139,7 +139,7 @@
--
-- ## 7. Manage "damage" behaviour of the AI in the AI_A2A_PATROL
--
-- When the AI is damaged, it is required that a new AIControllable is started. However, damage cannon be foreseen early on.
-- When the AI is damaged, it is required that a new Patrol is started. However, damage cannon be foreseen early on.
-- Therefore, when the damage treshold is reached, the AI will return immediately to the home base (RTB).
-- Use the method @{#AI_A2A_PATROL.ManageDamage}() to have this proces in place.
--
@@ -152,23 +152,23 @@ AI_A2A_PATROL = {
--- Creates a new AI_A2A_PATROL object
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Group#GROUP AIGroup
-- @param Wrapper.Group#GROUP AIPatrol
-- @param Core.Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed.
-- @param Dcs.DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
-- @param Dcs.DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol.
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h.
-- @param Dcs.DCSTypes#AltitudeType PatrolAltType The altitude type ("RADIO"=="AGL", "BARO"=="ASL"). Defaults to RADIO
-- @return #AI_A2A_PATROL self
-- @usage
-- -- Define a new AI_A2A_PATROL Object. This PatrolArea will patrol an AIControllable within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h.
-- -- Define a new AI_A2A_PATROL Object. This PatrolArea will patrol a Group within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h.
-- PatrolZone = ZONE:New( 'PatrolZone' )
-- PatrolSpawn = SPAWN:New( 'Patrol Group' )
-- PatrolArea = AI_A2A_PATROL:New( PatrolZone, 3000, 6000, 600, 900 )
function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
function AI_A2A_PATROL:New( AIPatrol, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType )
-- Inherits from BASE
local self = BASE:Inherit( self, AI_A2A:New( AIGroup ) ) -- #AI_A2A_PATROL
local self = BASE:Inherit( self, AI_A2A:New( AIPatrol ) ) -- #AI_A2A_PATROL
self.PatrolZone = PatrolZone
self.PatrolFloorAltitude = PatrolFloorAltitude
@@ -184,7 +184,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
--- OnBefore Transition Handler for Event Patrol.
-- @function [parent=#AI_A2A_PATROL] OnBeforePatrol
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -193,7 +193,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
--- OnAfter Transition Handler for Event Patrol.
-- @function [parent=#AI_A2A_PATROL] OnAfterPatrol
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -210,7 +210,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
--- OnLeave Transition Handler for State Patrolling.
-- @function [parent=#AI_A2A_PATROL] OnLeavePatrolling
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -219,7 +219,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
--- OnEnter Transition Handler for State Patrolling.
-- @function [parent=#AI_A2A_PATROL] OnEnterPatrolling
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -229,7 +229,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
--- OnBefore Transition Handler for Event Route.
-- @function [parent=#AI_A2A_PATROL] OnBeforeRoute
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -238,7 +238,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
--- OnAfter Transition Handler for Event Route.
-- @function [parent=#AI_A2A_PATROL] OnAfterRoute
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
@@ -264,8 +264,8 @@ end
--- Sets (modifies) the minimum and maximum speed of the patrol.
-- @param #AI_A2A_PATROL self
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h.
-- @param Dcs.DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h.
-- @return #AI_A2A_PATROL self
function AI_A2A_PATROL:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
self:F2( { PatrolMinSpeed, PatrolMaxSpeed } )
@@ -292,18 +292,18 @@ end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
-- @param #AI_A2A_PATROL self
-- @return #AI_A2A_PATROL self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group Object managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_PATROL:onafterPatrol( Controllable, From, Event, To )
function AI_A2A_PATROL:onafterPatrol( AIPatrol, From, Event, To )
self:F2()
self:ClearTargetDistance()
self:__Route( 1 )
self.Controllable:OnReSpawn(
self.AIPatrol:OnReSpawn(
function( PatrolGroup )
self:E( "ReSpawn" )
self:__Reset( 1 )
@@ -314,14 +314,14 @@ end
--- @param Wrapper.Group#GROUP AIGroup
-- This statis method is called from the route path within the last task at the last waaypoint of the Controllable.
-- Note that this method is required, as triggers the next route when patrolling for the Controllable.
function AI_A2A_PATROL.PatrolRoute( AIGroup, Fsm )
--- @param Wrapper.Group#GROUP AIPatrol
-- This statis method is called from the route path within the last task at the last waaypoint of the AIPatrol.
-- Note that this method is required, as triggers the next route when patrolling for the AIPatrol.
function AI_A2A_PATROL.PatrolRoute( AIPatrol, Fsm )
AIGroup:F( { "AI_A2A_PATROL.PatrolRoute:", AIGroup:GetName() } )
AIPatrol:F( { "AI_A2A_PATROL.PatrolRoute:", AIPatrol:GetName() } )
if AIGroup:IsAlive() then
if AIPatrol:IsAlive() then
Fsm:Route()
end
@@ -330,11 +330,11 @@ end
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
-- @param #AI_A2A_PATROL self
-- @param Wrapper.Group#GROUP AIGroup The AIGroup managed by the FSM.
-- @param Wrapper.Group#GROUP AIPatrol The Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_PATROL:onafterRoute( AIGroup, From, Event, To )
function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
self:F2()
@@ -344,13 +344,13 @@ function AI_A2A_PATROL:onafterRoute( AIGroup, From, Event, To )
end
if AIGroup:IsAlive() then
if AIPatrol:IsAlive() then
local PatrolRoute = {}
--- Calculate the target route point.
local CurrentCoord = AIGroup:GetCoordinate()
local CurrentCoord = AIPatrol:GetCoordinate()
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
ToTargetCoord:SetAlt( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ) )
@@ -371,23 +371,23 @@ function AI_A2A_PATROL:onafterRoute( AIGroup, From, Event, To )
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
local Tasks = {}
Tasks[#Tasks+1] = AIGroup:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
PatrolRoute[#PatrolRoute].task = AIGroup:TaskCombo( Tasks )
Tasks[#Tasks+1] = AIPatrol:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
AIGroup:OptionROEReturnFire()
AIGroup:OptionROTPassiveDefense()
AIPatrol:OptionROEReturnFire()
AIPatrol:OptionROTEvadeFire()
AIGroup:Route( PatrolRoute, 0.5 )
AIPatrol:Route( PatrolRoute, 0.5 )
end
end
--- @param Wrapper.Group#GROUP AIGroup
function AI_A2A_PATROL.Resume( AIGroup )
--- @param Wrapper.Group#GROUP AIPatrol
function AI_A2A_PATROL.Resume( AIPatrol )
AIGroup:F( { "AI_A2A_PATROL.Resume:", AIGroup:GetName() } )
if AIGroup:IsAlive() then
local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A
AIPatrol:F( { "AI_A2A_PATROL.Resume:", AIPatrol:GetName() } )
if AIPatrol:IsAlive() then
local _AI_A2A = AIPatrol:GetState( AIPatrol, "AI_A2A" ) -- #AI_A2A
_AI_A2A:__Reset( 1 )
_AI_A2A:__Route( 5 )
end

View File

@@ -479,7 +479,7 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
Controllable:OptionROEOpenFire()
Controllable:OptionROTPassiveDefense()
Controllable:OptionROTEvadeFire()
local AttackTasks = {}

View File

@@ -958,7 +958,7 @@ function AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
-- @param Wrapper.Unit#UNIT ClientUnit
function( FollowGroup, Formation, ClientUnit, CT1, CV1, CT2, CV2 )
FollowGroup:OptionROTPassiveDefense()
FollowGroup:OptionROTEvadeFire()
FollowGroup:OptionROEReturnFire()
local GroupUnit = FollowGroup:GetUnit( 1 )

View File

@@ -285,26 +285,5 @@ do -- ACT_ACCOUNT_DEADS
end
end
--- @param #ACT_ACCOUNT_DEADS self
-- @param Event#EVENTDATA EventData
function ACT_ACCOUNT_DEADS:onfuncEventDead( EventData )
self:T( { "EventDead", EventData } )
if EventData.IniDCSUnit then
self:Event( EventData )
end
end
--- DCS Events
--- @param #ACT_ACCOUNT_DEADS self
-- @param Event#EVENTDATA EventData
function ACT_ACCOUNT_DEADS:onfuncEventCrash( EventData )
self:T( { "EventDead", EventData } )
if EventData.IniDCSUnit then
self:Event( EventData )
end
end
end -- ACT_ACCOUNT DEADS

View File

@@ -269,6 +269,23 @@ function BASE:Inherit( Child, Parent )
return Child
end
local function getParent( Child )
local Parent = nil
if Child.ClassName == 'BASE' then
Parent = nil
else
if rawget( Child, "__" ) then
Parent = getmetatable( Child.__ ).__index
else
Parent = getmetatable( Child ).__index
end
end
return Parent
end
--- This is the worker method to retrieve the Parent class.
-- Note that the Parent class must be passed to call the parent class method.
--
@@ -278,17 +295,31 @@ end
-- @param #BASE self
-- @param #BASE Child is the Child class from which the Parent class needs to be retrieved.
-- @return #BASE
function BASE:GetParent( Child )
function BASE:GetParent( Child, FromClass )
local Parent
-- BASE class has no parent
if Child.ClassName == 'BASE' then
Parent = nil
elseif rawget( Child, "__" ) then
Parent = getmetatable( Child.__ ).__index
else
Parent = getmetatable( Child ).__index
end
return Parent
else
self:E({FromClass = FromClass})
self:E({Child = Child.ClassName})
if FromClass then
while( Child.ClassName ~= "BASE" and Child.ClassName ~= FromClass.ClassName ) do
Child = getParent( Child )
self:E({Child.ClassName})
end
end
if Child.ClassName == 'BASE' then
Parent = nil
else
Parent = getParent( Child )
end
end
self:E({Parent.ClassName})
return Parent
end
--- This is the worker method to check if an object is an (sub)instance of a class.
@@ -334,7 +365,7 @@ function BASE:IsInstanceOf( ClassName )
return true
end
local Parent = self:GetParent(self)
local Parent = getParent(self)
while Parent do
@@ -342,7 +373,7 @@ function BASE:IsInstanceOf( ClassName )
return true
end
Parent = Parent:GetParent(Parent)
Parent = getParent( Parent )
end

View File

@@ -70,6 +70,8 @@ DATABASE = {
NavPoints = {},
PLAYERSETTINGS = {},
ZONENAMES = {},
HITS = {},
DESTROYS = {},
}
local _DATABASECoalition =
@@ -104,6 +106,7 @@ function DATABASE:New()
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Hit, self.AccountHits )
self:HandleEvent( EVENTS.NewCargo )
self:HandleEvent( EVENTS.DeleteCargo )
@@ -722,6 +725,8 @@ function DATABASE:_EventOnDeadOrCrash( Event )
end
end
end
self:AccountDestroys( Event )
end
@@ -1053,6 +1058,99 @@ function DATABASE:_RegisterTemplates()
return self
end
--- Account the Hits of the Players.
-- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event
function DATABASE:AccountHits( Event )
self:F( { Event } )
if Event.IniPlayerName ~= nil then -- It is a player that is hitting something
self:T( "Hitting Something" )
-- What is he hitting?
if Event.TgtCategory then
-- A target got hit
self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {}
local Hit = self.HITS[Event.TgtUnitName]
Hit.Players = Hit.Players or {}
Hit.Players[Event.IniPlayerName] = true
end
end
-- It is a weapon initiated by a player, that is hitting something
-- This seems to occur only with scenery and static objects.
if Event.WeaponPlayerName ~= nil then
self:T( "Hitting Scenery" )
-- What is he hitting?
if Event.TgtCategory then
if Event.IniCoalition then -- A coalition object was hit, probably a static.
-- A target got hit
self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {}
local Hit = self.HITS[Event.TgtUnitName]
Hit.Players = Hit.Players or {}
Hit.Players[Event.WeaponPlayerName] = true
else -- A scenery object was hit.
end
end
end
end
--- Account the destroys.
-- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event
function DATABASE:AccountDestroys( Event )
self:F( { Event } )
local TargetUnit = nil
local TargetGroup = nil
local TargetUnitName = ""
local TargetGroupName = ""
local TargetPlayerName = ""
local TargetCoalition = nil
local TargetCategory = nil
local TargetType = nil
local TargetUnitCoalition = nil
local TargetUnitCategory = nil
local TargetUnitType = nil
if Event.IniDCSUnit then
TargetUnit = Event.IniUnit
TargetUnitName = Event.IniDCSUnitName
TargetGroup = Event.IniDCSGroup
TargetGroupName = Event.IniDCSGroupName
TargetPlayerName = Event.IniPlayerName
TargetCoalition = Event.IniCoalition
--TargetCategory = TargetUnit:getCategory()
--TargetCategory = TargetUnit:getDesc().category -- Workaround
TargetCategory = Event.IniCategory
TargetType = Event.IniTypeName
TargetUnitType = TargetType
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
end
self:T( "Something got destroyed" )
local Destroyed = false
-- What is the player destroying?
if self.HITS[Event.IniUnitName] then -- Was there a hit for this unit for this player before registered???
self.DESTROYS[Event.IniUnitName] = self.DESTROYS[Event.IniUnitName] or {}
self.DESTROYS[Event.IniUnitName] = true
end
end

View File

@@ -0,0 +1,146 @@
--- **Core (WIP)** -- Base class to allow the modeling of processes to achieve Goals.
--
-- ====
--
-- GOAL models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
--
-- ====
--
-- ### Author: **Sven Van de Velde (FlightControl)**
--
-- ====
--
-- @module Goal
do -- Goal
--- @type GOAL
-- @extends Core.Fsm#FSM
--- # GOAL class, extends @{Fsm#FSM}
--
-- GOAL models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
--
-- ## 1. GOAL constructor
--
-- * @{#GOAL.New}(): Creates a new GOAL object.
--
-- ## 2. GOAL is a finite state machine (FSM).
--
-- ### 2.1 GOAL States
--
-- * **Pending**: The goal object is in progress.
-- * **Achieved**: The goal objective is Achieved.
--
-- ### 2.2 GOAL Events
--
-- * **Achieved**: Set the goal objective to Achieved.
--
-- @field #GOAL
GOAL = {
ClassName = "GOAL",
}
--- @field #table GOAL.Players
GOAL.Players = {}
--- @field #number GOAL.TotalContributions
GOAL.TotalContributions = 0
--- GOAL Constructor.
-- @param #GOAL self
-- @return #GOAL
function GOAL:New()
local self = BASE:Inherit( self, FSM:New() ) -- #GOAL
self:F( {} )
--- Achieved State for GOAL
-- @field GOAL.Achieved
--- Achieved State Handler OnLeave for GOAL
-- @function [parent=#GOAL] OnLeaveAchieved
-- @param #GOAL self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Achieved State Handler OnEnter for GOAL
-- @function [parent=#GOAL] OnEnterAchieved
-- @param #GOAL self
-- @param #string From
-- @param #string Event
-- @param #string To
self:SetStartState( "Pending" )
self:AddTransition( "*", "Achieved", "Achieved" )
--- Achieved Handler OnBefore for GOAL
-- @function [parent=#GOAL] OnBeforeAchieved
-- @param #GOAL self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Achieved Handler OnAfter for GOAL
-- @function [parent=#GOAL] OnAfterAchieved
-- @param #GOAL self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Achieved Trigger for GOAL
-- @function [parent=#GOAL] Achieved
-- @param #GOAL self
--- Achieved Asynchronous Trigger for GOAL
-- @function [parent=#GOAL] __Achieved
-- @param #GOAL self
-- @param #number Delay
self:SetEventPriority( 5 )
return self
end
--- @param #GOAL self
-- @param #string PlayerName
function GOAL:AddPlayerContribution( PlayerName )
self.Players[PlayerName] = self.Players[PlayerName] or 0
self.Players[PlayerName] = self.Players[PlayerName] + 1
self.TotalContributions = self.TotalContributions + 1
end
--- @param #GOAL self
-- @param #number Player contribution.
function GOAL:GetPlayerContribution( PlayerName )
return self.Players[PlayerName] or 0
end
--- @param #GOAL self
function GOAL:GetPlayerContributions()
return self.Players or {}
end
--- @param #GOAL self
function GOAL:GetTotalContributions()
return self.TotalContributions or 0
end
--- @param #GOAL self
-- @return #boolean true if the goal is Achieved
function GOAL:IsAchieved()
return self:Is( "Achieved" )
end
end

View File

@@ -167,7 +167,7 @@ function MESSAGE:ToClient( Client, Settings )
if self.MessageType then
local Settings = Settings or ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = self.MessageType .. ": "
self.MessageCategory = "" -- self.MessageType .. ": "
end
if self.MessageDuration ~= 0 then
@@ -192,7 +192,7 @@ function MESSAGE:ToGroup( Group, Settings )
if self.MessageType then
local Settings = Settings or ( Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = self.MessageType .. ": "
self.MessageCategory = "" -- self.MessageType .. ": "
end
if self.MessageDuration ~= 0 then
@@ -259,7 +259,7 @@ function MESSAGE:ToCoalition( CoalitionSide, Settings )
if self.MessageType then
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = self.MessageType .. ": "
self.MessageCategory = "" -- self.MessageType .. ": "
end
if CoalitionSide then
@@ -303,7 +303,7 @@ function MESSAGE:ToAll()
if self.MessageType then
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = self.MessageType .. ": "
self.MessageCategory = "" -- self.MessageType .. ": "
end
if self.MessageDuration ~= 0 then

View File

@@ -1081,7 +1081,7 @@ do -- COORDINATE
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
local ModeA2A = true
local ModeA2A = false
if Task then
if Task:IsInstanceOf( TASK_A2A ) then
@@ -1092,6 +1092,8 @@ do -- COORDINATE
else
if Task:IsInstanceOf( TASK_CARGO ) then
ModeA2A = false
else
ModeA2A = false
end
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -50,6 +50,8 @@
-- ## Each zone has a name:
--
-- * @{#ZONE_BASE.GetName}(): Returns the name of the zone.
-- * @{#ZONE_BASE.SetName}(): Sets the name of the zone.
--
--
-- ## Each zone implements two polymorphic functions defined in @{Zone#ZONE_BASE}:
--
@@ -121,6 +123,17 @@ function ZONE_BASE:GetName()
return self.ZoneName
end
--- Sets the name of the zone.
-- @param #ZONE_BASE self
-- @param #string ZoneName The name of the zone.
-- @return #ZONE_BASE
function ZONE_BASE:SetName( ZoneName )
self:F2()
self.ZoneName = ZoneName
end
--- Returns if a Vec2 is within the zone.
-- @param #ZONE_BASE self
-- @param Dcs.DCSTypes#Vec2 Vec2 The Vec2 to test.
@@ -562,6 +575,160 @@ function ZONE_RADIUS:GetVec3( Height )
end
--- Scan the zone
-- @param #ZONE_RADIUS self
-- @param Coalition
function ZONE_RADIUS:Scan()
self.Coalitions = {}
local ZoneCoord = self:GetCoordinate()
local ZoneRadius = self:GetRadius()
self:E({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
local SphereSearch = {
id = world.VolumeType.SPHERE,
params = {
point = ZoneCoord:GetVec3(),
radius = ZoneRadius,
}
}
local function EvaluateZone( ZoneDCSUnit )
if ZoneDCSUnit:isExist() then
local CategoryDCSUnit = ZoneDCSUnit:getCategory()
if ( CategoryDCSUnit == Object.Category.UNIT and ZoneDCSUnit:isActive() ) or
CategoryDCSUnit == Object.Category.STATIC then
local CoalitionDCSUnit = ZoneDCSUnit:getCoalition()
self.Coalitions[CoalitionDCSUnit] = true
self:E( { Name = ZoneDCSUnit:getName(), Coalition = CoalitionDCSUnit } )
end
end
return true
end
world.searchObjects( { Object.Category.UNIT, Object.Category.STATIC }, SphereSearch, EvaluateZone )
end
function ZONE_RADIUS:CountCoalitions()
local Count = 0
for CoalitionID, Coalition in pairs( self.Coalitions ) do
Count = Count + 1
end
return Count
end
--- Is All in Zone of Coalition?
-- @param #ZONE_RADIUS self
-- @param Coalition
-- @return #boolean
function ZONE_RADIUS:IsAllInZoneOfCoalition( Coalition )
return self:CountCoalitions() == 1 and self.Coalitions[Coalition] == true
end
--- Is All in Zone of Other Coalition?
-- @param #ZONE_RADIUS self
-- @param Coalition
-- @return #boolean
function ZONE_RADIUS:IsAllInZoneOfOtherCoalition( Coalition )
self:E( { Coalitions = self.Coalitions, Count = self:CountCoalitions() } )
return self:CountCoalitions() == 1 and self.Coalitions[Coalition] == nil
end
--- Is Some in Zone of Coalition?
-- @param #ZONE_RADIUS self
-- @param Coalition
-- @return #boolean
function ZONE_RADIUS:IsSomeInZoneOfCoalition( Coalition )
return self:CountCoalitions() > 1 and self.Coalitions[Coalition] == true
end
--- Is None in Zone of Coalition?
-- @param #ZONE_RADIUS self
-- @param Coalition
-- @return #boolean
function ZONE_RADIUS:IsNoneInZoneOfCoalition( Coalition )
return self.Coalitions[Coalition] == nil
end
--- Is None in Zone?
-- @param #ZONE_RADIUS self
-- @return #boolean
function ZONE_RADIUS:IsNoneInZone()
return self:CountCoalitions() == 0
end
--- Get the Zone Coalitions.
-- Returns nil if there are none ot two coalitions in the zone!
-- @param #ZONE_RADIUS self
-- @return Coalitions
function ZONE_RADIUS:GetCoalition()
local Count = 0
local ReturnCoalition = nil
for CoalitionID, Coalition in pairs( self.Coalitions ) do
Count = Count + 1
ReturnCoalition = CoalitionID
end
if Count ~= 1 then
ReturnCoalition = nil
end
return ReturnCoalition
end
--- Searches the zone
-- @param #ZONE_RADIUS self
-- @param EvaluateFunction
function ZONE_RADIUS:SearchZone( EvaluateFunction )
local SearchZoneResult = true
local ZoneCoord = self:GetCoordinate()
local ZoneRadius = self:GetRadius()
self:E({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
local SphereSearch = {
id = world.VolumeType.SPHERE,
params = {
point = ZoneCoord:GetVec3(),
radius = ZoneRadius / 2,
}
}
local function EvaluateZone( ZoneDCSUnit )
env.info( ZoneDCSUnit:getName() )
local ZoneUnit = UNIT:Find( ZoneDCSUnit )
return EvaluateFunction( ZoneUnit )
end
world.searchObjects( Object.Category.UNIT, SphereSearch, EvaluateZone )
end
--- Returns if a location is within the zone.
-- @param #ZONE_RADIUS self
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.

View File

@@ -0,0 +1,305 @@
--- **Functional** -- The PROTECT class handles the protection of objects, which can be zones, units, scenery.
--
-- ===
--
-- ### Author: **Sven Van de Velde (FlightControl)**
-- ### Contributions: **MillerTime**
--
-- ====
--
-- @module Protect
--- @type PROTECT.__ Methods which are not intended for mission designers, but which are used interally by the moose designer :-)
-- @extends Core.Fsm#FSM
--- @type PROTECT
-- @extends #PROTECT.__
--- # PROTECT, extends @{Base#BASE}
--
-- @field #PROTECT
PROTECT = {
ClassName = "PROTECT",
}
--- Get the ProtectZone
-- @param #PROTECT self
-- @return Core.Zone#ZONE_BASE
function PROTECT:GetProtectZone()
return self.ProtectZone
end
--- Get the name of the ProtectZone
-- @param #PROTECT self
-- @return #string
function PROTECT:GetProtectZoneName()
return self.ProtectZone:GetName()
end
--- Set the owning coalition of the zone.
-- @param #PROTECT self
-- @param DCSCoalition.DCSCoalition#coalition Coalition
function PROTECT:SetCoalition( Coalition )
self.Coalition = Coalition
end
--- Get the owning coalition of the zone.
-- @param #PROTECT self
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
function PROTECT:GetCoalition()
return self.Coalition
end
--- Get the owning coalition name of the zone.
-- @param #PROTECT self
-- @return #string Coalition name.
function PROTECT:GetCoalitionName()
if self.Coalition == coalition.side.BLUE then
return "Blue"
end
if self.Coalition == coalition.side.RED then
return "Red"
end
if self.Coalition == coalition.side.NEUTRAL then
return "Neutral"
end
return ""
end
function PROTECT:IsGuarded()
local IsGuarded = self.ProtectZone:IsAllInZoneOfCoalition( self.Coalition )
self:E( { IsGuarded = IsGuarded } )
return IsGuarded
end
function PROTECT:IsCaptured()
local IsCaptured = self.ProtectZone:IsAllInZoneOfOtherCoalition( self.Coalition )
self:E( { IsCaptured = IsCaptured } )
return IsCaptured
end
function PROTECT:IsAttacked()
local IsAttacked = self.ProtectZone:IsSomeInZoneOfCoalition( self.Coalition )
self:E( { IsAttacked = IsAttacked } )
return IsAttacked
end
function PROTECT:IsEmpty()
local IsEmpty = self.ProtectZone:IsNoneInZone()
self:E( { IsEmpty = IsEmpty } )
return IsEmpty
end
--- Check if the units are still alive.
-- @param #PROTECT self
function PROTECT:AreProtectUnitsAlive()
local IsAlive = false
local UnitSet = self.ProtectUnitSet
UnitSet:Flush()
local UnitList = UnitSet:GetSet()
for UnitID, ProtectUnit in pairs( UnitList ) do
local IsUnitAlive = ProtectUnit:IsAlive()
if IsUnitAlive == true then
IsAlive = true
break
end
end
return IsAlive
end
--- Check if the statics are still alive.
-- @param #PROTECT self
function PROTECT:AreProtectStaticsAlive()
local IsAlive = false
local StaticSet = self.ProtectStaticSet
StaticSet:Flush()
local StaticList = StaticSet:GetSet()
for UnitID, ProtectStatic in pairs( StaticList ) do
local IsStaticAlive = ProtectStatic:IsAlive()
if IsStaticAlive == true then
IsAlive = true
break
end
end
return IsAlive
end
--- Check if there is a capture unit in the zone.
-- @param #PROTECT self
function PROTECT:IsCaptureUnitInZone()
local CaptureUnitSet = self.CaptureUnitSet
CaptureUnitSet:Flush()
local IsInZone = self.CaptureUnitSet:IsPartiallyInZone( self.ProtectZone )
self:E({IsInZone = IsInZone})
return IsInZone
end
--- Smoke.
-- @param #PROTECT self
-- @param #SMOKECOLOR.Color SmokeColor
function PROTECT:Smoke( SmokeColor )
self.SmokeColor = SmokeColor
end
--- Flare.
-- @param #PROTECT self
-- @param #SMOKECOLOR.Color FlareColor
function PROTECT:Flare( FlareColor )
self.ProtectZone:FlareZone( FlareColor, math.random( 1, 360 ) )
end
--- Mark.
-- @param #PROTECT self
function PROTECT:Mark()
local Coord = self.ProtectZone:GetCoordinate()
local ZoneName = self:GetProtectZoneName()
local State = self:GetState()
if self.MarkRed and self.MarkBlue then
self:E( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } )
Coord:RemoveMark( self.MarkRed )
Coord:RemoveMark( self.MarkBlue )
end
if self.Coalition == coalition.side.BLUE then
self.MarkBlue = Coord:MarkToCoalitionBlue( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
self.MarkRed = Coord:MarkToCoalitionRed( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
else
self.MarkRed = Coord:MarkToCoalitionRed( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
self.MarkBlue = Coord:MarkToCoalitionBlue( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
end
end
--- Bound.
-- @param #PROTECT self
function PROTECT:onafterStart()
self:ScheduleRepeat( 5, 15, 0.1, nil, self.StatusCoalition, self )
self:ScheduleRepeat( 5, 15, 0.1, nil, self.StatusZone, self )
self:ScheduleRepeat( 10, 15, 0, nil, self.StatusSmoke, self )
end
--- Bound.
-- @param #PROTECT self
function PROTECT:onenterGuarded()
if self.Coalition == coalition.side.BLUE then
--elf.ProtectZone:BoundZone( 12, country.id.USA )
else
--self.ProtectZone:BoundZone( 12, country.id.RUSSIA )
end
self:Mark()
end
function PROTECT:onenterCaptured()
local NewCoalition = self.ProtectZone:GetCoalition()
self:E( { NewCoalition = NewCoalition } )
self:SetCoalition( NewCoalition )
self:Mark()
end
function PROTECT:onenterEmpty()
self:Mark()
end
function PROTECT:onenterAttacked()
self:Mark()
end
--- Check status Coalition ownership.
-- @param #PROTECT self
function PROTECT:StatusCoalition()
self:E( { State = self:GetState() } )
self.ProtectZone:Scan()
if self:IsGuarded() then
self:Guard()
else
if self:IsCaptured() then
self:Capture()
end
end
end
--- Check status Zone.
-- @param #PROTECT self
function PROTECT:StatusZone()
self:E( { State = self:GetState() } )
self.ProtectZone:Scan()
if self:IsAttacked() then
self:Attack()
else
if self:IsEmpty() then
self:Empty()
end
end
end
--- Check status Smoke.
-- @param #PROTECT self
function PROTECT:StatusSmoke()
local CurrentTime = timer.getTime()
if self.SmokeTime == nil or self.SmokeTime + 300 <= CurrentTime then
if self.SmokeColor then
self.ProtectZone:GetCoordinate():Smoke( self.SmokeColor )
--self.SmokeColor = nil
self.SmokeTime = CurrentTime
end
end
end

View File

@@ -710,6 +710,39 @@ function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score )
end
end
--- Registers Scores the players completing a Mission Task.
-- @param #SCORING self
-- @param Tasking.Mission#MISSION Mission
-- @param #string PlayerName
-- @param #string Text
-- @param #number Score
function SCORING:_AddMissionGoalScore( Mission, PlayerName, Text, Score )
local MissionName = Mission:GetName()
self:E( { Mission:GetName(), PlayerName, Text, Score } )
-- PlayerName can be nil, if the Unit with the player crashed or due to another reason.
if PlayerName then
local PlayerData = self.Players[PlayerName]
if not PlayerData.Mission[MissionName] then
PlayerData.Mission[MissionName] = {}
PlayerData.Mission[MissionName].ScoreTask = 0
PlayerData.Mission[MissionName].ScoreMission = 0
end
self:T( PlayerName )
self:T( PlayerData.Mission[MissionName] )
PlayerData.Score = self.Players[PlayerName].Score + Score
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
MESSAGE:NewType( string.format( "%s%s: %s! Player %s receives %d score!", self.DisplayMessagePrefix, MissionName, Text, PlayerName, Score ), MESSAGE.Type.Information ):ToAll()
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score )
end
end
--- Registers Mission Scores for possible multiple players that contributed in the Mission.
-- @param #SCORING self

View File

@@ -0,0 +1,67 @@
--- **Functional (wIP)** -- Base class that models processes to capture a Zone for a Coalition, guarded by another Coalition.
--
-- ====
--
-- ZONE_CAPTURE_COALITION models processes that have an objective with a defined achievement involving a Zone. Derived classes implement the ways how the achievements can be realized.
--
-- ====
--
-- ### Author: **Sven Van de Velde (FlightControl)**
--
-- ====
--
-- @module ZoneCaptureCoalition
do -- ZoneGoal
--- @type ZONE_CAPTURE_COALITION
-- @extends Functional.ZoneGoalCoalition#ZONE_GOAL_COALITION
--- # ZONE_CAPTURE_COALITION class, extends @{ZoneGoalCoalition#ZONE_GOAL_COALITION}
--
-- ZONE_CAPTURE_COALITION models processes that have an objective with a defined achievement involving a Zone. Derived classes implement the ways how the achievements can be realized.
--
-- ## 1. ZONE_CAPTURE_COALITION constructor
--
-- * @{#ZONE_CAPTURE_COALITION.New}(): Creates a new ZONE_CAPTURE_COALITION object.
--
-- ## 2. ZONE_CAPTURE_COALITION is a finite state machine (FSM).
--
-- ### 2.1 ZONE_CAPTURE_COALITION States
--
-- ### 2.2 ZONE_CAPTURE_COALITION Events
--
-- @field #ZONE_CAPTURE_COALITION
ZONE_CAPTURE_COALITION = {
ClassName = "ZONE_CAPTURE_COALITION",
}
--- @field #table ZONE_CAPTURE_COALITION.States
ZONE_CAPTURE_COALITION.States = {}
--- ZONE_CAPTURE_COALITION Constructor.
-- @param #ZONE_CAPTURE_COALITION self
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
-- @return #ZONE_CAPTURE_COALITION
function ZONE_CAPTURE_COALITION:New( Zone, Coalition )
local self = BASE:Inherit( self, ZONE_GOAL_COALITION:New( Zone, Coalition ) ) -- #ZONE_CAPTURE_COALITION
self:F( { Zone = Zone, Coalition = Coalition } )
return self
end
--- @param #ZONE_CAPTURE_COALITION self
function ZONE_CAPTURE_COALITION:onenterCaptured()
self:GetParent( self, ZONE_CAPTURE_COALITION ).onenterCaptured( self )
self.Goal:Achieved()
end
end

View File

@@ -0,0 +1,177 @@
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone.
--
-- ====
--
-- ZONE_GOAL models processes that have a Goal with a defined achievement involving a Zone.
-- Derived classes implement the ways how the achievements can be realized.
--
-- ====
--
-- ### Author: **Sven Van de Velde (FlightControl)**
--
-- ====
--
-- @module ZoneGoal
do -- Zone
--- @type ZONE_GOAL
-- @extends Core.Fsm#FSM
--- # ZONE_GOAL class, extends @{Fsm#FSM}
--
-- ZONE_GOAL models processes that have a Goal with a defined achievement involving a Zone.
-- Derived classes implement the ways how the achievements can be realized.
--
-- ## 1. ZONE_GOAL constructor
--
-- * @{#ZONE_GOAL.New}(): Creates a new ZONE_GOAL object.
--
-- ## 2. ZONE_GOAL is a finite state machine (FSM).
--
-- ### 2.1 ZONE_GOAL States
--
-- * None: Initial State
--
-- ### 2.2 ZONE_GOAL Events
--
-- * DestroyedUnit: A @{Unit} is destroyed in the Zone. The event will only get triggered if the method @{#ZONE_GOAL.MonitorDestroyedUnits}() is used.
--
-- @field #ZONE_GOAL
ZONE_GOAL = {
ClassName = "ZONE_GOAL",
}
--- ZONE_GOAL Constructor.
-- @param #ZONE_GOAL self
-- @param Core.Zone#ZONE_BASE Zone A @{Zone} object with the goal to be achieved.
-- @return #ZONE_GOAL
function ZONE_GOAL:New( Zone )
local self = BASE:Inherit( self, FSM:New() ) -- #ZONE_GOAL
self:F( { Zone = Zone } )
self.Zone = Zone -- Core.Zone#ZONE_BASE
self.Goal = GOAL:New()
self.SmokeTime = nil
self:AddTransition( "*", "DestroyedUnit", "*" )
--- DestroyedUnit Handler OnAfter for ZONE_GOAL
-- @function [parent=#ZONE_GOAL] OnAfterDestroyedUnit
-- @param #ZONE_GOAL self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Wrapper.Unit#UNIT DestroyedUnit The destroyed unit.
-- @param #string PlayerName The name of the player.
return self
end
--- Get the Zone
-- @param #ZONE_GOAL self
-- @return Core.Zone#ZONE_BASE
function ZONE_GOAL:GetZone()
return self.Zone
end
--- Get the name of the ProtectZone
-- @param #ZONE_GOAL self
-- @return #string
function ZONE_GOAL:GetZoneName()
return self.Zone:GetName()
end
--- Smoke the center of theh zone.
-- @param #ZONE_GOAL self
-- @param #SMOKECOLOR.Color SmokeColor
function ZONE_GOAL:Smoke( SmokeColor )
self:F( { SmokeColor = SmokeColor} )
self.SmokeColor = SmokeColor
end
--- Flare the center of the zone.
-- @param #ZONE_GOAL self
-- @param #SMOKECOLOR.Color FlareColor
function ZONE_GOAL:Flare( FlareColor )
self.Zone:FlareZone( FlareColor, math.random( 1, 360 ) )
end
--- When started, check the Smoke and the Zone status.
-- @param #ZONE_GOAL self
function ZONE_GOAL:onafterGuard()
--self:GetParent( self ):onafterStart()
self:E("Guard")
--self:ScheduleRepeat( 15, 15, 0.1, nil, self.StatusZone, self )
if not self.SmokeScheduler then
self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self )
end
end
--- Check status Smoke.
-- @param #ZONE_GOAL self
function ZONE_GOAL:StatusSmoke()
self:F({self.SmokeTime, self.SmokeColor})
local CurrentTime = timer.getTime()
if self.SmokeTime == nil or self.SmokeTime + 300 <= CurrentTime then
if self.SmokeColor then
self.Zone:GetCoordinate():Smoke( self.SmokeColor )
--self.SmokeColor = nil
self.SmokeTime = CurrentTime
end
end
end
--- @param #ZONE_GOAL self
-- @param Core.Event#EVENTDATA EventData
function ZONE_GOAL:__Destroyed( EventData )
self:E( { "EventDead", EventData } )
self:E( { EventData.IniUnit } )
local Vec3 = EventData.IniDCSUnit:getPosition().p
self:E( { Vec3 = Vec3 } )
local ZoneGoal = self:GetZone()
self:E({ZoneGoal})
if EventData.IniDCSUnit then
if ZoneGoal:IsVec3InZone(Vec3) then
local PlayerHits = _DATABASE.HITS[EventData.IniUnitName]
if PlayerHits then
for PlayerName, PlayerHit in pairs( PlayerHits.Players or {} ) do
self.Goal:AddPlayerContribution( PlayerName )
self:DestroyedUnit( EventData.IniUnitName, PlayerName )
end
end
end
end
end
--- Activate the event UnitDestroyed to be fired when a unit is destroyed in the zone.
-- @param #ZONE_GOAL self
function ZONE_GOAL:MonitorDestroyedUnits()
self:HandleEvent( EVENTS.Dead, self.__Destroyed )
self:HandleEvent( EVENTS.Crash, self.__Destroyed )
end
end

View File

@@ -0,0 +1,452 @@
--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone for a Coalition.
--
-- ====
--
-- ZONE_GOAL_COALITION models processes that have a Goal with a defined achievement involving a Zone for a Coalition.
-- Derived classes implement the ways how the achievements can be realized.
--
-- ====
--
-- ### Author: **Sven Van de Velde (FlightControl)**
--
-- ====
--
-- @module ZoneGoalCoalition
do -- ZoneGoal
--- @type ZONE_GOAL_COALITION
-- @extends Functional.ZoneGoal#ZONE_GOAL
--- # ZONE_GOAL_COALITION class, extends @{ZoneGoal#ZONE_GOAL}
--
-- ZONE_GOAL_COALITION models processes that have a Goal with a defined achievement involving a Zone for a Coalition.
-- Derived classes implement the ways how the achievements can be realized.
--
-- ## 1. ZONE_GOAL_COALITION constructor
--
-- * @{#ZONE_GOAL_COALITION.New}(): Creates a new ZONE_GOAL_COALITION object.
--
-- ## 2. ZONE_GOAL_COALITION is a finite state machine (FSM).
--
-- ### 2.1 ZONE_GOAL_COALITION States
--
-- * **Captured**: The Zone has been captured by an other coalition.
-- * **Attacked**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
-- * **Guarded**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
--
-- ### 2.2 ZONE_GOAL_COALITION Events
--
-- * **Capture**: The Zone has been captured by an other coalition.
-- * **Attack**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone.
-- * **Guard**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone.
-- * **Empty**: The Zone is empty. There is not valid unit in the Zone.
--
-- ### 2.3 ZONE_GOAL_COALITION State Machine
--
-- @field #ZONE_GOAL_COALITION
ZONE_GOAL_COALITION = {
ClassName = "ZONE_GOAL_COALITION",
}
--- @field #table ZONE_GOAL_COALITION.States
ZONE_GOAL_COALITION.States = {}
--- ZONE_GOAL_COALITION Constructor.
-- @param #ZONE_GOAL_COALITION self
-- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved.
-- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone.
-- @return #ZONE_GOAL_COALITION
function ZONE_GOAL_COALITION:New( Zone, Coalition )
local self = BASE:Inherit( self, ZONE_GOAL:New( Zone ) ) -- #ZONE_GOAL_COALITION
self:F( { Zone = Zone, Coalition = Coalition } )
self:SetCoalition( Coalition )
do
--- Captured State Handler OnLeave for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnLeaveCaptured
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Captured State Handler OnEnter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnEnterCaptured
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
end
do
--- Attacked State Handler OnLeave for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnLeaveAttacked
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Attacked State Handler OnEnter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnEnterAttacked
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
end
do
--- Guarded State Handler OnLeave for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnLeaveGuarded
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Guarded State Handler OnEnter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnEnterGuarded
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
end
do
--- Empty State Handler OnLeave for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnLeaveEmpty
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Empty State Handler OnEnter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnEnterEmpty
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
end
self:AddTransition( "*", "Guard", "Guarded" )
--- Guard Handler OnBefore for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnBeforeGuard
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Guard Handler OnAfter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnAfterGuard
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Guard Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] Guard
-- @param #ZONE_GOAL_COALITION self
--- Guard Asynchronous Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] __Guard
-- @param #ZONE_GOAL_COALITION self
-- @param #number Delay
self:AddTransition( "*", "Empty", "Empty" )
--- Empty Handler OnBefore for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnBeforeEmpty
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Empty Handler OnAfter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnAfterEmpty
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Empty Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] Empty
-- @param #ZONE_GOAL_COALITION self
--- Empty Asynchronous Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] __Empty
-- @param #ZONE_GOAL_COALITION self
-- @param #number Delay
self:AddTransition( { "Guarded", "Empty" }, "Attack", "Attacked" )
--- Attack Handler OnBefore for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnBeforeAttack
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Attack Handler OnAfter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnAfterAttack
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Attack Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] Attack
-- @param #ZONE_GOAL_COALITION self
--- Attack Asynchronous Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] __Attack
-- @param #ZONE_GOAL_COALITION self
-- @param #number Delay
self:AddTransition( { "Guarded", "Attacked", "Empty" }, "Capture", "Captured" )
--- Capture Handler OnBefore for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnBeforeCapture
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Capture Handler OnAfter for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] OnAfterCapture
-- @param #ZONE_GOAL_COALITION self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Capture Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] Capture
-- @param #ZONE_GOAL_COALITION self
--- Capture Asynchronous Trigger for ZONE_GOAL_COALITION
-- @function [parent=#ZONE_GOAL_COALITION] __Capture
-- @param #ZONE_GOAL_COALITION self
-- @param #number Delay
return self
end
--- Set the owning coalition of the zone.
-- @param #ZONE_GOAL_COALITION self
-- @param DCSCoalition.DCSCoalition#coalition Coalition
function ZONE_GOAL_COALITION:SetCoalition( Coalition )
self.Coalition = Coalition
end
--- Get the owning coalition of the zone.
-- @param #ZONE_GOAL_COALITION self
-- @return DCSCoalition.DCSCoalition#coalition Coalition.
function ZONE_GOAL_COALITION:GetCoalition()
return self.Coalition
end
--- Get the owning coalition name of the zone.
-- @param #ZONE_GOAL_COALITION self
-- @return #string Coalition name.
function ZONE_GOAL_COALITION:GetCoalitionName()
if self.Coalition == coalition.side.BLUE then
return "Blue"
end
if self.Coalition == coalition.side.RED then
return "Red"
end
if self.Coalition == coalition.side.NEUTRAL then
return "Neutral"
end
return ""
end
function ZONE_GOAL_COALITION:IsGuarded()
local IsGuarded = self.Zone:IsAllInZoneOfCoalition( self.Coalition )
self:E( { IsGuarded = IsGuarded } )
return IsGuarded
end
function ZONE_GOAL_COALITION:IsEmpty()
local IsEmpty = self.Zone:IsNoneInZone()
self:E( { IsEmpty = IsEmpty } )
return IsEmpty
end
function ZONE_GOAL_COALITION:IsCaptured()
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
self:E( { IsCaptured = IsCaptured } )
return IsCaptured
end
function ZONE_GOAL_COALITION:IsAttacked()
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
self:E( { IsAttacked = IsAttacked } )
return IsAttacked
end
--- Mark.
-- @param #ZONE_GOAL_COALITION self
function ZONE_GOAL_COALITION:Mark()
local Coord = self.Zone:GetCoordinate()
local ZoneName = self:GetZoneName()
local State = self:GetState()
if self.MarkRed and self.MarkBlue then
self:E( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } )
Coord:RemoveMark( self.MarkRed )
Coord:RemoveMark( self.MarkBlue )
end
if self.Coalition == coalition.side.BLUE then
self.MarkBlue = Coord:MarkToCoalitionBlue( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
self.MarkRed = Coord:MarkToCoalitionRed( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
else
self.MarkRed = Coord:MarkToCoalitionRed( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State )
self.MarkBlue = Coord:MarkToCoalitionBlue( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State )
end
end
--- Bound.
-- @param #ZONE_GOAL_COALITION self
function ZONE_GOAL_COALITION:onenterGuarded()
--self:GetParent( self ):onenterGuarded()
if self.Coalition == coalition.side.BLUE then
--elf.ProtectZone:BoundZone( 12, country.id.USA )
else
--self.ProtectZone:BoundZone( 12, country.id.RUSSIA )
end
self:Mark()
end
function ZONE_GOAL_COALITION:onenterCaptured()
--self:GetParent( self ):onenterCaptured()
local NewCoalition = self.Zone:GetCoalition()
self:E( { NewCoalition = NewCoalition } )
self:SetCoalition( NewCoalition )
self:Mark()
end
function ZONE_GOAL_COALITION:onenterEmpty()
--self:GetParent( self ):onenterEmpty()
self:Mark()
end
function ZONE_GOAL_COALITION:onenterAttacked()
--self:GetParent( self ):onenterAttacked()
self:Mark()
end
--- When started, check the Coalition status.
-- @param #ZONE_GOAL_COALITION self
function ZONE_GOAL_COALITION:onafterGuard()
--self:E({BASE:GetParent( self )})
--BASE:GetParent( self ).onafterGuard( self )
if not self.SmokeScheduler then
self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self )
end
if not self.ScheduleStatusZone then
self.ScheduleStatusZone = self:ScheduleRepeat( 15, 15, 0.1, nil, self.StatusZone, self )
end
end
function ZONE_GOAL_COALITION:IsCaptured()
local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition )
self:E( { IsCaptured = IsCaptured } )
return IsCaptured
end
function ZONE_GOAL_COALITION:IsAttacked()
local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition )
self:E( { IsAttacked = IsAttacked } )
return IsAttacked
end
--- Check status Coalition ownership.
-- @param #ZONE_GOAL_COALITION self
function ZONE_GOAL_COALITION:StatusZone()
local State = self:GetState()
self:E( { State = self:GetState() } )
self.Zone:Scan()
if State ~= "Guarded" and self:IsGuarded() then
self:Guard()
end
if State ~= "Empty" and self:IsEmpty() then
self:Empty()
end
if State ~= "Attacked" and self:IsAttacked() then
self:Attack()
end
if State ~= "Captured" and self:IsCaptured() then
self:Capture()
end
end
end

View File

@@ -175,28 +175,34 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
--- Goal Handler OnBefore for TASK
-- @function [parent=#TASK] OnBeforeGoal
-- @param #TASK self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
-- @param #string PlayerName The name of the player.
-- @return #boolean
--- Goal Handler OnAfter for TASK
-- @function [parent=#TASK] OnAfterGoal
-- @param #TASK self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
-- @param #string From
-- @param #string Event
-- @param #string To
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
-- @param #string PlayerName The name of the player.
--- Goal Trigger for TASK
-- @function [parent=#TASK] Goal
-- @param #TASK self
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
-- @param #string PlayerName The name of the player.
--- Goal Asynchronous Trigger for TASK
-- @function [parent=#TASK] __Goal
-- @param #TASK self
-- @param #number Delay
-- @param Wrapper.Unit#UNIT PlayerUnit The @{Unit} of the player.
-- @param #string PlayerName The name of the player.
@@ -872,42 +878,20 @@ function TASK:MenuMarkToGroup( TaskGroup )
-- List the name of the Task.
local Name = self:GetName()
Report:Add( Name .. ": " .. self:GetTaskBriefing() )
Report:Add( "Task " .. Name .. ": " .. self:GetTaskBriefing() .. "\n" )
for TaskInfoID, TaskInfo in pairs( self.TaskInfo, function( t, a, b ) return t[a].TaskInfoOrder < t[b].TaskInfoOrder end ) do
local TaskInfoIDText = "" --string.format( "%s: ", TaskInfoID )
if type( TaskInfo.TaskInfoText ) == "string" then
if TaskInfoID == "Targets" then
else
Report:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
end
elseif type( TaskInfo ) == "table" then
if TaskInfoID == "Coordinates" then
--local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
--Report:Add( TaskInfoIDText .. ToCoordinate:ToString() )
else
end
local ReportText = self:GetMarkInfo( TaskInfoID, TaskInfo )
if ReportText then
Report:Add( ReportText )
end
end
local Coordinate = self:GetInfo( "Coordinates" ) -- Core.Point#COORDINATE
local Velocity = self.TargetSetUnit:GetVelocity()
local Heading = self.TargetSetUnit:GetHeading()
Coordinate:SetHeading( Heading )
Coordinate:SetVelocity( Velocity )
Report:Add( "Targets are" .. Coordinate:GetMovingText() .. "." )
local TargetCoordinate = self:GetInfo( "Coordinate" ) -- Core.Point#COORDINATE
local MarkText = Report:Text( ", " )
self:F( { Coordinate = Coordinate, MarkText = MarkText } )
Coordinate:MarkToGroup( MarkText, TaskGroup )
self:F( { Coordinate = TargetCoordinate, MarkText = MarkText } )
TargetCoordinate:MarkToGroup( MarkText, TaskGroup )
--Coordinate:MarkToAll( Briefing )
end
@@ -1274,7 +1258,7 @@ function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
self:GetMission():__Start( 1 )
-- When the task is assigned, the task goal needs to be checked of the derived classes.
self:__Goal( -10 ) -- Polymorphic
self:__Goal( -10, PlayerUnit, PlayerName ) -- Polymorphic
self:SetMenu()
end
@@ -1443,14 +1427,14 @@ function TASK:ReportSummary( ReportGroup )
local Report = REPORT:New()
-- List the name of the Task.
Report:Add( self:GetName() )
Report:Add( "Task " .. self:GetName() )
-- Determine the status of the Task.
Report:Add( "State: <" .. self:GetState() .. ">" )
if self.TaskInfo["Coordinates"] then
if self.TaskInfo["Coordinate"] then
local TaskInfoIDText = string.format( "%s: ", "Coordinate" )
local TaskCoord = self.TaskInfo["Coordinates"].TaskInfoText -- Core.Point#COORDINATE
local TaskCoord = self.TaskInfo["Coordinate"].TaskInfoText -- Core.Point#COORDINATE
Report:Add( TaskInfoIDText .. TaskCoord:ToString( ReportGroup, nil, self ) )
end
@@ -1480,7 +1464,7 @@ function TASK:ReportOverview( ReportGroup )
if Line ~= 0 then
Report:AddIndent( LineReport:Text( ", " ) )
else
Report:Add( TaskName .. ", " .. LineReport:Text( ", " ) )
Report:Add( "Task " .. TaskName .. ", " .. LineReport:Text( ", " ) )
end
LineReport = REPORT:New()
Line = math.floor( TaskInfo.TaskInfoOrder / 10 )
@@ -1491,7 +1475,7 @@ function TASK:ReportOverview( ReportGroup )
if type( TaskInfo.TaskInfoText ) == "string" then
LineReport:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
elseif type(TaskInfo) == "table" then
if TaskInfoID == "Coordinates" then
if TaskInfoID == "Coordinate" then
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
--Report:Add( TaskInfoIDText )
LineReport:Add( TaskInfoIDText .. ToCoordinate:ToString( ReportGroup, nil, self ) )
@@ -1565,7 +1549,7 @@ function TASK:ReportDetails( ReportGroup )
-- Determine the status of the Task.
local Status = "<" .. self:GetState() .. ">"
Report:Add( "Task: " .. Name .. " - " .. Status .. " - Detailed Report" )
Report:Add( "Task " .. Name .. " - " .. Status .. " - Detailed Report" )
-- Loop each Unit active in the Task, and find Player Names.
local PlayerNames = self:GetPlayerNames()
@@ -1583,31 +1567,13 @@ function TASK:ReportDetails( ReportGroup )
for TaskInfoID, TaskInfo in pairs( self.TaskInfo, function( t, a, b ) return t[a].TaskInfoOrder < t[b].TaskInfoOrder end ) do
local TaskInfoIDText = string.format( " - %s: ", TaskInfoID )
if type( TaskInfo.TaskInfoText ) == "string" then
Report:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
elseif type(TaskInfo) == "table" then
if TaskInfoID == "Coordinates" then
local FromCoordinate = ReportGroup:GetUnit(1):GetCoordinate()
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
Report:Add( TaskInfoIDText .. ToCoordinate:ToString( ReportGroup:GetUnit(1), nil, self ) )
else
end
local ReportText = self:GetReportDetail( ReportGroup, TaskInfoID, TaskInfo )
if ReportText then
Report:Add( ReportText )
end
end
local Coordinate = self:GetInfo( "Coordinates" ) -- Core.Point#COORDINATE
local Velocity = self.TargetSetUnit:GetVelocity()
local Heading = self.TargetSetUnit:GetHeading()
Coordinate:SetHeading( Heading )
Coordinate:SetVelocity( Velocity )
Report:Add( "Targets are" .. Coordinate:GetMovingText() .. "." )
return Report:Text()
end

View File

@@ -0,0 +1,284 @@
--- **Tasking** - The TASK_Protect models tasks for players to protect or capture specific zones.
--
-- ====
--
-- ### Author: **Sven Van de Velde (FlightControl)**
--
-- ### Contributions: MillerTime
--
-- ====
--
-- @module TaskZoneCapture
do -- TASK_ZONE_GOAL
--- The TASK_ZONE_GOAL class
-- @type TASK_ZONE_GOAL
-- @field Core.ZoneGoal#ZONE_GOAL ZoneGoal
-- @extends Tasking.Task#TASK
--- # TASK_ZONE_GOAL class, extends @{Task#TASK}
--
-- The TASK_ZONE_GOAL class defines the task to protect or capture a protection zone.
-- The TASK_ZONE_GOAL is implemented using a @{Fsm#FSM_TASK}, and has the following statuses:
--
-- * **None**: Start of the process
-- * **Planned**: The A2G task is planned.
-- * **Assigned**: The A2G task is assigned to a @{Group#GROUP}.
-- * **Success**: The A2G task is successfully completed.
-- * **Failed**: The A2G task has failed. This will happen if the player exists the task early, without communicating a possible cancellation to HQ.
--
-- ## Set the scoring of achievements in an A2G attack.
--
-- Scoring or penalties can be given in the following circumstances:
--
-- * @{#TASK_ZONE_GOAL.SetScoreOnDestroy}(): Set a score when a target in scope of the A2G attack, has been destroyed.
-- * @{#TASK_ZONE_GOAL.SetScoreOnSuccess}(): Set a score when all the targets in scope of the A2G attack, have been destroyed.
-- * @{#TASK_ZONE_GOAL.SetPenaltyOnFailed}(): Set a penalty when the A2G attack has failed.
--
-- @field #TASK_ZONE_GOAL
TASK_ZONE_GOAL = {
ClassName = "TASK_ZONE_GOAL",
}
--- Instantiates a new TASK_ZONE_GOAL.
-- @param #TASK_ZONE_GOAL self
-- @param Tasking.Mission#MISSION Mission
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal
-- @return #TASK_ZONE_GOAL self
function TASK_ZONE_GOAL:New( Mission, SetGroup, TaskName, ZoneGoal, TaskType, TaskBriefing )
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType, TaskBriefing ) ) -- #TASK_ZONE_GOAL
self:F()
self.ZoneGoal = ZoneGoal
self.TaskType = TaskType
local Fsm = self:GetUnitProcess()
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "StartMonitoring", Rejected = "Reject" } )
Fsm:AddTransition( "Assigned", "StartMonitoring", "Monitoring" )
Fsm:AddTransition( "Monitoring", "Monitor", "Monitoring", {} )
Fsm:AddTransition( "Monitoring", "RouteTo", "Monitoring" )
Fsm:AddProcess( "Monitoring", "RouteToZone", ACT_ROUTE_ZONE:New(), {} )
--Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
--Fsm:AddTransition( "Accounted", "Success", "Success" )
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
Fsm:AddTransition( "Failed", "Fail", "Failed" )
self:SetTargetZone( self.ZoneGoal:GetZone() )
--- Test
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task#TASK_ZONE_GOAL Task
function Fsm:onafterStartMonitoring( TaskUnit, Task )
self:E( { self } )
self:__Monitor( 0.1 )
self:__RouteTo( 0.1 )
end
--- Monitor Loop
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task#TASK_ZONE_GOAL Task
function Fsm:onafterMonitor( TaskUnit, Task )
self:E( { self } )
self:__Monitor( 15 )
end
--- Test
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task_A2G#TASK_ZONE_GOAL Task
function Fsm:onafterRouteTo( TaskUnit, Task )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
-- Determine the first Unit from the self.TargetSetUnit
if Task:GetTargetZone( TaskUnit ) then
self:__RouteTo( 0.1 )
end
end
return self
end
--- @param #TASK_ZONE_GOAL self
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal Engine.
function TASK_ZONE_GOAL:SetProtect( ZoneGoal )
self.ZoneGoal = ZoneGoal -- Core.ZoneGoal#ZONE_GOAL
end
--- @param #TASK_ZONE_GOAL self
function TASK_ZONE_GOAL:GetPlannedMenuText()
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.ZoneGoal:GetZoneName() .. " )"
end
--- @param #TASK_ZONE_GOAL self
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
-- @param Wrapper.Unit#UNIT TaskUnit
function TASK_ZONE_GOAL:SetTargetZone( TargetZone, TaskUnit )
local ProcessUnit = self:GetUnitProcess( TaskUnit )
local ActRouteZone = ProcessUnit:GetProcess( "Monitoring", "RouteToZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
ActRouteZone:SetZone( TargetZone )
end
--- @param #TASK_ZONE_GOAL self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
function TASK_ZONE_GOAL:GetTargetZone( TaskUnit )
local ProcessUnit = self:GetUnitProcess( TaskUnit )
local ActRouteZone = ProcessUnit:GetProcess( "Monitoring", "RouteToZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
return ActRouteZone:GetZone()
end
function TASK_ZONE_GOAL:SetGoalTotal( GoalTotal )
self.GoalTotal = GoalTotal
end
function TASK_ZONE_GOAL:GetGoalTotal()
return self.GoalTotal
end
function TASK_ZONE_GOAL:GetMarkInfo( TaskInfoID, TaskInfo )
if type( TaskInfo.TaskInfoText ) == "string" then
return string.format( "%s: %s", TaskInfoID, TaskInfo.TaskInfoText )
elseif type( TaskInfo ) == "table" then
if TaskInfoID == "Coordinate" then
end
end
return nil
end
function TASK_ZONE_GOAL:GetReportDetail( ReportGroup, TaskInfoID, TaskInfo )
if type( TaskInfo.TaskInfoText ) == "string" then
return string.format( " - %s: %s", TaskInfoID, TaskInfo.TaskInfoText )
elseif type(TaskInfo) == "table" then
if TaskInfoID == "Coordinate" then
local FromCoordinate = ReportGroup:GetUnit(1):GetCoordinate()
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
return string.format( " - %s: %s", TaskInfoID, ToCoordinate:ToString( ReportGroup:GetUnit( 1 ), nil, self ) )
else
end
end
end
end
do -- TASK_ZONE_CAPTURE
--- The TASK_ZONE_CAPTURE class
-- @type TASK_ZONE_CAPTURE
-- @field Core.ZoneGoalCoalition#ZONE_GOAL_COALITION ZoneGoal
-- @extends #TASK_ZONE_GOAL
--- # TASK_ZONE_CAPTURE class, extends @{TaskZoneGoal#TASK_ZONE_GOAL}
--
-- The TASK_ZONE_CAPTURE class defines an Suppression or Extermination of Air Defenses task for a human player to be executed.
-- These tasks are important to be executed as they will help to achieve air superiority at the vicinity.
--
-- The TASK_ZONE_CAPTURE is used by the @{Task_A2G_Dispatcher#TASK_A2G_DISPATCHER} to automatically create SEAD tasks
-- based on detected enemy ground targets.
--
-- @field #TASK_ZONE_CAPTURE
TASK_ZONE_CAPTURE = {
ClassName = "TASK_ZONE_CAPTURE",
}
--- Instantiates a new TASK_ZONE_CAPTURE.
-- @param #TASK_ZONE_CAPTURE self
-- @param Tasking.Mission#MISSION Mission
-- @param Core.Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Core.ZoneGoalCoalition#ZONE_GOAL_COALITION ZoneGoalCoalition
-- @param #string TaskBriefing The briefing of the task.
-- @return #TASK_ZONE_CAPTURE self
function TASK_ZONE_CAPTURE:New( Mission, SetGroup, TaskName, ZoneGoalCoalition, TaskBriefing)
local self = BASE:Inherit( self, TASK_ZONE_GOAL:New( Mission, SetGroup, TaskName, ZoneGoalCoalition, "CAPTURE", TaskBriefing ) ) -- #TASK_ZONE_CAPTURE
self:F()
Mission:AddTask( self )
self.TaskCoalition = ZoneGoalCoalition:GetCoalition()
self.TaskCoalitionName = ZoneGoalCoalition:GetCoalitionName()
self.TaskZoneName = ZoneGoalCoalition:GetZoneName()
ZoneGoalCoalition:MonitorDestroyedUnits()
self:SetBriefing(
TaskBriefing or
"Capture Zone " .. self.TaskZoneName
)
self:UpdateTaskInfo()
return self
end
--- Instantiates a new TASK_ZONE_CAPTURE.
-- @param #TASK_ZONE_CAPTURE self
function TASK_ZONE_CAPTURE:UpdateTaskInfo()
local ZoneCoordinate = self.ZoneGoal:GetZone():GetCoordinate()
self:SetInfo( "Coordinate", ZoneCoordinate, 0 )
self:SetInfo( "Zone Name", self.ZoneGoal:GetZoneName(), 10 )
self:SetInfo( "Zone Coalition", self.ZoneGoal:GetCoalitionName(), 11 )
end
function TASK_ZONE_CAPTURE:ReportOrder( ReportGroup )
local Coordinate = self:GetInfo( "Coordinate" )
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
return Distance
end
--- @param #TASK_ZONE_CAPTURE self
-- @param Wrapper.Unit#UNIT TaskUnit
function TASK_ZONE_CAPTURE:OnAfterGoal( From, Event, To, PlayerUnit, PlayerName )
self:E( { PlayerUnit = PlayerUnit } )
if self.ZoneGoal then
if self.ZoneGoal.Goal:IsAchieved() then
self:Success()
local TotalContributions = self.ZoneGoal.Goal:GetTotalContributions()
local PlayerContributions = self.ZoneGoal.Goal:GetPlayerContributions()
self:E( { TotalContributions = TotalContributions, PlayerContributions = PlayerContributions } )
for PlayerName, PlayerContribution in pairs( PlayerContributions ) do
local Scoring = self:GetScoring()
if Scoring then
Scoring:_AddMissionGoalScore( self.Mission, PlayerName, "Zone " .. self.ZoneGoal:GetZoneName() .." captured", PlayerContribution * 200 / TotalContributions )
end
end
end
end
self:__Goal( -10, PlayerUnit, PlayerName )
end
end

View File

@@ -277,6 +277,35 @@ do -- TASK_A2A
return self.GoalTotal
end
function TASK_A2A:GetMarkInfo( TaskInfoID, TaskInfo )
if type( TaskInfo.TaskInfoText ) == "string" then
if TaskInfoID == "Targets" then
else
return string.format( "%s: %s", TaskInfoID, TaskInfo.TaskInfoText )
end
elseif type( TaskInfo ) == "table" then
if TaskInfoID == "Coordinate" then
end
end
return nil
end
function TASK_A2A:GetReportDetail( ReportGroup, TaskInfoID, TaskInfo )
if type( TaskInfo.TaskInfoText ) == "string" then
return string.format( "%s: %s", TaskInfoID, TaskInfo.TaskInfoText )
elseif type(TaskInfo) == "table" then
if TaskInfoID == "Coordinate" then
local FromCoordinate = ReportGroup:GetUnit(1):GetCoordinate()
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
return string.format( " - %s: %s", TaskInfoID, ToCoordinate:ToString( ReportGroup:GetUnit(1), nil, self ) )
else
end
end
end
end
@@ -336,7 +365,7 @@ do -- TASK_A2A_INTERCEPT
function TASK_A2A_INTERCEPT:UpdateTaskInfo()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Coordinate", TargetCoordinate, 0 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
@@ -492,7 +521,7 @@ do -- TASK_A2A_SWEEP
function TASK_A2A_SWEEP:UpdateTaskInfo()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Coordinate", TargetCoordinate, 0 )
self:SetInfo( "Assumed Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
@@ -641,7 +670,7 @@ do -- TASK_A2A_ENGAGE
function TASK_A2A_ENGAGE:UpdateTaskInfo()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Coordinate", TargetCoordinate, 0 )
self:SetInfo( "Threat", "[" .. string.rep( "", self.Detection and self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex ) or self.TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )

View File

@@ -285,6 +285,36 @@ do -- TASK_A2G
return self.GoalTotal
end
function TASK_A2G:GetMarkInfo( TaskInfoID, TaskInfo )
if type( TaskInfo.TaskInfoText ) == "string" then
if TaskInfoID == "Targets" then
else
return string.format( "%s: %s", TaskInfoID, TaskInfo.TaskInfoText )
end
elseif type( TaskInfo ) == "table" then
if TaskInfoID == "Coordinate" then
end
end
return nil
end
function TASK_A2G:GetReportDetail( ReportGroup, TaskInfoID, TaskInfo )
if type( TaskInfo.TaskInfoText ) == "string" then
return string.format( "%s: %s", TaskInfoID, TaskInfo.TaskInfoText )
elseif type(TaskInfo) == "table" then
if TaskInfoID == "Coordinate" then
local FromCoordinate = ReportGroup:GetUnit(1):GetCoordinate()
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
return string.format( " - %s: %s", TaskInfoID, ToCoordinate:ToString( ReportGroup:GetUnit(1), nil, self ) )
else
end
end
end
end
@@ -335,7 +365,7 @@ do -- TASK_A2G_SEAD
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Coordinate", TargetCoordinate, 0 )
local ThreatLevel, ThreatText
if self.Detection then
@@ -366,7 +396,7 @@ do -- TASK_A2G_SEAD
end
function TASK_A2G_SEAD:ReportOrder( ReportGroup )
local Coordinate = self:GetInfo( "Coordinates" )
local Coordinate = self:GetInfo( "Coordinate" )
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
@@ -484,7 +514,7 @@ do -- TASK_A2G_BAI
self:E({self.Detection, self.DetectedItemIndex})
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Coordinate", TargetCoordinate, 0 )
local ThreatLevel, ThreatText
if self.Detection then
@@ -512,11 +542,21 @@ do -- TASK_A2G_BAI
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 10 )
end
local TargetCoordinate = self:GetInfo( "Coordinate" ) -- Core.Point#COORDINATE
local Velocity = self.TargetSetUnit:GetVelocity()
local Heading = self.TargetSetUnit:GetHeading()
TargetCoordinate:SetHeading( Heading )
TargetCoordinate:SetVelocity( Velocity )
self:SetInfo( "Position", "Targets are" .. TargetCoordinate:GetMovingText() .. ".", 12 )
end
function TASK_A2G_BAI:ReportOrder( ReportGroup )
local Coordinate = self:GetInfo( "Coordinates" )
local Coordinate = self:GetInfo( "Coordinate" )
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
@@ -633,7 +673,7 @@ do -- TASK_A2G_CAS
function TASK_A2G_CAS:UpdateTaskInfo()
local TargetCoordinate = ( self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
self:SetInfo( "Coordinate", TargetCoordinate, 0 )
local ThreatLevel, ThreatText
if self.Detection then
@@ -666,7 +706,7 @@ do -- TASK_A2G_CAS
--- @param #TASK_A2G_CAS self
function TASK_A2G_CAS:ReportOrder( ReportGroup )
local Coordinate = self:GetInfo( "Coordinates" )
local Coordinate = self:GetInfo( "Coordinate" )
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
return Distance

View File

@@ -159,6 +159,36 @@ function IDENTIFIABLE:GetCoalition()
return nil
end
--- Returns the name of the coalition of the Identifiable.
-- @param #IDENTIFIABLE self
-- @return #string The name of the coalition.
-- @return #nil The DCS Identifiable is not existing or alive.
function IDENTIFIABLE:GetCoalitionName()
self:F2( self.IdentifiableName )
local DCSIdentifiable = self:GetDCSObject()
if DCSIdentifiable then
local IdentifiableCoalition = DCSIdentifiable:getCoalition()
self:T3( IdentifiableCoalition )
if IdentifiableCoalition == coalition.side.BLUE then
return "Blue"
end
if IdentifiableCoalition == coalition.side.RED then
return "Red"
end
if IdentifiableCoalition == coalition.side.NEUTRAL then
return "Neutral"
end
end
self:E( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )
return nil
end
--- Returns country of the Identifiable.
-- @param #IDENTIFIABLE self
-- @return Dcs.DCScountry#country.id The country identifier.

View File

@@ -415,9 +415,9 @@ function POSITIONABLE:GetMessageText( Message, Name ) --R2.1 added
local DCSObject = self:GetDCSObject()
if DCSObject then
Name = Name and ( " (" .. Name .. ")" ) or ""
local Callsign = string.format( "[%s]", self:GetCallsign() ~= "" and self:GetCallsign() or self:GetName() )
local MessageText = Callsign .. Name .. ": " .. Message
Name = Name and ( " => " .. Name ) or ""
local Callsign = string.format( "%s", self:GetCallsign() ~= "" and self:GetCallsign() or self:GetName() )
local MessageText = string.format("[%s%s]: %s", Callsign, Name, Message )
return MessageText
end