mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
264 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd9b844909 | ||
|
|
3c4f0a4b97 | ||
|
|
33916c2631 | ||
|
|
a0befeb34f | ||
|
|
0501959ab9 | ||
|
|
764beb7c22 | ||
|
|
9a40bceec5 | ||
|
|
a402235da3 | ||
|
|
1d939311c3 | ||
|
|
47f1b8ae66 | ||
|
|
cff8522922 | ||
|
|
d78547aa33 | ||
|
|
ab33d6b272 | ||
|
|
388103afea | ||
|
|
62b156c0e8 | ||
|
|
752de77a82 | ||
|
|
85975c01a4 | ||
|
|
3fe573926b | ||
|
|
8e2aef17e7 | ||
|
|
367c4d74af | ||
|
|
06e063d594 | ||
|
|
7ebf7a2bee | ||
|
|
b5c53baf67 | ||
|
|
536934390c | ||
|
|
1e6035b282 | ||
|
|
5bbe5fca60 | ||
|
|
e658a2a3bf | ||
|
|
4b8b155fb8 | ||
|
|
4c5aad51b3 | ||
|
|
688875dca5 | ||
|
|
ce2b982782 | ||
|
|
af61fc6c74 | ||
|
|
b4c8fbf75a | ||
|
|
edb53013b2 | ||
|
|
70f48a3d53 | ||
|
|
532a311db6 | ||
|
|
71da9933d7 | ||
|
|
9f5b9ab04c | ||
|
|
f76ac1e03a | ||
|
|
b84541f232 | ||
|
|
6115e12309 | ||
|
|
c22bc1c57f | ||
|
|
84055e9798 | ||
|
|
ccfcca8f9a | ||
|
|
c043eef5eb | ||
|
|
2db0265ae6 | ||
|
|
3cd787fb1e | ||
|
|
93f7d1f013 | ||
|
|
51f8c532ca | ||
|
|
8825b26b36 | ||
|
|
300ee0a16a | ||
|
|
f18a56ab1a | ||
|
|
9dc9fcfeff | ||
|
|
1283caf80b | ||
|
|
af230d9874 | ||
|
|
f221047eba | ||
|
|
e7b3aa82f9 | ||
|
|
33c6290864 | ||
|
|
9006e17c25 | ||
|
|
22b02cd3ee | ||
|
|
507e4ef25a | ||
|
|
8b1583df30 | ||
|
|
083568d3fd | ||
|
|
8e5af4ada4 | ||
|
|
b217e855e9 | ||
|
|
21c19bf97e | ||
|
|
5d2eb2ea15 | ||
|
|
76ec5aa009 | ||
|
|
35681c6f96 | ||
|
|
d719c437ec | ||
|
|
133910ac3b | ||
|
|
862f2ab3ac | ||
|
|
565237b29e | ||
|
|
78085d3de2 | ||
|
|
2f4361c97a | ||
|
|
b245292d11 | ||
|
|
dd7d5d9a56 | ||
|
|
4b7b042bb1 | ||
|
|
18a76fa355 | ||
|
|
ce688aabcb | ||
|
|
8e2e2e5a1e | ||
|
|
bccc4abf26 | ||
|
|
a1b31e0065 | ||
|
|
8af5de6fb5 | ||
|
|
975566eb3c | ||
|
|
572d1f2902 | ||
|
|
4a7f8b869d | ||
|
|
55164c38bf | ||
|
|
1aeb7b3ff6 | ||
|
|
967c2a5633 | ||
|
|
0203e73c71 | ||
|
|
fa77ba3f48 | ||
|
|
1aecd47d5a | ||
|
|
6b920ea3f4 | ||
|
|
6a2869138e | ||
|
|
1b36cee3b6 | ||
|
|
05e7eb3456 | ||
|
|
70f2c0051a | ||
|
|
d396ca1684 | ||
|
|
aed71ca9e2 | ||
|
|
50094fde6c | ||
|
|
d5b66fd08c | ||
|
|
34d2b12acc | ||
|
|
f0c20be967 | ||
|
|
6126ec9450 | ||
|
|
df7c45d7ef | ||
|
|
f52d8a3ad4 | ||
|
|
ab27a1bd2b | ||
|
|
e341287c56 | ||
|
|
ca5247ce1b | ||
|
|
81a8056233 | ||
|
|
a92174f32e | ||
|
|
79ec86f369 | ||
|
|
a31abef3cf | ||
|
|
f89964d8ba | ||
|
|
706a0949ee | ||
|
|
bdfd169d39 | ||
|
|
44f60169cb | ||
|
|
caad080c6c | ||
|
|
c4a2c9edc9 | ||
|
|
ee30fa6ac2 | ||
|
|
d23cf6028b | ||
|
|
6a58290833 | ||
|
|
3b9fdbd5cd | ||
|
|
d88c3106d0 | ||
|
|
34bf013b9b | ||
|
|
2e8efe8f4a | ||
|
|
54c8a6f9dd | ||
|
|
18ddbdac84 | ||
|
|
7c4ee9bebd | ||
|
|
ce397d0a4e | ||
|
|
06c8c00dc9 | ||
|
|
220e5b17aa | ||
|
|
ef217c0b19 | ||
|
|
c72e6ff9b4 | ||
|
|
305584344e | ||
|
|
a42b5fcea7 | ||
|
|
18591c434f | ||
|
|
439ebf1676 | ||
|
|
05d69457f2 | ||
|
|
a646dd900d | ||
|
|
fb54b2f280 | ||
|
|
2f8b881186 | ||
|
|
385dba63d9 | ||
|
|
95ce44f2d8 | ||
|
|
915c65176e | ||
|
|
4f472253de | ||
|
|
c53f8a7033 | ||
|
|
15cf215d49 | ||
|
|
208f214e96 | ||
|
|
e7f83669c4 | ||
|
|
2b6fecbe4d | ||
|
|
3e5542e592 | ||
|
|
1369a28aca | ||
|
|
00933b2905 | ||
|
|
dd39ff4e94 | ||
|
|
922b61b9fe | ||
|
|
5a7551d312 | ||
|
|
94c208cbc9 | ||
|
|
1ea916ec73 | ||
|
|
f56b2229a7 | ||
|
|
4f91ba6081 | ||
|
|
9f22e2cc71 | ||
|
|
e17de754a3 | ||
|
|
18885f0450 | ||
|
|
0f9f615313 | ||
|
|
d84f3fcd24 | ||
|
|
fa6d53634b | ||
|
|
ce24d2b4a6 | ||
|
|
f151e1e5f4 | ||
|
|
59ab62685c | ||
|
|
e68b715321 | ||
|
|
ef95cfb1f5 | ||
|
|
d120875fa9 | ||
|
|
9dfff9ae5e | ||
|
|
86d8eb023d | ||
|
|
b48c467d57 | ||
|
|
cf4c269f77 | ||
|
|
2fb83c89af | ||
|
|
37a176e3ae | ||
|
|
09776a60c9 | ||
|
|
17838d7099 | ||
|
|
531f8a9106 | ||
|
|
a3289205e6 | ||
|
|
0af5e1428b | ||
|
|
7ec9a93231 | ||
|
|
9984055f7d | ||
|
|
4e29565382 | ||
|
|
bc734f1190 | ||
|
|
7d8add6d4c | ||
|
|
ec8a399ca6 | ||
|
|
1935bd235e | ||
|
|
c6631356ea | ||
|
|
f2e966735c | ||
|
|
35c2cb45bb | ||
|
|
33fcb86383 | ||
|
|
8096c170d5 | ||
|
|
333eba2cb8 | ||
|
|
3cb6bd3a99 | ||
|
|
f8ab65ce0e | ||
|
|
707a5a778a | ||
|
|
6f183bad74 | ||
|
|
28a38d04fd | ||
|
|
051cc4955f | ||
|
|
e06b2c5e4f | ||
|
|
8157d7a8d0 | ||
|
|
a522568a60 | ||
|
|
b6ecd52444 | ||
|
|
3105ef7cb6 | ||
|
|
356f4a041f | ||
|
|
6d43ab371e | ||
|
|
a1a8f90cc5 | ||
|
|
c10b4fb129 | ||
|
|
e025b6b407 | ||
|
|
10f12e4ead | ||
|
|
3c71af48ee | ||
|
|
daa68cb110 | ||
|
|
10b49b4a15 | ||
|
|
bcae1bbd89 | ||
|
|
624a4aa70a | ||
|
|
0702057f47 | ||
|
|
89371378b7 | ||
|
|
f3b49ecc0a | ||
|
|
fb1e9972a5 | ||
|
|
f6a26e3723 | ||
|
|
26027245f0 | ||
|
|
a66529d482 | ||
|
|
bbb086ae6b | ||
|
|
4ed387cc6b | ||
|
|
b88c6b5f6c | ||
|
|
30ae32e539 | ||
|
|
e42ea47ea8 | ||
|
|
96f7a79f3a | ||
|
|
6378cbc0ee | ||
|
|
f3a5b735d6 | ||
|
|
473735dcd7 | ||
|
|
220edef653 | ||
|
|
2619fe814a | ||
|
|
599f31dfae | ||
|
|
8ab12e5e9a | ||
|
|
314032ba3d | ||
|
|
961658ee9a | ||
|
|
2b0fcd3426 | ||
|
|
824431ae94 | ||
|
|
923ea597ec | ||
|
|
9112d6cc6e | ||
|
|
ece08e5e37 | ||
|
|
96fdf72400 | ||
|
|
5fd4f96fc8 | ||
|
|
13449cc9ee | ||
|
|
eab81a2bf9 | ||
|
|
264cf69a6f | ||
|
|
0e9caf2d3f | ||
|
|
45429c8f2a | ||
|
|
312007b51c | ||
|
|
3106f62709 | ||
|
|
48595e1282 | ||
|
|
ee20d91a5e | ||
|
|
9abc4f9725 | ||
|
|
cc064c95b1 | ||
|
|
1f2e3d6514 | ||
|
|
71566e3a53 | ||
|
|
4b62fbd497 | ||
|
|
b96628eba8 |
@@ -4,5 +4,6 @@
|
||||
<listEntry value="org.eclipse.ui.externaltools.launchGroup"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/Moose_Framework/Utils/GenerateDocumentations.bat}"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS" value="*.lua"/>
|
||||
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/Moose_Framework/Utils}"/>
|
||||
</launchConfiguration>
|
||||
|
||||
BIN
Moose Development/Maths/Aspect.ggb
Normal file
BIN
Moose Development/Maths/Aspect.ggb
Normal file
Binary file not shown.
553
Moose Development/Moose/AI/AI_A2A.lua
Normal file
553
Moose Development/Moose/AI/AI_A2A.lua
Normal file
@@ -0,0 +1,553 @@
|
||||
--- **AI** -- **AI A2A Air Patrolling or Staging.**
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Testing and API concept review.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_A2A
|
||||
|
||||
--BASE:TraceClass("AI_A2A")
|
||||
|
||||
|
||||
--- @type AI_A2A
|
||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||
|
||||
--- # AI_A2A class, extends @{Fsm#FSM_CONTROLLABLE}
|
||||
--
|
||||
-- The AI_A2A class implements the core functions to operate an AI @{Group} A2A tasking.
|
||||
--
|
||||
--
|
||||
-- ## AI_A2A constructor
|
||||
--
|
||||
-- * @{#AI_A2A.New}(): Creates a new AI_A2A object.
|
||||
--
|
||||
-- ## 2. AI_A2A is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 2.1. AI_A2A States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||
-- * **Returning** ( Group ): The AI is returning to Base.
|
||||
-- * **Stopped** ( Group ): The process is stopped.
|
||||
-- * **Crashed** ( Group ): The AI has crashed or is dead.
|
||||
--
|
||||
-- ### 2.2. AI_A2A Events
|
||||
--
|
||||
-- * **Start** ( Group ): Start the process.
|
||||
-- * **Stop** ( Group ): Stop the process.
|
||||
-- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone.
|
||||
-- * **RTB** ( Group ): Route the AI to the home base.
|
||||
-- * **Detect** ( Group ): The AI is detecting targets.
|
||||
-- * **Detected** ( Group ): The AI has detected new targets.
|
||||
-- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- ## 3. Set or Get the AI controllable
|
||||
--
|
||||
-- * @{#AI_A2A.SetControllable}(): Set the AIControllable.
|
||||
-- * @{#AI_A2A.GetControllable}(): Get the AIControllable.
|
||||
--
|
||||
-- @field #AI_A2A
|
||||
AI_A2A = {
|
||||
ClassName = "AI_A2A",
|
||||
}
|
||||
|
||||
--- Creates a new AI_A2A object
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Group#GROUP AIGroup The GROUP object to receive the A2A Process.
|
||||
-- @return #AI_A2A
|
||||
function AI_A2A:New( AIGroup )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_A2A
|
||||
|
||||
self:SetControllable( AIGroup )
|
||||
|
||||
self:ManageFuel( .2, 60 )
|
||||
self:ManageDamage( 0.4 )
|
||||
|
||||
self:SetStartState( "Stopped" )
|
||||
|
||||
self:AddTransition( "*", "Start", "Started" )
|
||||
|
||||
--- Start Handler OnBefore for AI_A2A
|
||||
-- @function [parent=#AI_A2A] OnBeforeStart
|
||||
-- @param #AI_A2A self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Start Handler OnAfter for AI_A2A
|
||||
-- @function [parent=#AI_A2A] OnAfterStart
|
||||
-- @param #AI_A2A self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Start Trigger for AI_A2A
|
||||
-- @function [parent=#AI_A2A] Start
|
||||
-- @param #AI_A2A self
|
||||
|
||||
--- Start Asynchronous Trigger for AI_A2A
|
||||
-- @function [parent=#AI_A2A] __Start
|
||||
-- @param #AI_A2A self
|
||||
-- @param #number Delay
|
||||
|
||||
self:AddTransition( "*", "Stop", "Stopped" )
|
||||
|
||||
--- OnLeave Transition Handler for State Stopped.
|
||||
-- @function [parent=#AI_A2A] OnLeaveStopped
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnEnter Transition Handler for State Stopped.
|
||||
-- @function [parent=#AI_A2A] OnEnterStopped
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
|
||||
--- OnBefore Transition Handler for Event Stop.
|
||||
-- @function [parent=#AI_A2A] OnBeforeStop
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Stop.
|
||||
-- @function [parent=#AI_A2A] OnAfterStop
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
|
||||
--- Synchronous Event Trigger for Event Stop.
|
||||
-- @function [parent=#AI_A2A] Stop
|
||||
-- @param #AI_A2A self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Stop.
|
||||
-- @function [parent=#AI_A2A] __Stop
|
||||
-- @param #AI_A2A self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Status", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A.
|
||||
|
||||
--- OnBefore Transition Handler for Event Status.
|
||||
-- @function [parent=#AI_A2A] OnBeforeStatus
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event Status.
|
||||
-- @function [parent=#AI_A2A] OnAfterStatus
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
|
||||
--- Synchronous Event Trigger for Event Status.
|
||||
-- @function [parent=#AI_A2A] Status
|
||||
-- @param #AI_A2A self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Status.
|
||||
-- @function [parent=#AI_A2A] __Status
|
||||
-- @param #AI_A2A self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "RTB", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A.
|
||||
|
||||
--- OnBefore Transition Handler for Event RTB.
|
||||
-- @function [parent=#AI_A2A] OnBeforeRTB
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnAfter Transition Handler for Event RTB.
|
||||
-- @function [parent=#AI_A2A] OnAfterRTB
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
|
||||
--- Synchronous Event Trigger for Event RTB.
|
||||
-- @function [parent=#AI_A2A] RTB
|
||||
-- @param #AI_A2A self
|
||||
|
||||
--- Asynchronous Event Trigger for Event RTB.
|
||||
-- @function [parent=#AI_A2A] __RTB
|
||||
-- @param #AI_A2A self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- OnLeave Transition Handler for State Returning.
|
||||
-- @function [parent=#AI_A2A] OnLeaveReturning
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- OnEnter Transition Handler for State Returning.
|
||||
-- @function [parent=#AI_A2A] OnEnterReturning
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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.
|
||||
|
||||
|
||||
self:AddTransition( "*", "Return", "Returning" )
|
||||
self:AddTransition( "*", "Home", "Home" )
|
||||
self:AddTransition( "*", "LostControl", "LostControl" )
|
||||
self:AddTransition( "*", "Fuel", "Fuel" )
|
||||
self:AddTransition( "*", "Damaged", "Damaged" )
|
||||
self:AddTransition( "*", "Eject", "*" )
|
||||
self:AddTransition( "*", "Crash", "Crashed" )
|
||||
self:AddTransition( "*", "PilotDead", "*" )
|
||||
|
||||
self.IdleCount = 0
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function AI_A2A:SetDispatcher( Dispatcher )
|
||||
self.Dispatcher = Dispatcher
|
||||
end
|
||||
|
||||
function AI_A2A:GetDispatcher()
|
||||
return self.Dispatcher
|
||||
end
|
||||
|
||||
function AI_A2A:SetTargetDistance( Coordinate )
|
||||
|
||||
local CurrentCoord = self.Controllable:GetCoordinate()
|
||||
self.TargetDistance = CurrentCoord:Get2DDistance( Coordinate )
|
||||
|
||||
self.ClosestTargetDistance = ( not self.ClosestTargetDistance or self.ClosestTargetDistance > self.TargetDistance ) and self.TargetDistance or self.ClosestTargetDistance
|
||||
end
|
||||
|
||||
|
||||
function AI_A2A:ClearTargetDistance()
|
||||
|
||||
self.TargetDistance = nil
|
||||
self.ClosestTargetDistance = nil
|
||||
end
|
||||
|
||||
|
||||
--- Sets (modifies) the minimum and maximum speed of the patrol.
|
||||
-- @param #AI_A2A 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.
|
||||
-- @return #AI_A2A self
|
||||
function AI_A2A:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
|
||||
self:F2( { PatrolMinSpeed, PatrolMaxSpeed } )
|
||||
|
||||
self.PatrolMinSpeed = PatrolMinSpeed
|
||||
self.PatrolMaxSpeed = PatrolMaxSpeed
|
||||
end
|
||||
|
||||
|
||||
--- Sets the floor and ceiling altitude of the patrol.
|
||||
-- @param #AI_A2A self
|
||||
-- @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.
|
||||
-- @return #AI_A2A self
|
||||
function AI_A2A:SetAltitude( PatrolFloorAltitude, PatrolCeilingAltitude )
|
||||
self:F2( { PatrolFloorAltitude, PatrolCeilingAltitude } )
|
||||
|
||||
self.PatrolFloorAltitude = PatrolFloorAltitude
|
||||
self.PatrolCeilingAltitude = PatrolCeilingAltitude
|
||||
end
|
||||
|
||||
|
||||
--- Sets the home airbase.
|
||||
-- @param #AI_A2A self
|
||||
-- @param Wrapper.Airbase#AIRBASE HomeAirbase
|
||||
-- @return #AI_A2A self
|
||||
function AI_A2A:SetHomeAirbase( HomeAirbase )
|
||||
self:F2( { HomeAirbase } )
|
||||
|
||||
self.HomeAirbase = HomeAirbase
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Set the status checking off.
|
||||
-- @param #AI_A2A self
|
||||
-- @return #AI_A2A self
|
||||
function AI_A2A:SetStatusOff()
|
||||
self:F2()
|
||||
|
||||
self.CheckStatus = false
|
||||
end
|
||||
|
||||
|
||||
--- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
|
||||
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel treshold is calculated.
|
||||
-- When the fuel treshold is reached, the AI will continue for a given time its patrol task in orbit, while a new AIControllable is targetted to the AI_A2A.
|
||||
-- Once the time is finished, the old AI will return to the base.
|
||||
-- @param #AI_A2A self
|
||||
-- @param #number PatrolFuelTresholdPercentage The treshold in percentage (between 0 and 1) when the AIControllable is considered to get out of fuel.
|
||||
-- @param #number PatrolOutOfFuelOrbitTime The amount of seconds the out of fuel AIControllable will orbit before returning to the base.
|
||||
-- @return #AI_A2A self
|
||||
function AI_A2A:ManageFuel( PatrolFuelTresholdPercentage, PatrolOutOfFuelOrbitTime )
|
||||
|
||||
self.PatrolManageFuel = true
|
||||
self.PatrolFuelTresholdPercentage = PatrolFuelTresholdPercentage
|
||||
self.PatrolOutOfFuelOrbitTime = PatrolOutOfFuelOrbitTime
|
||||
|
||||
self.Controllable:OptionRTBBingoFuel( false )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- When the AI is damaged beyond a certain treshold, it is required that the AI returns to the home base.
|
||||
-- However, damage cannot be foreseen early on.
|
||||
-- Therefore, when the damage treshold is reached,
|
||||
-- the AI will return immediately to the home base (RTB).
|
||||
-- Note that for groups, the average damage of the complete group will be calculated.
|
||||
-- So, in a group of 4 airplanes, 2 lost and 2 with damage 0.2, the damage treshold will be 0.25.
|
||||
-- @param #AI_A2A self
|
||||
-- @param #number PatrolDamageTreshold The treshold in percentage (between 0 and 1) when the AI is considered to be damaged.
|
||||
-- @return #AI_A2A self
|
||||
function AI_A2A:ManageDamage( PatrolDamageTreshold )
|
||||
|
||||
self.PatrolManageDamage = true
|
||||
self.PatrolDamageTreshold = PatrolDamageTreshold
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Defines a new patrol route using the @{Process_PatrolZone} parameters and settings.
|
||||
-- @param #AI_A2A self
|
||||
-- @return #AI_A2A self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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:onafterStart( Controllable, From, Event, To )
|
||||
self:F2()
|
||||
|
||||
self:__Status( 10 ) -- Check status status every 30 seconds.
|
||||
|
||||
self:HandleEvent( EVENTS.PilotDead, self.OnPilotDead )
|
||||
self:HandleEvent( EVENTS.Crash, self.OnCrash )
|
||||
self:HandleEvent( EVENTS.Ejection, self.OnEjection )
|
||||
|
||||
Controllable:OptionROEHoldFire()
|
||||
Controllable:OptionROTVertical()
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_A2A self
|
||||
function AI_A2A:onbeforeStatus()
|
||||
|
||||
return self.CheckStatus
|
||||
end
|
||||
|
||||
--- @param #AI_A2A self
|
||||
function AI_A2A:onafterStatus()
|
||||
self:F()
|
||||
|
||||
if self.Controllable and self.Controllable:IsAlive() then
|
||||
|
||||
local RTB = false
|
||||
|
||||
local Fuel = self.Controllable:GetUnit(1):GetFuel()
|
||||
self:F({Fuel=Fuel})
|
||||
if Fuel < self.PatrolFuelTresholdPercentage then
|
||||
self:E( self.Controllable:GetName() .. " is out of fuel: " .. Fuel .. " ... RTB!" )
|
||||
local OldAIControllable = self.Controllable
|
||||
local AIControllableTemplate = self.Controllable:GetTemplate()
|
||||
|
||||
local OrbitTask = OldAIControllable:TaskOrbitCircle( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ), self.PatrolMinSpeed )
|
||||
local TimedOrbitTask = OldAIControllable:TaskControlled( OrbitTask, OldAIControllable:TaskCondition(nil,nil,nil,nil,self.PatrolOutOfFuelOrbitTime,nil ) )
|
||||
OldAIControllable:SetTask( TimedOrbitTask, 10 )
|
||||
|
||||
self:Fuel()
|
||||
RTB = true
|
||||
else
|
||||
end
|
||||
|
||||
-- TODO: Check GROUP damage function.
|
||||
local Damage = self.Controllable:GetLife()
|
||||
local InitialLife = self.Controllable:GetLife0()
|
||||
self:F( { Damage = Damage, InitialLife = InitialLife, DamageTreshold = self.PatrolDamageTreshold } )
|
||||
if ( Damage / InitialLife ) < self.PatrolDamageTreshold then
|
||||
self:E( self.Controllable:GetName() .. " is damaged: " .. Damage .. " ... RTB!" )
|
||||
self:Damaged()
|
||||
RTB = true
|
||||
end
|
||||
|
||||
-- Check if planes went RTB and are out of control.
|
||||
if self.Controllable:HasTask() == false then
|
||||
if not self:Is( "Started" ) and
|
||||
not self:Is( "Stopped" ) then
|
||||
if self.IdleCount >= 2 then
|
||||
self:E( self.Controllable:GetName() .. " control lost! " )
|
||||
self:LostControl()
|
||||
else
|
||||
self.IdleCount = self.IdleCount + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
self.IdleCount = 0
|
||||
end
|
||||
|
||||
if RTB == true then
|
||||
self:__RTB( 0.5 )
|
||||
end
|
||||
|
||||
self:__Status( 10 )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- @param Wrapper.Group#GROUP AIGroup
|
||||
function AI_A2A.RTBRoute( AIGroup )
|
||||
|
||||
AIGroup:E( { "RTBRoute:", AIGroup:GetName() } )
|
||||
local _AI_A2A = AIGroup:GetState( AIGroup, "AI_A2A" ) -- #AI_A2A
|
||||
_AI_A2A:__RTB( 0.5 )
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_A2A self
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
function AI_A2A:onafterRTB( AIGroup, From, Event, To )
|
||||
self:F( { AIGroup, From, Event, To } )
|
||||
|
||||
|
||||
if AIGroup and AIGroup:IsAlive() then
|
||||
|
||||
self:E( "Group " .. AIGroup:GetName() .. " ... RTB! ( " .. self:GetState() .. " )" )
|
||||
|
||||
self.CheckStatus = false
|
||||
|
||||
self:ClearTargetDistance()
|
||||
AIGroup:ClearTasks()
|
||||
|
||||
local EngageRoute = {}
|
||||
|
||||
--- Calculate the target route point.
|
||||
|
||||
local CurrentCoord = AIGroup:GetCoordinate()
|
||||
local ToTargetCoord = self.HomeAirbase:GetCoordinate()
|
||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||
local ToAirbaseAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
||||
|
||||
local Distance = CurrentCoord:Get2DDistance( ToTargetCoord )
|
||||
|
||||
local ToAirbaseCoord = CurrentCoord:Translate( 5000, ToAirbaseAngle )
|
||||
if Distance < 5000 then
|
||||
self:Home()
|
||||
return
|
||||
end
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = ToAirbaseCoord:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
self:F( { Angle = ToAirbaseAngle, ToTargetSpeed = ToTargetSpeed } )
|
||||
self:T2( { self.MinSpeed, self.MaxSpeed, ToTargetSpeed } )
|
||||
|
||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
AIGroup:OptionROEHoldFire()
|
||||
AIGroup:OptionROTEvadeFire()
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
AIGroup:WayPointInitialize( EngageRoute )
|
||||
|
||||
local Tasks = {}
|
||||
Tasks[#Tasks+1] = AIGroup:TaskFunction( 1, 1, "AI_A2A.RTBRoute" )
|
||||
EngageRoute[1].task = AIGroup:TaskCombo( Tasks )
|
||||
|
||||
AIGroup:SetState( AIGroup, "AI_A2A", self )
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
AIGroup:WayPointExecute( 1, 0 )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_A2A self
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
function AI_A2A:onafterHome( AIGroup, From, Event, To )
|
||||
self:F( { AIGroup, From, Event, To } )
|
||||
|
||||
self:E( "Group " .. self.Controllable:GetName() .. " ... Home! ( " .. self:GetState() .. " )" )
|
||||
|
||||
if AIGroup and AIGroup:IsAlive() then
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_A2A self
|
||||
function AI_A2A:onafterDead()
|
||||
self:SetStatusOff()
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_A2A self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_A2A:OnCrash( EventData )
|
||||
|
||||
if self.Controllable:IsAlive() and EventData.IniDCSGroupName == self.Controllable:GetName() then
|
||||
self:E( self.Controllable:GetUnits() )
|
||||
if #self.Controllable:GetUnits() == 1 then
|
||||
self:__Crash( 1, EventData )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_A2A:OnEjection( EventData )
|
||||
|
||||
if self.Controllable:IsAlive() and EventData.IniDCSGroupName == self.Controllable:GetName() then
|
||||
self:__Eject( 1, EventData )
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_A2A:OnPilotDead( EventData )
|
||||
|
||||
if self.Controllable:IsAlive() and EventData.IniDCSGroupName == self.Controllable:GetName() then
|
||||
self:__PilotDead( 1, EventData )
|
||||
end
|
||||
end
|
||||
491
Moose Development/Moose/AI/AI_A2A_Cap.lua
Normal file
491
Moose Development/Moose/AI/AI_A2A_Cap.lua
Normal file
@@ -0,0 +1,491 @@
|
||||
--- **AI** -- **Execute Combat Air Patrol (CAP).**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- AI CAP classes makes AI Controllables execute a Combat Air Patrol.
|
||||
--
|
||||
-- There are the following types of CAP classes defined:
|
||||
--
|
||||
-- * @{#AI_A2A_CAP}: Perform a CAP in a zone.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing.
|
||||
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_A2A_Cap
|
||||
|
||||
--BASE:TraceClass("AI_A2A_CAP")
|
||||
|
||||
--- @type AI_A2A_CAP
|
||||
-- @extends AI.AI_A2A_Patrol#AI_A2A_PATROL
|
||||
|
||||
|
||||
--- # 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}
|
||||
-- and automatically engage any airborne enemies that are within a certain range or within a certain zone.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_A2A_CAP is assigned a @{Group} and this must be done before the AI_A2A_CAP process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When enemies are detected, the AI will automatically engage the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage treshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1. AI_A2A_CAP constructor
|
||||
--
|
||||
-- * @{#AI_A2A_CAP.New}(): Creates a new AI_A2A_CAP object.
|
||||
--
|
||||
-- ## 2. AI_A2A_CAP is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 2.1 AI_A2A_CAP States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||
-- * **Engaging** ( Group ): The AI is engaging the bogeys.
|
||||
-- * **Returning** ( Group ): The AI is returning to Base..
|
||||
--
|
||||
-- ### 2.2 AI_A2A_CAP Events
|
||||
--
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Start}**: Start the process.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Route}**: Route the AI to a new random 3D point within the Patrol Zone.
|
||||
-- * **@{#AI_A2A_CAP.Engage}**: Let the AI engage the bogeys.
|
||||
-- * **@{#AI_A2A_CAP.Abort}**: Aborts the engagement and return patrolling in the patrol zone.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.RTB}**: Route the AI to the home base.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Detect}**: The AI is detecting targets.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Detected}**: The AI has detected new targets.
|
||||
-- * **@{#AI_A2A_CAP.Destroy}**: The AI has destroyed a bogey @{Unit}.
|
||||
-- * **@{#AI_A2A_CAP.Destroyed}**: The AI has destroyed all bogeys @{Unit}s assigned in the CAS task.
|
||||
-- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- ## 3. Set the Range of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional range can be set in meters,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- The range can be beyond or smaller than the range of the Patrol Zone.
|
||||
-- The range is applied at the position of the AI.
|
||||
-- Use the method @{AI_CAP#AI_A2A_CAP.SetEngageRange}() to define that range.
|
||||
--
|
||||
-- ## 4. Set the Zone of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional @{Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{AI_Cap#AI_A2A_CAP.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2A_CAP
|
||||
AI_A2A_CAP = {
|
||||
ClassName = "AI_A2A_CAP",
|
||||
}
|
||||
|
||||
--- Creates a new AI_A2A_CAP object
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
-- @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#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 )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed, PatrolAltType ) ) -- #AI_A2A_CAP
|
||||
|
||||
self.Accomplished = false
|
||||
self.Engaging = false
|
||||
|
||||
self.EngageMinSpeed = EngageMinSpeed
|
||||
self.EngageMaxSpeed = EngageMaxSpeed
|
||||
|
||||
self:AddTransition( { "Patrolling", "Engaging", "Returning" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_CAP.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_A2A_CAP] Engage
|
||||
-- @param #AI_A2A_CAP self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_A2A_CAP] __Engage
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
self:AddTransition( "Engaging", "Fired", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_CAP.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_A2A_CAP] Fired
|
||||
-- @param #AI_A2A_CAP self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_A2A_CAP] __Fired
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Destroy", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_CAP.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_A2A_CAP] Destroy
|
||||
-- @param #AI_A2A_CAP self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_A2A_CAP] __Destroy
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
|
||||
self:AddTransition( "Engaging", "Abort", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_CAP.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_A2A_CAP] Abort
|
||||
-- @param #AI_A2A_CAP self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_A2A_CAP] __Abort
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "Engaging", "Accomplish", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_CAP.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_A2A_CAP] Accomplish
|
||||
-- @param #AI_A2A_CAP self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_A2A_CAP] __Accomplish
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set the Engage Zone which defines where the AI will engage bogies.
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param Core.Zone#ZONE EngageZone The zone where the AI is performing CAP.
|
||||
-- @return #AI_A2A_CAP self
|
||||
function AI_A2A_CAP:SetEngageZone( EngageZone )
|
||||
self:F2()
|
||||
|
||||
if EngageZone then
|
||||
self.EngageZone = EngageZone
|
||||
else
|
||||
self.EngageZone = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Set the Engage Range when the AI will engage with airborne enemies.
|
||||
-- @param #AI_A2A_CAP self
|
||||
-- @param #number EngageRange The Engage Range.
|
||||
-- @return #AI_A2A_CAP self
|
||||
function AI_A2A_CAP:SetEngageRange( EngageRange )
|
||||
self:F2()
|
||||
|
||||
if EngageRange then
|
||||
self.EngageRange = EngageRange
|
||||
else
|
||||
self.EngageRange = nil
|
||||
end
|
||||
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 #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 )
|
||||
|
||||
-- Call the parent Start event handler
|
||||
self:GetParent(self).onafterPatrol( self, AIGroup, 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 )
|
||||
|
||||
local EngageZone = AIGroup:GetState( AIGroup, "AI_A2A_CAP" ) -- AI.AI_Cap#AI_A2A_CAP
|
||||
EngageZone:__Engage( 0.5 )
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_CAP self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The Controllable 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 )
|
||||
|
||||
if self.Accomplished == true then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_CAP self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup 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()
|
||||
self:__Route( 0.5 )
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_A2A_CAP self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE AIGroup The Controllable 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 )
|
||||
|
||||
self:F( { AIGroup, From, Event, To, AttackSetUnit} )
|
||||
|
||||
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
local FirstAttackUnit = self.AttackSetUnit:GetFirst()
|
||||
|
||||
if FirstAttackUnit then
|
||||
|
||||
if AIGroup:IsAlive() then
|
||||
|
||||
local EngageRoute = {}
|
||||
|
||||
--- Calculate the target route point.
|
||||
local CurrentCoord = AIGroup:GetCoordinate()
|
||||
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
||||
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
||||
local ToInterceptAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = CurrentCoord:Translate( 5000, ToInterceptAngle ):RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
self:F( { Angle = ToInterceptAngle, ToTargetSpeed = ToTargetSpeed } )
|
||||
self:T2( { self.MinSpeed, self.MaxSpeed, ToTargetSpeed } )
|
||||
|
||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
AIGroup:OptionROEOpenFire()
|
||||
AIGroup:OptionROTPassiveDefense()
|
||||
|
||||
local AttackTasks = {}
|
||||
|
||||
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
||||
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 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
self.Controllable:WayPointInitialize( EngageRoute )
|
||||
|
||||
|
||||
if #AttackTasks == 0 then
|
||||
self:E("No targets found -> Going back to Patrolling")
|
||||
self:__Abort( 0.5 )
|
||||
else
|
||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( 1, #AttackTasks, "AI_A2A_CAP.AttackRoute" )
|
||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskOrbitCircle( 4000, self.PatrolMinSpeed )
|
||||
|
||||
EngageRoute[1].task = AIGroup:TaskCombo( AttackTasks )
|
||||
|
||||
--- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ...
|
||||
AIGroup:SetState( AIGroup, "AI_A2A_CAP", self )
|
||||
end
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
AIGroup:WayPointExecute( 1, 0 )
|
||||
end
|
||||
else
|
||||
self:E("No targets found -> Going back to Patrolling")
|
||||
self:__Abort( 0.5 )
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_CAP self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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 )
|
||||
self.Accomplished = true
|
||||
self:SetDetectionOff()
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_CAP self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable 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 )
|
||||
|
||||
if EventData.IniUnit then
|
||||
self.AttackUnits[EventData.IniUnit] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_CAP self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_A2A_CAP:OnEventDead( EventData )
|
||||
self:F( { "EventDead", EventData } )
|
||||
|
||||
if EventData.IniDCSUnit then
|
||||
if self.AttackUnits and self.AttackUnits[EventData.IniUnit] then
|
||||
self:__Destroy( 1, EventData )
|
||||
end
|
||||
end
|
||||
end
|
||||
2382
Moose Development/Moose/AI/AI_A2A_Dispatcher.lua
Normal file
2382
Moose Development/Moose/AI/AI_A2A_Dispatcher.lua
Normal file
File diff suppressed because it is too large
Load Diff
462
Moose Development/Moose/AI/AI_A2A_Gci.lua
Normal file
462
Moose Development/Moose/AI/AI_A2A_Gci.lua
Normal file
@@ -0,0 +1,462 @@
|
||||
--- **AI** -- **Execute Ground Controlled Interception (GCI).**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- AI A2A_INTEREPT class makes AI Groups execute an Intercept.
|
||||
--
|
||||
-- There are the following types of GCI classes defined:
|
||||
--
|
||||
-- * @{#AI_A2A_GCI}: Perform a GCI in a zone.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_A2A_GCI
|
||||
|
||||
|
||||
--BASE:TraceClass("AI_A2A_GCI")
|
||||
|
||||
|
||||
--- @type AI_A2A_GCI
|
||||
-- @extends AI.AI_A2A#AI_A2A
|
||||
|
||||
|
||||
--- # AI_A2A_GCI class, extends @{AI_A2A#AI_A2A}
|
||||
--
|
||||
-- The AI_A2A_GCI class implements the core functions to intercept intruders. The Engage function will intercept intruders.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI_A2A_GCI is assigned a @{Group} and this must be done before the AI_A2A_GCI process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- When enemies are detected, the AI will automatically engage the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage treshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1. AI_A2A_GCI constructor
|
||||
--
|
||||
-- * @{#AI_A2A_GCI.New}(): Creates a new AI_A2A_GCI object.
|
||||
--
|
||||
-- ## 2. AI_A2A_GCI is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 2.1 AI_A2A_GCI States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||
-- * **Engaging** ( Group ): The AI is engaging the bogeys.
|
||||
-- * **Returning** ( Group ): The AI is returning to Base..
|
||||
--
|
||||
-- ### 2.2 AI_A2A_GCI Events
|
||||
--
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Start}**: Start the process.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Route}**: Route the AI to a new random 3D point within the Patrol Zone.
|
||||
-- * **@{#AI_A2A_GCI.Engage}**: Let the AI engage the bogeys.
|
||||
-- * **@{#AI_A2A_GCI.Abort}**: Aborts the engagement and return patrolling in the patrol zone.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.RTB}**: Route the AI to the home base.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Detect}**: The AI is detecting targets.
|
||||
-- * **@{AI_Patrol#AI_PATROL_ZONE.Detected}**: The AI has detected new targets.
|
||||
-- * **@{#AI_A2A_GCI.Destroy}**: The AI has destroyed a bogey @{Unit}.
|
||||
-- * **@{#AI_A2A_GCI.Destroyed}**: The AI has destroyed all bogeys @{Unit}s assigned in the CAS task.
|
||||
-- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- ## 3. Set the Range of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional range can be set in meters,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- The range can be beyond or smaller than the range of the Patrol Zone.
|
||||
-- The range is applied at the position of the AI.
|
||||
-- Use the method @{AI_GCI#AI_A2A_GCI.SetEngageRange}() to define that range.
|
||||
--
|
||||
-- ## 4. Set the Zone of Engagement
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- An optional @{Zone} can be set,
|
||||
-- that will define when the AI will engage with the detected airborne enemy targets.
|
||||
-- Use the method @{AI_Cap#AI_A2A_GCI.SetEngageZone}() to define that Zone.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2A_GCI
|
||||
AI_A2A_GCI = {
|
||||
ClassName = "AI_A2A_GCI",
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Creates a new AI_A2A_GCI object
|
||||
-- @param #AI_A2A_GCI self
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
-- @return #AI_A2A_GCI
|
||||
function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, AI_A2A:New( AIGroup ) ) -- #AI_A2A_GCI
|
||||
|
||||
self.Accomplished = false
|
||||
self.Engaging = false
|
||||
|
||||
self.EngageMinSpeed = EngageMinSpeed
|
||||
self.EngageMaxSpeed = EngageMaxSpeed
|
||||
self.PatrolMinSpeed = EngageMinSpeed
|
||||
self.PatrolMaxSpeed = EngageMaxSpeed
|
||||
|
||||
self.PatrolAltType = "RADIO"
|
||||
|
||||
self:AddTransition( { "Started", "Engaging", "Returning" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_GCI.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_A2A_GCI] Engage
|
||||
-- @param #AI_A2A_GCI self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Engage.
|
||||
-- @function [parent=#AI_A2A_GCI] __Engage
|
||||
-- @param #AI_A2A_GCI self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
self:AddTransition( "Engaging", "Fired", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_GCI.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_A2A_GCI] Fired
|
||||
-- @param #AI_A2A_GCI self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Fired.
|
||||
-- @function [parent=#AI_A2A_GCI] __Fired
|
||||
-- @param #AI_A2A_GCI self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Destroy", "*" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_GCI.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_A2A_GCI] Destroy
|
||||
-- @param #AI_A2A_GCI self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Destroy.
|
||||
-- @function [parent=#AI_A2A_GCI] __Destroy
|
||||
-- @param #AI_A2A_GCI self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
|
||||
self:AddTransition( "Engaging", "Abort", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_GCI.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_A2A_GCI] Abort
|
||||
-- @param #AI_A2A_GCI self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Abort.
|
||||
-- @function [parent=#AI_A2A_GCI] __Abort
|
||||
-- @param #AI_A2A_GCI self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "Engaging", "Accomplish", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_GCI.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_A2A_GCI] Accomplish
|
||||
-- @param #AI_A2A_GCI self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Accomplish.
|
||||
-- @function [parent=#AI_A2A_GCI] __Accomplish
|
||||
-- @param #AI_A2A_GCI self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
return self
|
||||
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 #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 )
|
||||
|
||||
self:HandleEvent( EVENTS.Dead )
|
||||
|
||||
end
|
||||
|
||||
-- todo: need to fix this global function
|
||||
|
||||
--- @param Wrapper.Group#GROUP AIControllable
|
||||
function AI_A2A_GCI.InterceptRoute( AIControllable )
|
||||
|
||||
AIControllable:T( "NewEngageRoute" )
|
||||
local EngageZone = AIControllable:GetState( AIControllable, "EngageZone" ) -- AI.AI_Cap#AI_A2A_GCI
|
||||
EngageZone:__Engage( 0.5 )
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_GCI self
|
||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup 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 )
|
||||
|
||||
if self.Accomplished == true then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_GCI self
|
||||
-- @param Wrapper.Group#GROUP AIGroup 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()
|
||||
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 #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 )
|
||||
|
||||
self:F( { AIGroup, From, Event, To, AttackSetUnit} )
|
||||
|
||||
self.AttackSetUnit = AttackSetUnit or self.AttackSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
local FirstAttackUnit = self.AttackSetUnit:GetFirst()
|
||||
|
||||
if FirstAttackUnit then
|
||||
|
||||
if AIGroup:IsAlive() then
|
||||
|
||||
local EngageRoute = {}
|
||||
|
||||
--- Calculate the target route point.
|
||||
|
||||
local CurrentCoord = AIGroup:GetCoordinate()
|
||||
|
||||
local ToTargetCoord = self.AttackSetUnit:GetFirst():GetCoordinate()
|
||||
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
||||
|
||||
local ToTargetSpeed = math.random( self.EngageMinSpeed, self.EngageMaxSpeed )
|
||||
local ToInterceptAngle = CurrentCoord:GetAngleDegrees( CurrentCoord:GetDirectionVec3( ToTargetCoord ) )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = CurrentCoord:Translate( 5000, ToInterceptAngle ):RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
self:F( { Angle = ToInterceptAngle, ToTargetSpeed = ToTargetSpeed } )
|
||||
self:T2( { self.EngageMinSpeed, self.EngageMaxSpeed, ToTargetSpeed } )
|
||||
|
||||
EngageRoute[#EngageRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
AIGroup:OptionROEOpenFire()
|
||||
AIGroup:OptionROTPassiveDefense()
|
||||
|
||||
local AttackTasks = {}
|
||||
|
||||
for AttackUnitID, AttackUnit in pairs( self.AttackSetUnit:GetSet() ) do
|
||||
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
||||
self:T( { "Intercepting Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
||||
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskAttackUnit( AttackUnit )
|
||||
end
|
||||
end
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
AIGroup:WayPointInitialize( EngageRoute )
|
||||
|
||||
|
||||
if #AttackTasks == 0 then
|
||||
self:E("No targets found -> Going RTB")
|
||||
self:Return()
|
||||
self:__RTB( 0.5 )
|
||||
else
|
||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskFunction( 1, #AttackTasks, "AI_A2A_GCI.InterceptRoute" )
|
||||
AttackTasks[#AttackTasks+1] = AIGroup:TaskOrbitCircle( 4000, self.EngageMinSpeed )
|
||||
EngageRoute[1].task = AIGroup:TaskCombo( AttackTasks )
|
||||
|
||||
--- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ...
|
||||
AIGroup:SetState( AIGroup, "EngageZone", self )
|
||||
end
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
AIGroup:WayPointExecute( 1, 0 )
|
||||
|
||||
end
|
||||
else
|
||||
self:E("No targets found -> Going RTB")
|
||||
self:Return()
|
||||
self:__RTB( 0.5 )
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_GCI self
|
||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup 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 )
|
||||
self.Accomplished = true
|
||||
self:SetDetectionOff()
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_GCI self
|
||||
-- @param Wrapper.Group#GROUP AIGroup The AIGroup 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 )
|
||||
|
||||
if EventData.IniUnit then
|
||||
self.AttackUnits[EventData.IniUnit] = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #AI_A2A_GCI self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function AI_A2A_GCI:OnEventDead( EventData )
|
||||
self:F( { "EventDead", EventData } )
|
||||
|
||||
if EventData.IniDCSUnit then
|
||||
if self.AttackUnits and self.AttackUnits[EventData.IniUnit] then
|
||||
self:__Destroy( 1, EventData )
|
||||
end
|
||||
end
|
||||
end
|
||||
382
Moose Development/Moose/AI/AI_A2A_Patrol.lua
Normal file
382
Moose Development/Moose/AI/AI_A2A_Patrol.lua
Normal file
@@ -0,0 +1,382 @@
|
||||
--- **AI** -- **Air Patrolling or Staging.**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- AI PATROL classes makes AI Controllables execute an Patrol.
|
||||
--
|
||||
-- There are the following types of PATROL classes defined:
|
||||
--
|
||||
-- * @{#AI_A2A_PATROL}: Perform a PATROL in a zone.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # Demo Missions
|
||||
--
|
||||
-- ### [AI_PATROL Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/PAT%20-%20Patrolling)
|
||||
--
|
||||
-- ### [AI_PATROL Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/PAT%20-%20Patrolling)
|
||||
--
|
||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # YouTube Channel
|
||||
--
|
||||
-- ### [AI_PATROL YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl35HvYZKA6G22WMt7iI3zky)
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Testing and API concept review.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_A2A_Patrol
|
||||
|
||||
|
||||
--- @type AI_A2A_PATROL
|
||||
-- @extends AI.AI_A2A#AI_A2A
|
||||
|
||||
--- # 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 is assigned a @{Group} and this must be done before the AI_A2A_PATROL process can be started using the **Start** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The AI will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits.
|
||||
-- Upon arrival at the 3D point, a new random 3D point will be selected within the patrol zone using the given limits.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- This cycle will continue.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- During the patrol, the AI will detect enemy targets, which are reported through the **Detected** event.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
---- Note that the enemy is not engaged! To model enemy engagement, either tailor the **Detected** event, or
|
||||
-- use derived AI_ classes to model AI offensive or defensive behaviour.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Until a fuel or damage treshold has been reached by the AI, or when the AI is commanded to RTB.
|
||||
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ## 1. AI_A2A_PATROL constructor
|
||||
--
|
||||
-- * @{#AI_A2A_PATROL.New}(): Creates a new AI_A2A_PATROL object.
|
||||
--
|
||||
-- ## 2. AI_A2A_PATROL is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ### 2.1. AI_A2A_PATROL States
|
||||
--
|
||||
-- * **None** ( Group ): The process is not started yet.
|
||||
-- * **Patrolling** ( Group ): The AI is patrolling the Patrol Zone.
|
||||
-- * **Returning** ( Group ): The AI is returning to Base.
|
||||
-- * **Stopped** ( Group ): The process is stopped.
|
||||
-- * **Crashed** ( Group ): The AI has crashed or is dead.
|
||||
--
|
||||
-- ### 2.2. AI_A2A_PATROL Events
|
||||
--
|
||||
-- * **Start** ( Group ): Start the process.
|
||||
-- * **Stop** ( Group ): Stop the process.
|
||||
-- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone.
|
||||
-- * **RTB** ( Group ): Route the AI to the home base.
|
||||
-- * **Detect** ( Group ): The AI is detecting targets.
|
||||
-- * **Detected** ( Group ): The AI has detected new targets.
|
||||
-- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.
|
||||
--
|
||||
-- ## 3. Set or Get the AI controllable
|
||||
--
|
||||
-- * @{#AI_A2A_PATROL.SetControllable}(): Set the AIControllable.
|
||||
-- * @{#AI_A2A_PATROL.GetControllable}(): Get the AIControllable.
|
||||
--
|
||||
-- ## 4. Set the Speed and Altitude boundaries of the AI controllable
|
||||
--
|
||||
-- * @{#AI_A2A_PATROL.SetSpeed}(): Set the patrol speed boundaries of the AI, for the next patrol.
|
||||
-- * @{#AI_A2A_PATROL.SetAltitude}(): Set altitude boundaries of the AI, for the next patrol.
|
||||
--
|
||||
-- ## 5. Manage the detection process of the AI controllable
|
||||
--
|
||||
-- The detection process of the AI controllable can be manipulated.
|
||||
-- Detection requires an amount of CPU power, which has an impact on your mission performance.
|
||||
-- Only put detection on when absolutely necessary, and the frequency of the detection can also be set.
|
||||
--
|
||||
-- * @{#AI_A2A_PATROL.SetDetectionOn}(): Set the detection on. The AI will detect for targets.
|
||||
-- * @{#AI_A2A_PATROL.SetDetectionOff}(): Set the detection off, the AI will not detect for targets. The existing target list will NOT be erased.
|
||||
--
|
||||
-- The detection frequency can be set with @{#AI_A2A_PATROL.SetDetectionInterval}( seconds ), where the amount of seconds specify how much seconds will be waited before the next detection.
|
||||
-- Use the method @{#AI_A2A_PATROL.GetDetectedUnits}() to obtain a list of the @{Unit}s detected by the AI.
|
||||
--
|
||||
-- The detection can be filtered to potential targets in a specific zone.
|
||||
-- Use the method @{#AI_A2A_PATROL.SetDetectionZone}() to set the zone where targets need to be detected.
|
||||
-- Note that when the zone is too far away, or the AI is not heading towards the zone, or the AI is too high, no targets may be detected
|
||||
-- according the weather conditions.
|
||||
--
|
||||
-- ## 6. Manage the "out of fuel" in the AI_A2A_PATROL
|
||||
--
|
||||
-- When the AI is out of fuel, it is required that a new AI is started, before the old AI can return to the home base.
|
||||
-- Therefore, with a parameter and a calculation of the distance to the home base, the fuel treshold is calculated.
|
||||
-- When the fuel treshold is reached, the AI will continue for a given time its patrol task in orbit,
|
||||
-- while a new AI is targetted to the AI_A2A_PATROL.
|
||||
-- Once the time is finished, the old AI will return to the base.
|
||||
-- Use the method @{#AI_A2A_PATROL.ManageFuel}() to have this proces in place.
|
||||
--
|
||||
-- ## 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.
|
||||
-- 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.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_A2A_PATROL
|
||||
AI_A2A_PATROL = {
|
||||
ClassName = "AI_A2A_PATROL",
|
||||
}
|
||||
|
||||
--- Creates a new AI_A2A_PATROL object
|
||||
-- @param #AI_A2A_PATROL self
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
-- @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#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.
|
||||
-- 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 )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, AI_A2A:New( AIGroup ) ) -- #AI_A2A_PATROL
|
||||
|
||||
self.PatrolZone = PatrolZone
|
||||
self.PatrolFloorAltitude = PatrolFloorAltitude
|
||||
self.PatrolCeilingAltitude = PatrolCeilingAltitude
|
||||
self.PatrolMinSpeed = PatrolMinSpeed
|
||||
self.PatrolMaxSpeed = PatrolMaxSpeed
|
||||
|
||||
-- defafult PatrolAltType to "RADIO" if not specified
|
||||
self.PatrolAltType = PatrolAltType or "RADIO"
|
||||
|
||||
self:AddTransition( "Started", "Patrol", "Patrolling" )
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Patrol.
|
||||
-- @function [parent=#AI_A2A_PATROL] Patrol
|
||||
-- @param #AI_A2A_PATROL self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Patrol.
|
||||
-- @function [parent=#AI_A2A_PATROL] __Patrol
|
||||
-- @param #AI_A2A_PATROL self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
self:AddTransition( "Patrolling", "Route", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_PATROL.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @return #boolean Return false to cancel Transition.
|
||||
|
||||
--- 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 #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
|
||||
--- Synchronous Event Trigger for Event Route.
|
||||
-- @function [parent=#AI_A2A_PATROL] Route
|
||||
-- @param #AI_A2A_PATROL self
|
||||
|
||||
--- Asynchronous Event Trigger for Event Route.
|
||||
-- @function [parent=#AI_A2A_PATROL] __Route
|
||||
-- @param #AI_A2A_PATROL self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
self:AddTransition( "*", "Reset", "Patrolling" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_PATROL.
|
||||
|
||||
return self
|
||||
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.
|
||||
-- @return #AI_A2A_PATROL self
|
||||
function AI_A2A_PATROL:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
|
||||
self:F2( { PatrolMinSpeed, PatrolMaxSpeed } )
|
||||
|
||||
self.PatrolMinSpeed = PatrolMinSpeed
|
||||
self.PatrolMaxSpeed = PatrolMaxSpeed
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Sets the floor and ceiling altitude of the patrol.
|
||||
-- @param #AI_A2A_PATROL self
|
||||
-- @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.
|
||||
-- @return #AI_A2A_PATROL self
|
||||
function AI_A2A_PATROL:SetAltitude( PatrolFloorAltitude, PatrolCeilingAltitude )
|
||||
self:F2( { PatrolFloorAltitude, PatrolCeilingAltitude } )
|
||||
|
||||
self.PatrolFloorAltitude = PatrolFloorAltitude
|
||||
self.PatrolCeilingAltitude = PatrolCeilingAltitude
|
||||
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 #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 )
|
||||
self:F2()
|
||||
|
||||
self:ClearTargetDistance()
|
||||
|
||||
self:__Route( 1 )
|
||||
|
||||
self.Controllable:OnReSpawn(
|
||||
function( PatrolGroup )
|
||||
self:E( "ReSpawn" )
|
||||
self:__Reset( 1 )
|
||||
self:__Route( 5 )
|
||||
end
|
||||
)
|
||||
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 )
|
||||
|
||||
local _AI_A2A_Patrol = AIGroup:GetState( AIGroup, "AI_A2A_PATROL" ) -- #AI_A2A_PATROL
|
||||
_AI_A2A_Patrol:Route()
|
||||
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 #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 )
|
||||
|
||||
self:F2()
|
||||
|
||||
-- When RTB, don't allow anymore the routing.
|
||||
if From == "RTB" then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if AIGroup:IsAlive() then
|
||||
|
||||
local PatrolRoute = {}
|
||||
|
||||
--- Calculate the target route point.
|
||||
|
||||
local CurrentCoord = AIGroup:GetCoordinate()
|
||||
|
||||
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
|
||||
ToTargetCoord:SetAlt(math.random( self.PatrolFloorAltitude,self.PatrolCeilingAltitude ) )
|
||||
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
||||
|
||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = ToTargetCoord:RoutePointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
AIGroup:WayPointInitialize( PatrolRoute )
|
||||
|
||||
local Tasks = {}
|
||||
Tasks[#Tasks+1] = AIGroup:TaskFunction( 1, 1, "AI_A2A_PATROL.PatrolRoute" )
|
||||
|
||||
PatrolRoute[1].task = AIGroup:TaskCombo( Tasks )
|
||||
|
||||
--- Do a trick, link the NewPatrolRoute function of the PATROLGROUP object to the AIControllable in a temporary variable ...
|
||||
AIGroup:SetState( AIGroup, "AI_A2A_PATROL", self )
|
||||
|
||||
--- NOW ROUTE THE GROUP!
|
||||
AIGroup:WayPointExecute( 1, 2 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -26,30 +26,15 @@
|
||||
--
|
||||
-- ### [AI_BAI YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3JBO1WDqqpyYRRmIkR2ir2)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-15: Initial class and API.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_Bai
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- Single-Player:**No** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**All** -- **AI Balancing will replace in multi player missions
|
||||
--- **AI** -- **AI Balancing will replace in multi player missions
|
||||
-- non-occupied human slots with AI groups, in order to provide an engaging simulation environment,
|
||||
-- even when there are hardly any players in the mission.**
|
||||
--
|
||||
@@ -20,33 +20,14 @@
|
||||
--
|
||||
-- ### [AI_BALANCER YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl2CJVIrL1TdAumuVS8n64B7)
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-17: There is still a problem with AI being destroyed, but not respawned. Need to check further upon that.
|
||||
--
|
||||
-- 2017-01-08: AI_BALANCER:**InitSpawnInterval( Earliest, Latest )** added.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **SNAFU**: Had a couple of mails with the guys to validate, if the same concept in the GCI/CAP script could be reworked within MOOSE. None of the script code has been used however within the new AI_BALANCER moose class.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * FlightControl: Framework Design & Programming and Documentation.
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_Balancer
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **AI** - **Execute Combat Air Patrol (CAP).**
|
||||
--- **AI** -- **Execute Combat Air Patrol (CAP).**
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -27,33 +27,18 @@
|
||||
-- ### [AI_CAP YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1YCyPxJgoZn-CfhwyeW65L)
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-15: Initial class and API.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
-- * **[Whisper](http://forums.eagle.ru/member.php?u=3829): Testing.
|
||||
-- * **[Delta99](https://forums.eagle.ru/member.php?u=125166): Testing.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_Cap
|
||||
|
||||
@@ -417,7 +402,7 @@ function AI_CAP_ZONE:onafterDetected( Controllable, From, Event, To )
|
||||
end
|
||||
|
||||
if Engage == true then
|
||||
self:E( 'Detected -> Engaging' )
|
||||
self:F( 'Detected -> Engaging' )
|
||||
self:__Engage( 1 )
|
||||
end
|
||||
end
|
||||
@@ -500,13 +485,13 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
||||
if DetectedUnit:IsAlive() and DetectedUnit:IsAir() then
|
||||
if self.EngageZone then
|
||||
if DetectedUnit:IsInZone( self.EngageZone ) then
|
||||
self:E( {"Within Zone and Engaging ", DetectedUnit } )
|
||||
self:F( {"Within Zone and Engaging ", DetectedUnit } )
|
||||
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit )
|
||||
end
|
||||
else
|
||||
if self.EngageRange then
|
||||
if DetectedUnit:GetPointVec3():Get2DDistance(Controllable:GetPointVec3() ) <= self.EngageRange then
|
||||
self:E( {"Within Range and Engaging", DetectedUnit } )
|
||||
self:F( {"Within Range and Engaging", DetectedUnit } )
|
||||
AttackTasks[#AttackTasks+1] = Controllable:TaskAttackUnit( DetectedUnit )
|
||||
end
|
||||
else
|
||||
@@ -523,7 +508,7 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
|
||||
|
||||
|
||||
if #AttackTasks == 0 then
|
||||
self:E("No targets found -> Going back to Patrolling")
|
||||
self:F("No targets found -> Going back to Patrolling")
|
||||
self:__Abort( 1 )
|
||||
self:__Route( 1 )
|
||||
self:SetDetectionActivated()
|
||||
|
||||
@@ -26,19 +26,18 @@
|
||||
--
|
||||
-- ### [AI_CAS YouTube Channel](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3JBO1WDqqpyYRRmIkR2ir2)
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Quax](https://forums.eagle.ru/member.php?u=90530)**: Concept, Advice & Testing.
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Concept, Advice & Testing.
|
||||
-- * **[Gunterlund](http://forums.eagle.ru:8080/member.php?u=75036)**: Test case revision.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_Cas
|
||||
|
||||
@@ -107,11 +106,11 @@
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- # 1. AI_CAS_ZONE constructor
|
||||
-- ## AI_CAS_ZONE constructor
|
||||
--
|
||||
-- * @{#AI_CAS_ZONE.New}(): Creates a new AI_CAS_ZONE object.
|
||||
--
|
||||
-- ## 2. AI_CAS_ZONE is a FSM
|
||||
-- ## AI_CAS_ZONE is a FSM
|
||||
--
|
||||
-- 
|
||||
--
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **AI** -- (R2.1) Build large **formations** of AI @{Group}s flying together.
|
||||
--- **AI** -- Build large **formations** of AI @{Group}s flying together.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -46,13 +46,11 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_Formation
|
||||
|
||||
|
||||
@@ -28,47 +28,17 @@
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **OPEN ISSUES**
|
||||
--
|
||||
-- 2017-01-17: When Spawned AI is located at an airbase, it will be routed first back to the airbase after take-off.
|
||||
--
|
||||
-- 2016-01-17:
|
||||
-- -- Fixed problem with AI returning to base too early and unexpected.
|
||||
-- -- ReSpawning of AI will reset the AI_PATROL and derived classes.
|
||||
-- -- Checked the correct workings of SCHEDULER, and it DOES work correctly.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-01-17: Rename of class: **AI\_PATROL\_ZONE** is the new name for the old _AI\_PATROLZONE_.
|
||||
--
|
||||
-- 2017-01-15: Complete revision. AI_PATROL_ZONE is the base class for other AI_PATROL like classes.
|
||||
--
|
||||
-- 2016-09-01: Initial class and API.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[Dutch_Baron](https://forums.eagle.ru/member.php?u=112075)**: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
-- * **[Pikey](https://forums.eagle.ru/member.php?u=62835)**: Testing and API concept review.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming.
|
||||
-- ====
|
||||
--
|
||||
-- @module AI_Patrol
|
||||
|
||||
|
||||
--- AI_PATROL_ZONE class
|
||||
-- @type AI_PATROL_ZONE
|
||||
-- @field Wrapper.Controllable#CONTROLLABLE AIControllable The @{Controllable} patrolling.
|
||||
|
||||
@@ -70,19 +70,20 @@ do -- ACT_ACCOUNT
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM_PROCESS:New() ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
self:AddTransition( "Assigned", "Start", "Waiting")
|
||||
self:AddTransition( "*", "Wait", "Waiting")
|
||||
self:AddTransition( "*", "Report", "Report")
|
||||
self:AddTransition( "*", "Event", "Account")
|
||||
self:AddTransition( "Account", "More", "Wait")
|
||||
self:AddTransition( "Account", "NoMore", "Accounted")
|
||||
self:AddTransition( "*", "Fail", "Failed")
|
||||
self:AddTransition( "Assigned", "Start", "Waiting" )
|
||||
self:AddTransition( "*", "Wait", "Waiting" )
|
||||
self:AddTransition( "*", "Report", "Report" )
|
||||
self:AddTransition( "*", "Event", "Account" )
|
||||
self:AddTransition( "Account", "Player", "AccountForPlayer" )
|
||||
self:AddTransition( "Account", "Other", "AccountForOther" )
|
||||
self:AddTransition( { "Account", "AccountForPlayer", "AccountForOther" }, "More", "Wait" )
|
||||
self:AddTransition( { "Account", "AccountForPlayer", "AccountForOther" }, "NoMore", "Accounted" )
|
||||
self:AddTransition( "*", "Fail", "Failed" )
|
||||
|
||||
self:AddEndState( "Accounted" )
|
||||
self:AddEndState( "Failed" )
|
||||
|
||||
self:SetStartState( "Assigned" )
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -97,6 +98,8 @@ do -- ACT_ACCOUNT
|
||||
function ACT_ACCOUNT:onafterStart( ProcessUnit, From, Event, To )
|
||||
|
||||
self:HandleEvent( EVENTS.Dead, self.onfuncEventDead )
|
||||
self:HandleEvent( EVENTS.Crash, self.onfuncEventCrash )
|
||||
self:HandleEvent( EVENTS.Hit )
|
||||
|
||||
self:__Wait( 1 )
|
||||
end
|
||||
@@ -199,44 +202,88 @@ do -- ACT_ACCOUNT_DEADS
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param Wrapper.Client#CLIENT ProcessClient
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT_DEADS:onenterAccount( ProcessUnit, Task, From, Event, To, EventData )
|
||||
self:T( { ProcessUnit, EventData, From, Event, To } )
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function ACT_ACCOUNT_DEADS:onafterEvent( ProcessClient, Task, From, Event, To, EventData )
|
||||
self:T( { ProcessClient:GetName(), Task:GetName(), From, Event, To, EventData } )
|
||||
|
||||
self:T({self.Controllable})
|
||||
|
||||
self.TargetSetUnit:Flush()
|
||||
|
||||
self:T( { "Before sending Message", EventData.IniUnitName, self.TargetSetUnit:FindUnit( EventData.IniUnitName ) } )
|
||||
if self.TargetSetUnit:FindUnit( EventData.IniUnitName ) then
|
||||
self:T( "Sending Message" )
|
||||
local TaskGroup = ProcessUnit:GetGroup()
|
||||
self.TargetSetUnit:Remove( EventData.IniUnitName )
|
||||
self:Message( "You hit a target. Your group with assigned " .. self.TaskName .. " task has " .. self.TargetSetUnit:Count() .. " targets ( " .. self.TargetSetUnit:GetUnitTypesText() .. " ) left to be destroyed." )
|
||||
local PlayerName = ProcessClient:GetPlayerName()
|
||||
local PlayerHit = self.PlayerHits and self.PlayerHits[EventData.IniUnitName]
|
||||
if PlayerHit == PlayerName then
|
||||
self:Player( EventData )
|
||||
else
|
||||
self:Other( EventData )
|
||||
end
|
||||
end
|
||||
self:T( { "After sending Message" } )
|
||||
end
|
||||
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param Wrapper.Client#CLIENT ProcessClient
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function ACT_ACCOUNT_DEADS:onafterEvent( ProcessUnit, Task, From, Event, To )
|
||||
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function ACT_ACCOUNT_DEADS:onenterAccountForPlayer( ProcessClient, Task, From, Event, To, EventData )
|
||||
self:T( { ProcessClient:GetName(), Task:GetName(), From, Event, To, EventData } )
|
||||
|
||||
local TaskGroup = ProcessClient:GetGroup()
|
||||
|
||||
self.TargetSetUnit:Remove( EventData.IniUnitName )
|
||||
self:Message( "You have destroyed a target. Your group assigned with task " .. self.TaskName .. " has " .. self.TargetSetUnit:Count() .. " targets ( " .. self.TargetSetUnit:GetUnitTypesText() .. " ) left to be destroyed." )
|
||||
|
||||
local PlayerName = ProcessClient:GetPlayerName()
|
||||
Task:AddProgress( PlayerName, "Destroyed " .. EventData.IniTypeName, timer.getTime(), 1 )
|
||||
|
||||
if self.TargetSetUnit:Count() > 0 then
|
||||
self:__More( 1 )
|
||||
else
|
||||
self:__NoMore( 1 )
|
||||
end
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Wrapper.Client#CLIENT ProcessClient
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function ACT_ACCOUNT_DEADS:onenterAccountForOther( ProcessClient, Task, From, Event, To, EventData )
|
||||
self:T( { ProcessClient:GetName(), Task:GetName(), From, Event, To, EventData } )
|
||||
|
||||
local TaskGroup = ProcessClient:GetGroup()
|
||||
self.TargetSetUnit:Remove( EventData.IniUnitName )
|
||||
self:Message( "One of the task targets has been destroyed. Your group assigned with task " .. self.TaskName .. " has " .. self.TargetSetUnit:Count() .. " targets ( " .. self.TargetSetUnit:GetUnitTypesText() .. " ) left to be destroyed." )
|
||||
|
||||
if self.TargetSetUnit:Count() > 0 then
|
||||
self:__More( 1 )
|
||||
else
|
||||
self:__NoMore( 1 )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- DCS Events
|
||||
|
||||
--- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function ACT_ACCOUNT_DEADS:OnEventHit( EventData )
|
||||
self:T( { "EventDead", EventData } )
|
||||
|
||||
if EventData.IniPlayerName and EventData.TgtDCSUnitName then
|
||||
self.PlayerHits = self.PlayerHits or {}
|
||||
self.PlayerHits[EventData.TgtDCSUnitName] = EventData.IniPlayerName
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #ACT_ACCOUNT_DEADS self
|
||||
-- @param Event#EVENTDATA EventData
|
||||
function ACT_ACCOUNT_DEADS:onfuncEventDead( EventData )
|
||||
@@ -247,4 +294,16 @@ do -- ACT_ACCOUNT_DEADS
|
||||
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
|
||||
|
||||
@@ -154,29 +154,54 @@ do -- ACT_ROUTE
|
||||
--- Get the routing text to be displayed.
|
||||
-- The route mode determines the text displayed.
|
||||
-- @param #ACT_ROUTE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable
|
||||
-- @return #string
|
||||
function ACT_ROUTE:GetRouteText( FromCoordinate )
|
||||
|
||||
function ACT_ROUTE:GetRouteText( Controllable )
|
||||
|
||||
self:E()
|
||||
|
||||
local RouteText = ""
|
||||
|
||||
if self.Coordinate and self.RouteMode == "B" then
|
||||
RouteText = "Route to " .. FromCoordinate:GetBRText( self.Coordinate ) .. " km."
|
||||
local Coordinate = nil -- Core.Point#COORDINATE
|
||||
|
||||
if self.Coordinate then
|
||||
Coordinate = self.Coordinate
|
||||
end
|
||||
|
||||
if self.Coordinate and self.RouteMode == "C" then
|
||||
RouteText = "Route to " .. self.Coordinate:ToString()
|
||||
if self.Zone then
|
||||
Coordinate = self.Zone:GetPointVec3( self.Altitude )
|
||||
Coordinate:SetHeading( self.Heading )
|
||||
end
|
||||
|
||||
if self.Zone and self.RouteMode == "B" then
|
||||
local Coordinate = self.Zone:GetCoordinate()
|
||||
RouteText = "Route to zone bearing " .. FromCoordinate:GetBRText( Coordinate ) .. " km."
|
||||
|
||||
local CC = self:GetTask():GetMission():GetCommandCenter()
|
||||
if CC then
|
||||
if CC:IsModeWWII() then
|
||||
-- Find closest reference point to the target.
|
||||
local ShortestDistance = 0
|
||||
local ShortestReferencePoint = nil
|
||||
local ShortestReferenceName = ""
|
||||
self:E( { CC.ReferencePoints } )
|
||||
for ZoneName, Zone in pairs( CC.ReferencePoints ) do
|
||||
self:E( { ZoneName = ZoneName } )
|
||||
local Zone = Zone -- Core.Zone#ZONE
|
||||
local ZoneCoord = Zone:GetCoordinate()
|
||||
local ZoneDistance = ZoneCoord:Get2DDistance( self.Coordinate )
|
||||
self:E( { ShortestDistance, ShortestReferenceName } )
|
||||
if ShortestDistance == 0 or ZoneDistance < ShortestDistance then
|
||||
ShortestDistance = ZoneDistance
|
||||
ShortestReferencePoint = ZoneCoord
|
||||
ShortestReferenceName = CC.ReferenceNames[ZoneName]
|
||||
end
|
||||
end
|
||||
if ShortestReferencePoint then
|
||||
RouteText = Coordinate:ToStringFromRP( ShortestReferencePoint, ShortestReferenceName, Controllable )
|
||||
end
|
||||
else
|
||||
RouteText = Coordinate:ToString( Controllable )
|
||||
end
|
||||
end
|
||||
|
||||
if self.Zone and self.RouteMode == "C" then
|
||||
local Coordinate = self.Zone:GetCoordinate()
|
||||
RouteText = "Route to zone at " .. Coordinate:ToString()
|
||||
end
|
||||
|
||||
return RouteText
|
||||
end
|
||||
|
||||
@@ -353,8 +378,7 @@ do -- ACT_ROUTE_POINT
|
||||
-- @param #string To
|
||||
function ACT_ROUTE_POINT:onafterReport( ProcessUnit, From, Event, To )
|
||||
|
||||
local TaskUnitCoordinate = ProcessUnit:GetCoordinate()
|
||||
local RouteText = self:GetRouteText( TaskUnitCoordinate )
|
||||
local RouteText = self:GetRouteText( ProcessUnit )
|
||||
self:Message( RouteText )
|
||||
end
|
||||
|
||||
@@ -403,8 +427,12 @@ do -- ACT_ROUTE_ZONE
|
||||
--- Set Zone
|
||||
-- @param #ACT_ROUTE_ZONE self
|
||||
-- @param Core.Zone#ZONE_BASE Zone The Zone object where to route to.
|
||||
function ACT_ROUTE_ZONE:SetZone( Zone )
|
||||
-- @param #number Altitude
|
||||
-- @param #number Heading
|
||||
function ACT_ROUTE_ZONE:SetZone( Zone, Altitude, Heading ) -- R2.2 Added altitude and heading
|
||||
self.Zone = Zone
|
||||
self.Altitude = Altitude
|
||||
self.Heading = Heading
|
||||
end
|
||||
|
||||
--- Get Zone
|
||||
@@ -437,12 +465,9 @@ do -- ACT_ROUTE_ZONE
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE_ZONE:onafterReport( ProcessUnit, From, Event, To )
|
||||
self:E( { ProcessUnit = ProcessUnit } )
|
||||
|
||||
local ZoneVec2 = self.Zone:GetVec2()
|
||||
local ZoneCoordinate = COORDINATE:New( ZoneVec2.x, ZoneVec2.y )
|
||||
local TaskUnitVec2 = ProcessUnit:GetVec2()
|
||||
local TaskUnitCoordinate = COORDINATE:New( TaskUnitVec2.x, TaskUnitVec2.y )
|
||||
local RouteText = self:GetRouteText( TaskUnitCoordinate )
|
||||
local RouteText = self:GetRouteText( ProcessUnit )
|
||||
self:Message( RouteText )
|
||||
end
|
||||
|
||||
|
||||
@@ -1,36 +1,13 @@
|
||||
--- **Core** - BASE forms **the basis of the MOOSE framework**. Each class within the MOOSE framework derives from BASE.
|
||||
--- **Core** -- BASE forms **the basis of the MOOSE framework**. Each class within the MOOSE framework derives from BASE.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- The @{#BASE} class is the core root class from where every other class in moose is derived.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction**( Params ) replaces CLASS:_OldFunction_( Params )
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction( Params )** added
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * None.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming
|
||||
-- ====
|
||||
--
|
||||
-- @module Base
|
||||
|
||||
@@ -224,6 +201,10 @@ BASE = {
|
||||
_ = {},
|
||||
}
|
||||
|
||||
|
||||
--- @field #BASE.__
|
||||
BASE.__ = {}
|
||||
|
||||
--- The Formation Class
|
||||
-- @type FORMATION
|
||||
-- @field Cone A cone formation.
|
||||
@@ -247,47 +228,19 @@ FORMATION = {
|
||||
-- @return #BASE
|
||||
function BASE:New()
|
||||
local self = routines.utils.deepCopy( self ) -- Create a new self instance
|
||||
local MetaTable = {}
|
||||
setmetatable( self, MetaTable )
|
||||
self.__index = self
|
||||
|
||||
_ClassID = _ClassID + 1
|
||||
self.ClassID = _ClassID
|
||||
|
||||
|
||||
-- This is for "private" methods...
|
||||
-- When a __ is passed to a method as "self", the __index will search for the method on the public method list too!
|
||||
-- if rawget( self, "__" ) then
|
||||
--setmetatable( self, { __index = self.__ } )
|
||||
-- end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function BASE:_Destructor()
|
||||
--self:E("_Destructor")
|
||||
|
||||
--self:EventRemoveAll()
|
||||
end
|
||||
|
||||
|
||||
-- THIS IS WHY WE NEED LUA 5.2 ...
|
||||
function BASE:_SetDestructor()
|
||||
|
||||
-- TODO: Okay, this is really technical...
|
||||
-- When you set a proxy to a table to catch __gc, weak tables don't behave like weak...
|
||||
-- Therefore, I am parking this logic until I've properly discussed all this with the community.
|
||||
|
||||
local proxy = newproxy(true)
|
||||
local proxyMeta = getmetatable(proxy)
|
||||
|
||||
proxyMeta.__gc = function ()
|
||||
env.info("In __gc for " .. self:GetClassNameAndID() )
|
||||
if self._Destructor then
|
||||
self:_Destructor()
|
||||
end
|
||||
end
|
||||
|
||||
-- keep the userdata from newproxy reachable until the object
|
||||
-- table is about to be garbage-collected - then the __gc hook
|
||||
-- will be invoked and the destructor called
|
||||
rawset( self, '__proxy', proxy )
|
||||
|
||||
end
|
||||
|
||||
--- This is the worker method to inherit from a parent class.
|
||||
-- @param #BASE self
|
||||
-- @param Child is the Child class that inherits.
|
||||
@@ -295,15 +248,20 @@ end
|
||||
-- @return #BASE Child
|
||||
function BASE:Inherit( Child, Parent )
|
||||
local Child = routines.utils.deepCopy( Child )
|
||||
--local Parent = routines.utils.deepCopy( Parent )
|
||||
--local Parent = Parent
|
||||
|
||||
if Child ~= nil then
|
||||
setmetatable( Child, Parent )
|
||||
Child.__index = Child
|
||||
|
||||
|
||||
-- This is for "private" methods...
|
||||
-- When a __ is passed to a method as "self", the __index will search for the method on the public method list of the same object too!
|
||||
if rawget( Child, "__" ) then
|
||||
setmetatable( Child, { __index = Child.__ } )
|
||||
setmetatable( Child.__, { __index = Parent } )
|
||||
else
|
||||
setmetatable( Child, { __index = Parent } )
|
||||
end
|
||||
|
||||
--Child:_SetDestructor()
|
||||
end
|
||||
--self:T( 'Inherited from ' .. Parent.ClassName )
|
||||
return Child
|
||||
end
|
||||
|
||||
@@ -317,8 +275,12 @@ end
|
||||
-- @param #BASE Child is the Child class from which the Parent class needs to be retrieved.
|
||||
-- @return #BASE
|
||||
function BASE:GetParent( Child )
|
||||
local Parent = getmetatable( Child )
|
||||
-- env.info('Inherited class of ' .. Child.ClassName .. ' is ' .. Parent.ClassName )
|
||||
local Parent
|
||||
if rawget( Child, "__" ) then
|
||||
Parent = getmetatable( Child.__ ).__index
|
||||
else
|
||||
Parent = getmetatable( Child ).__index
|
||||
end
|
||||
return Parent
|
||||
end
|
||||
|
||||
@@ -402,7 +364,7 @@ do -- Event Handling
|
||||
-- @return #BASE
|
||||
function BASE:UnHandleEvent( Event )
|
||||
|
||||
self:EventDispatcher():Remove( self, Event )
|
||||
self:EventDispatcher():RemoveEvent( self, Event )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -640,7 +602,6 @@ end
|
||||
-- @param #BASE self
|
||||
-- @param Object The object that holds the Value set by the Key.
|
||||
-- @param Key The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type!
|
||||
-- @param Value The value to is stored in the Object.
|
||||
-- @return The Value retrieved.
|
||||
function BASE:GetState( Object, Key )
|
||||
|
||||
@@ -919,3 +880,35 @@ end
|
||||
|
||||
|
||||
|
||||
--- old stuff
|
||||
|
||||
--function BASE:_Destructor()
|
||||
-- --self:E("_Destructor")
|
||||
--
|
||||
-- --self:EventRemoveAll()
|
||||
--end
|
||||
|
||||
|
||||
-- THIS IS WHY WE NEED LUA 5.2 ...
|
||||
--function BASE:_SetDestructor()
|
||||
--
|
||||
-- -- TODO: Okay, this is really technical...
|
||||
-- -- When you set a proxy to a table to catch __gc, weak tables don't behave like weak...
|
||||
-- -- Therefore, I am parking this logic until I've properly discussed all this with the community.
|
||||
--
|
||||
-- local proxy = newproxy(true)
|
||||
-- local proxyMeta = getmetatable(proxy)
|
||||
--
|
||||
-- proxyMeta.__gc = function ()
|
||||
-- env.info("In __gc for " .. self:GetClassNameAndID() )
|
||||
-- if self._Destructor then
|
||||
-- self:_Destructor()
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- -- keep the userdata from newproxy reachable until the object
|
||||
-- -- table is about to be garbage-collected - then the __gc hook
|
||||
-- -- will be invoked and the destructor called
|
||||
-- rawset( self, '__proxy', proxy )
|
||||
--
|
||||
--end
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **(R2.1) Core** -- Management of CARGO logistics, that can be transported from and to transportation carriers.
|
||||
--- **Core** -- Management of CARGO logistics, that can be transported from and to transportation carriers.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -9,13 +9,15 @@
|
||||
-- * CARGO_UNIT, represented by a @{Unit} in a singleton @{Group}: Cargo can be represented by a Unit in a Group. a CARGO_UNIT is representable...
|
||||
-- * CARGO_GROUP, represented by a @{Group}. A CARGO_GROUP is reportable...
|
||||
--
|
||||
-- This module is still under construction, but is described above works already, and will keep working ...
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # Demo Missions
|
||||
--
|
||||
-- ### [CARGO Demo Missions source code]()
|
||||
-- ### [CARGO Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/CGO%20-%20Cargo)
|
||||
--
|
||||
-- ### [CARGO Demo Missions, only for beta testers]()
|
||||
-- ### [CARGO Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/CGO%20-%20Cargo)
|
||||
--
|
||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||
--
|
||||
@@ -23,11 +25,14 @@
|
||||
--
|
||||
-- # YouTube Channel
|
||||
--
|
||||
-- ### [SPAWNSTATIC YouTube Channel]()
|
||||
-- ### [CARGO YouTube Channel](https://www.youtube.com/watch?v=tM00lTlkpYs&list=PL7ZUrU4zZUl2zUTuKrLW5RsO9zLMqUtbf)
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- This module is still under construction, but is described above works already, and will keep working ...
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Cargo
|
||||
|
||||
@@ -159,7 +164,7 @@ do -- CARGO
|
||||
-- @field #number Weight A number defining the weight of the cargo. The weight is expressed in kg.
|
||||
-- @field #number NearRadius (optional) A number defining the radius in meters when the cargo is near to a Carrier, so that it can be loaded.
|
||||
-- @field Wrapper.Controllable#CONTROLLABLE CargoObject The alive DCS object representing the cargo. This value can be nil, meaning, that the cargo is not represented anywhere...
|
||||
-- @field Wrapper.Controllable#CONTROLLABLE CargoCarrier The alive DCS object carrying the cargo. This value can be nil, meaning, that the cargo is not contained anywhere...
|
||||
-- @field Wrapper.Client#CLIENT CargoCarrier The alive DCS object carrying the cargo. This value can be nil, meaning, that the cargo is not contained anywhere...
|
||||
-- @field #boolean Slingloadable This flag defines if the cargo can be slingloaded.
|
||||
-- @field #boolean Moveable This flag defines if the cargo is moveable.
|
||||
-- @field #boolean Representable This flag defines if the cargo can be represented by a DCS Unit.
|
||||
@@ -205,8 +210,7 @@ do -- CARGO
|
||||
-- The state transition method needs to start with the name **OnEnter + the name of the state**.
|
||||
-- These state transition methods need to provide a return value, which is specified at the function description.
|
||||
--
|
||||
-- @field #CARGO CARGO
|
||||
--
|
||||
-- @field #CARGO
|
||||
CARGO = {
|
||||
ClassName = "CARGO",
|
||||
Type = nil,
|
||||
@@ -246,6 +250,7 @@ function CARGO:New( Type, Name, Weight ) --R2.1
|
||||
self:AddTransition( "UnBoarding", "UnBoarding", "UnBoarding" )
|
||||
self:AddTransition( "UnBoarding", "UnLoad", "UnLoaded" )
|
||||
self:AddTransition( "Loaded", "UnLoad", "UnLoaded" )
|
||||
self:AddTransition( "*", "Damaged", "Damaged" )
|
||||
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
||||
self:AddTransition( "*", "Respawn", "UnLoaded" )
|
||||
|
||||
@@ -259,17 +264,26 @@ function CARGO:New( Type, Name, Weight ) --R2.1
|
||||
self.Slingloadable = false
|
||||
self.Moveable = false
|
||||
self.Containable = false
|
||||
|
||||
self:SetDeployed( false )
|
||||
|
||||
self.CargoScheduler = SCHEDULER:New()
|
||||
|
||||
CARGOS[self.Name] = self
|
||||
|
||||
self:SetEventPriority( 5 )
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Destroy the cargo.
|
||||
-- @param #CARGO self
|
||||
function CARGO:Destroy()
|
||||
if self.CargoObject then
|
||||
self.CargoObject:Destroy()
|
||||
end
|
||||
self:Destroyed()
|
||||
end
|
||||
|
||||
--- Get the name of the Cargo.
|
||||
-- @param #CARGO self
|
||||
-- @return #string The name of the Cargo.
|
||||
@@ -302,6 +316,13 @@ function CARGO:GetCoordinate()
|
||||
return self.CargoObject:GetCoordinate()
|
||||
end
|
||||
|
||||
--- Check if cargo is destroyed.
|
||||
-- @param #CARGO self
|
||||
-- @return #boolean true if destroyed
|
||||
function CARGO:IsDestroyed()
|
||||
return self:Is( "Destroyed" )
|
||||
end
|
||||
|
||||
|
||||
--- Check if cargo is loaded.
|
||||
-- @param #CARGO self
|
||||
@@ -329,6 +350,19 @@ function CARGO:IsAlive()
|
||||
end
|
||||
end
|
||||
|
||||
--- Set the cargo as deployed
|
||||
-- @param #CARGO self
|
||||
function CARGO:SetDeployed( Deployed )
|
||||
self.Deployed = Deployed
|
||||
end
|
||||
|
||||
--- Is the cargo deployed
|
||||
-- @param #CARGO self
|
||||
-- @return #boolean
|
||||
function CARGO:IsDeployed()
|
||||
return self.Deployed
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -340,6 +374,85 @@ function CARGO:Spawn( PointVec2 )
|
||||
|
||||
end
|
||||
|
||||
--- Signal a flare at the position of the CARGO.
|
||||
-- @param #CARGO self
|
||||
-- @param Utilities.Utils#FLARECOLOR FlareColor
|
||||
function CARGO:Flare( FlareColor )
|
||||
if self:IsUnLoaded() then
|
||||
trigger.action.signalFlare( self.CargoObject:GetVec3(), FlareColor , 0 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Signal a white flare at the position of the CARGO.
|
||||
-- @param #CARGO self
|
||||
function CARGO:FlareWhite()
|
||||
self:Flare( trigger.flareColor.White )
|
||||
end
|
||||
|
||||
--- Signal a yellow flare at the position of the CARGO.
|
||||
-- @param #CARGO self
|
||||
function CARGO:FlareYellow()
|
||||
self:Flare( trigger.flareColor.Yellow )
|
||||
end
|
||||
|
||||
--- Signal a green flare at the position of the CARGO.
|
||||
-- @param #CARGO self
|
||||
function CARGO:FlareGreen()
|
||||
self:Flare( trigger.flareColor.Green )
|
||||
end
|
||||
|
||||
--- Signal a red flare at the position of the CARGO.
|
||||
-- @param #CARGO self
|
||||
function CARGO:FlareRed()
|
||||
self:Flare( trigger.flareColor.Red )
|
||||
end
|
||||
|
||||
--- Smoke the CARGO.
|
||||
-- @param #CARGO self
|
||||
function CARGO:Smoke( SmokeColor, Range )
|
||||
self:F2()
|
||||
if self:IsUnLoaded() then
|
||||
if Range then
|
||||
trigger.action.smoke( self.CargoObject:GetRandomVec3( Range ), SmokeColor )
|
||||
else
|
||||
trigger.action.smoke( self.CargoObject:GetVec3(), SmokeColor )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Smoke the CARGO Green.
|
||||
-- @param #CARGO self
|
||||
function CARGO:SmokeGreen()
|
||||
self:Smoke( trigger.smokeColor.Green, Range )
|
||||
end
|
||||
|
||||
--- Smoke the CARGO Red.
|
||||
-- @param #CARGO self
|
||||
function CARGO:SmokeRed()
|
||||
self:Smoke( trigger.smokeColor.Red, Range )
|
||||
end
|
||||
|
||||
--- Smoke the CARGO White.
|
||||
-- @param #CARGO self
|
||||
function CARGO:SmokeWhite()
|
||||
self:Smoke( trigger.smokeColor.White, Range )
|
||||
end
|
||||
|
||||
--- Smoke the CARGO Orange.
|
||||
-- @param #CARGO self
|
||||
function CARGO:SmokeOrange()
|
||||
self:Smoke( trigger.smokeColor.Orange, Range )
|
||||
end
|
||||
|
||||
--- Smoke the CARGO Blue.
|
||||
-- @param #CARGO self
|
||||
function CARGO:SmokeBlue()
|
||||
self:Smoke( trigger.smokeColor.Blue, Range )
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Check if Cargo is the given @{Zone}.
|
||||
@@ -352,7 +465,12 @@ function CARGO:IsInZone( Zone )
|
||||
if self:IsLoaded() then
|
||||
return Zone:IsPointVec2InZone( self.CargoCarrier:GetPointVec2() )
|
||||
else
|
||||
return Zone:IsPointVec2InZone( self.CargoObject:GetPointVec2() )
|
||||
self:F( { Size = self.CargoObject:GetSize(), Units = self.CargoObject:GetUnits() } )
|
||||
if self.CargoObject:GetSize() ~= 0 then
|
||||
return Zone:IsPointVec2InZone( self.CargoObject:GetPointVec2() )
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
@@ -475,8 +593,12 @@ end -- CARGO_REPRESENTABLE
|
||||
local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight ) ) -- #CARGO_REPORTABLE
|
||||
self:F( { Type, Name, Weight, ReportRadius } )
|
||||
|
||||
self.CargoSet = SET_CARGO:New() -- Core.Set#SET_CARGO
|
||||
|
||||
self.ReportRadius = ReportRadius or 1000
|
||||
self.CargoObject = CargoObject
|
||||
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -506,7 +628,7 @@ end -- CARGO_REPRESENTABLE
|
||||
end
|
||||
|
||||
--- Send a CC message to a GROUP.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param #CARGO_REPORTABLE self
|
||||
-- @param #string Message
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
|
||||
@@ -519,12 +641,38 @@ end -- CARGO_REPRESENTABLE
|
||||
end
|
||||
|
||||
--- Get the range till cargo will board.
|
||||
-- @param #CARGO self
|
||||
-- @param #CARGO_REPORTABLE self
|
||||
-- @return #number The range till cargo will board.
|
||||
function CARGO_REPORTABLE:GetBoardingRange()
|
||||
return self.ReportRadius
|
||||
end
|
||||
|
||||
--- Respawn the cargo.
|
||||
-- @param #CARGO_REPORTABLE self
|
||||
function CARGO_REPORTABLE:Respawn()
|
||||
|
||||
self:F({"Respawning"})
|
||||
|
||||
for CargoID, CargoData in pairs( self.CargoSet:GetSet() ) do
|
||||
local Cargo = CargoData -- #CARGO
|
||||
Cargo:Destroy()
|
||||
Cargo:SetStartState( "UnLoaded" )
|
||||
end
|
||||
|
||||
local CargoObject = self.CargoObject -- Wrapper.Group#GROUP
|
||||
CargoObject:Destroy()
|
||||
local Template = CargoObject:GetTemplate()
|
||||
CargoObject:Respawn( Template )
|
||||
|
||||
self:SetDeployed( false )
|
||||
|
||||
local WeightGroup = 0
|
||||
|
||||
self:SetStartState( "UnLoaded" )
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
do -- CARGO_UNIT
|
||||
@@ -564,16 +712,18 @@ function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius )
|
||||
|
||||
self:T( self.ClassName )
|
||||
|
||||
self:HandleEvent( EVENTS.Dead,
|
||||
--- @param #CARGO Cargo
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function( Cargo, EventData )
|
||||
if Cargo:GetObjectName() == EventData.IniUnit:GetName() then
|
||||
self:E( { "Cargo destroyed", Cargo } )
|
||||
Cargo:Destroyed()
|
||||
end
|
||||
end
|
||||
)
|
||||
-- self:HandleEvent( EVENTS.Dead,
|
||||
-- --- @param #CARGO Cargo
|
||||
-- -- @param Core.Event#EVENTDATA EventData
|
||||
-- function( Cargo, EventData )
|
||||
-- if Cargo:GetObjectName() == EventData.IniUnit:GetName() then
|
||||
-- self:E( { "Cargo destroyed", Cargo } )
|
||||
-- Cargo:Destroyed()
|
||||
-- end
|
||||
-- end
|
||||
-- )
|
||||
|
||||
self:SetEventPriority( 5 )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -584,6 +734,7 @@ end
|
||||
function CARGO_UNIT:Destroy()
|
||||
|
||||
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
||||
self:F( { CargoName = self:GetName() } )
|
||||
_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
||||
|
||||
return self
|
||||
@@ -911,9 +1062,9 @@ function CARGO_GROUP:New( CargoGroup, Type, Name, ReportRadius )
|
||||
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( CargoGroup, Type, Name, 0, ReportRadius ) ) -- #CARGO_GROUP
|
||||
self:F( { Type, Name, ReportRadius } )
|
||||
|
||||
self.CargoSet = SET_CARGO:New()
|
||||
|
||||
self.CargoObject = CargoGroup
|
||||
self:SetDeployed( false )
|
||||
self.CargoGroup = CargoGroup
|
||||
|
||||
local WeightGroup = 0
|
||||
|
||||
@@ -932,9 +1083,47 @@ function CARGO_GROUP:New( CargoGroup, Type, Name, ReportRadius )
|
||||
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
|
||||
_EVENTDISPATCHER:CreateEventNewCargo( self )
|
||||
|
||||
self:HandleEvent( EVENTS.Dead, self.OnEventCargoDead )
|
||||
self:HandleEvent( EVENTS.Crash, self.OnEventCargoDead )
|
||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self.OnEventCargoDead )
|
||||
|
||||
self:SetEventPriority( 4 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #CARGO_GROUP self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
|
||||
local Destroyed = false
|
||||
|
||||
if self:IsDestroyed() or self:IsUnLoaded() then
|
||||
Destroyed = true
|
||||
for CargoID, CargoData in pairs( self.CargoSet:GetSet() ) do
|
||||
local Cargo = CargoData -- #CARGO
|
||||
if Cargo:IsAlive() then
|
||||
Destroyed = false
|
||||
else
|
||||
Cargo:Destroyed()
|
||||
end
|
||||
end
|
||||
else
|
||||
local CarrierName = self.CargoCarrier:GetName()
|
||||
if CarrierName == EventData.IniDCSUnitName then
|
||||
MESSAGE:New( "Cargo is lost from carrier " .. CarrierName, 15 ):ToAll()
|
||||
Destroyed = true
|
||||
self.CargoCarrier:ClearCargo()
|
||||
end
|
||||
end
|
||||
|
||||
if Destroyed then
|
||||
self:Destroyed()
|
||||
self:E( { "Cargo group destroyed" } )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Enter Boarding State.
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
@@ -976,7 +1165,7 @@ function CARGO_GROUP:onenterLoaded( From, Event, To, CargoCarrier, ... )
|
||||
end
|
||||
end
|
||||
|
||||
self.CargoObject:Destroy()
|
||||
--self.CargoObject:Destroy()
|
||||
self.CargoCarrier = CargoCarrier
|
||||
|
||||
end
|
||||
@@ -1032,6 +1221,14 @@ function CARGO_GROUP:onafterBoarding( From, Event, To, CargoCarrier, NearRadius,
|
||||
|
||||
end
|
||||
|
||||
--- Get the amount of cargo units in the group.
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @return #CARGO_GROUP
|
||||
function CARGO_GROUP:GetCount()
|
||||
return self.CargoSet:Count()
|
||||
end
|
||||
|
||||
|
||||
--- Enter UnBoarding State.
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @param Core.Point#POINT_VEC2 ToPointVec2
|
||||
@@ -1046,6 +1243,10 @@ function CARGO_GROUP:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius
|
||||
local Timer = 1
|
||||
|
||||
if From == "Loaded" then
|
||||
|
||||
if self.CargoObject then
|
||||
self.CargoObject:Destroy()
|
||||
end
|
||||
|
||||
-- For each Cargo object within the CARGO_GROUP, route each object to the CargoLoadPointVec2
|
||||
self.CargoSet:ForEach(
|
||||
@@ -1137,6 +1338,23 @@ function CARGO_GROUP:onenterUnLoaded( From, Event, To, ToPointVec2, ... )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Respawn the cargo when destroyed
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @param #boolean RespawnDestroyed
|
||||
function CARGO_GROUP:RespawnOnDestroyed( RespawnDestroyed )
|
||||
self:F({"In function RespawnOnDestroyed"})
|
||||
if RespawnDestroyed then
|
||||
self.onenterDestroyed = function( self )
|
||||
self:F("IN FUNCTION")
|
||||
self:Respawn()
|
||||
end
|
||||
else
|
||||
self.onenterDestroyed = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end -- CARGO_GROUP
|
||||
|
||||
do -- CARGO_PACKAGE
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- This module contains the DATABASE class, managing the database of mission objects.
|
||||
--- **Core** -- DATABASE manages the database of mission objects.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
@@ -35,8 +35,13 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
-- @module Database
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
--- DATABASE class
|
||||
-- @type DATABASE
|
||||
@@ -56,12 +61,15 @@ DATABASE = {
|
||||
GROUPS = {},
|
||||
PLAYERS = {},
|
||||
PLAYERSJOINED = {},
|
||||
PLAYERUNITS = {},
|
||||
CLIENTS = {},
|
||||
CARGOS = {},
|
||||
AIRBASES = {},
|
||||
COUNTRY_ID = {},
|
||||
COUNTRY_NAME = {},
|
||||
NavPoints = {},
|
||||
PLAYERSETTINGS = {},
|
||||
ZONENAMES = {},
|
||||
}
|
||||
|
||||
local _DATABASECoalition =
|
||||
@@ -100,34 +108,40 @@ function DATABASE:New()
|
||||
self:HandleEvent( EVENTS.DeleteCargo )
|
||||
|
||||
-- Follow alive players and clients
|
||||
-- self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit )
|
||||
self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit )
|
||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
||||
|
||||
self:_RegisterTemplates()
|
||||
self:_RegisterGroupsAndUnits()
|
||||
self:_RegisterClients()
|
||||
self:_RegisterStatics()
|
||||
self:_RegisterPlayers()
|
||||
--self:_RegisterPlayers()
|
||||
self:_RegisterAirbases()
|
||||
|
||||
self.UNITS_Position = 0
|
||||
|
||||
--- @param #DATABASE self
|
||||
local function CheckPlayers( self )
|
||||
|
||||
local CoalitionsData = { AlivePlayersRed = coalition.getPlayers( coalition.side.RED ), AlivePlayersBlue = coalition.getPlayers( coalition.side.BLUE ) }
|
||||
for CoalitionId, CoalitionData in pairs( CoalitionsData ) do
|
||||
--self:E( { "CoalitionData:", CoalitionData } )
|
||||
for UnitId, UnitData in pairs( CoalitionData ) do
|
||||
if UnitData and UnitData:isExist() then
|
||||
|
||||
local UnitName = UnitData:getName()
|
||||
local PlayerName = UnitData:getPlayerName()
|
||||
local PlayerUnit = UNIT:Find( UnitData )
|
||||
--self:T( { "UnitData:", UnitData, UnitName, PlayerName, PlayerUnit } )
|
||||
|
||||
local UNITS_Count = #self.UNITS_Index
|
||||
if UNITS_Count > 0 then
|
||||
self.UNITS_Position = ( ( self.UNITS_Position <= UNITS_Count ) and self.UNITS_Position + 1 ) or 1
|
||||
local PlayerUnit = self.UNITS[self.UNITS_Index[self.UNITS_Position]]
|
||||
if PlayerUnit then
|
||||
local UnitName = PlayerUnit:GetName()
|
||||
local PlayerName = PlayerUnit:GetPlayerName()
|
||||
--self:E( { UNITS_Count, self.UNITS_Position, UnitName, PlayerName } )
|
||||
if PlayerName and PlayerName ~= "" then
|
||||
if self.PLAYERS[PlayerName] == nil or self.PLAYERS[PlayerName] ~= UnitName then
|
||||
self:E( { "Add player for unit:", UnitName, PlayerName } )
|
||||
self:AddPlayer( UnitName, PlayerName )
|
||||
--_EVENTDISPATCHER:CreateEventPlayerEnterUnit( PlayerUnit )
|
||||
if PlayerName and PlayerName ~= "" then
|
||||
if self.PLAYERS[PlayerName] == nil or self.PLAYERS[PlayerName] ~= UnitName then
|
||||
--self:E( { "Add player for unit:", UnitName, PlayerName } )
|
||||
self:AddPlayer( UnitName, PlayerName )
|
||||
--_EVENTDISPATCHER:CreateEventPlayerEnterUnit( PlayerUnit )
|
||||
local Settings = SETTINGS:Set( PlayerName )
|
||||
Settings:SetPlayerMenu( PlayerUnit )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -135,7 +149,7 @@ function DATABASE:New()
|
||||
end
|
||||
|
||||
self:E( "Scheduling" )
|
||||
--local PlayerCheckSchedule = SCHEDULER:New( nil, CheckPlayers, { self }, 2, 0.1 )
|
||||
PlayerCheckSchedule = SCHEDULER:New( nil, CheckPlayers, { self }, 1, 1 )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -200,6 +214,16 @@ function DATABASE:FindStatic( StaticName )
|
||||
return StaticFound
|
||||
end
|
||||
|
||||
--- Finds a AIRBASE based on the AirbaseName.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string AirbaseName
|
||||
-- @return Wrapper.Airbase#AIRBASE The found AIRBASE.
|
||||
function DATABASE:FindAirbase( AirbaseName )
|
||||
|
||||
local AirbaseFound = self.AIRBASES[AirbaseName]
|
||||
return AirbaseFound
|
||||
end
|
||||
|
||||
--- Adds a Airbase based on the Airbase Name in the DATABASE.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string AirbaseName The name of the airbase
|
||||
@@ -312,17 +336,19 @@ function DATABASE:AddPlayer( UnitName, PlayerName )
|
||||
if PlayerName then
|
||||
self:E( { "Add player for unit:", UnitName, PlayerName } )
|
||||
self.PLAYERS[PlayerName] = UnitName
|
||||
self.PLAYERUNITS[UnitName] = PlayerName
|
||||
self.PLAYERSJOINED[PlayerName] = PlayerName
|
||||
end
|
||||
end
|
||||
|
||||
--- Deletes a player from the DATABASE based on the Player Name.
|
||||
-- @param #DATABASE self
|
||||
function DATABASE:DeletePlayer( PlayerName )
|
||||
function DATABASE:DeletePlayer( UnitName, PlayerName )
|
||||
|
||||
if PlayerName then
|
||||
self:E( { "Clean player:", PlayerName } )
|
||||
self.PLAYERS[PlayerName] = nil
|
||||
self.PLAYERUNITS[UnitName] = PlayerName
|
||||
end
|
||||
end
|
||||
|
||||
@@ -359,7 +385,12 @@ function DATABASE:Spawn( SpawnTemplate )
|
||||
SpawnTemplate.CountryID = SpawnCountryID
|
||||
SpawnTemplate.CategoryID = SpawnCategoryID
|
||||
|
||||
-- Ensure that for the spawned group and its units, there are GROUP and UNIT objects created in the DATABASE.
|
||||
local SpawnGroup = self:AddGroup( SpawnTemplate.name )
|
||||
for UnitID, UnitData in pairs( SpawnTemplate.units ) do
|
||||
self:AddUnit( UnitData.name )
|
||||
end
|
||||
|
||||
return SpawnGroup
|
||||
end
|
||||
|
||||
@@ -667,7 +698,7 @@ function DATABASE:_EventOnBirth( Event )
|
||||
self:AddGroup( Event.IniDCSGroupName )
|
||||
end
|
||||
end
|
||||
self:_EventOnPlayerEnterUnit( Event )
|
||||
--self:_EventOnPlayerEnterUnit( Event )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -708,6 +739,8 @@ function DATABASE:_EventOnPlayerEnterUnit( Event )
|
||||
if not self.PLAYERS[PlayerName] then
|
||||
self:AddPlayer( Event.IniUnitName, PlayerName )
|
||||
end
|
||||
local Settings = SETTINGS:Set( PlayerName )
|
||||
Settings:SetPlayerMenu( Event.IniUnit )
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -723,7 +756,9 @@ function DATABASE:_EventOnPlayerLeaveUnit( Event )
|
||||
if Event.IniObjectCategory == 1 then
|
||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||
if self.PLAYERS[PlayerName] then
|
||||
self:DeletePlayer( PlayerName )
|
||||
local Settings = SETTINGS:Set( PlayerName )
|
||||
Settings:RemovePlayerMenu( Event.IniUnit )
|
||||
self:DeletePlayer( Event.IniUnit, PlayerName )
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -808,10 +843,10 @@ end
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a GROUP parameter.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachGroup( IteratorFunction, ... )
|
||||
function DATABASE:ForEachGroup( IteratorFunction, FinalizeFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, arg, self.GROUPS )
|
||||
self:ForEach( IteratorFunction, FinalizeFunction, arg, self.GROUPS )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -821,10 +856,10 @@ end
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept the player name.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachPlayer( IteratorFunction, ... )
|
||||
function DATABASE:ForEachPlayer( IteratorFunction, FinalizeFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, arg, self.PLAYERS )
|
||||
self:ForEach( IteratorFunction, FinalizeFunction, arg, self.PLAYERS )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -834,14 +869,27 @@ end
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept a UNIT parameter.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachPlayerJoined( IteratorFunction, ... )
|
||||
function DATABASE:ForEachPlayerJoined( IteratorFunction, FinalizeFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, arg, self.PLAYERSJOINED )
|
||||
self:ForEach( IteratorFunction, FinalizeFunction, arg, self.PLAYERSJOINED )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for each **ALIVE** player UNIT, providing the player UNIT and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called for each object in the database. The function needs to accept the player name.
|
||||
-- @return #DATABASE self
|
||||
function DATABASE:ForEachPlayerUnit( IteratorFunction, FinalizeFunction, ... )
|
||||
self:F2( arg )
|
||||
|
||||
self:ForEach( IteratorFunction, FinalizeFunction, arg, self.PLAYERUNITS )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Iterate the DATABASE and call an iterator function for each CLIENT, providing the CLIENT to the function and optional parameters.
|
||||
-- @param #DATABASE self
|
||||
-- @param #function IteratorFunction The function that will be called object in the database. The function needs to accept a CLIENT parameter.
|
||||
@@ -891,6 +939,29 @@ function DATABASE:OnEventDeleteCargo( EventData )
|
||||
end
|
||||
|
||||
|
||||
--- Gets the player settings
|
||||
-- @param #DATABASE self
|
||||
-- @param #string PlayerName
|
||||
-- @return Core.Settings#SETTINGS
|
||||
function DATABASE:GetPlayerSettings( PlayerName )
|
||||
self:E({PlayerName})
|
||||
return self.PLAYERSETTINGS[PlayerName]
|
||||
end
|
||||
|
||||
|
||||
--- Sets the player settings
|
||||
-- @param #DATABASE self
|
||||
-- @param #string PlayerName
|
||||
-- @param Core.Settings#SETTINGS Settings
|
||||
-- @return Core.Settings#SETTINGS
|
||||
function DATABASE:SetPlayerSettings( PlayerName, Settings )
|
||||
self:E({PlayerName, Settings})
|
||||
self.PLAYERSETTINGS[PlayerName] = Settings
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- @param #DATABASE self
|
||||
function DATABASE:_RegisterTemplates()
|
||||
self:F2()
|
||||
@@ -974,6 +1045,11 @@ function DATABASE:_RegisterTemplates()
|
||||
end --if coa_name == 'red' or coa_name == 'blue' and type(coa_data) == 'table' then
|
||||
end --for coa_name, coa_data in pairs(mission.coalition) do
|
||||
|
||||
for ZoneID, ZoneData in pairs( env.mission.triggers.zones ) do
|
||||
local ZoneName = ZoneData.name
|
||||
self.ZONENAMES[ZoneName] = ZoneName
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Core R2.1** - EVENT models DCS **event dispatching** using a **publish-subscribe** model.
|
||||
--- **Core** -- EVENT models DCS **event dispatching** using a **publish-subscribe** model.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -157,33 +157,12 @@
|
||||
--
|
||||
-- When a static object is involved in the event, the Group and Player fields won't be populated.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction**( Params ) replaces CLASS:_OldFunction_( Params )
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction( Params )** added
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- * 2017-03-07: Added the correct event dispatching in case the event is subscribed by a GROUP.
|
||||
--
|
||||
-- * 2017-02-07: Did a complete revision of the Event Handing API and underlying mechanisms.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * [**FlightControl**](https://forums.eagle.ru/member.php?u=89536): Design & Programming & documentation.
|
||||
-- ====
|
||||
--
|
||||
-- @module Event
|
||||
|
||||
@@ -471,16 +450,16 @@ end
|
||||
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
|
||||
-- @param Dcs.DCSWorld#world.event EventID
|
||||
-- @return #EVENT.Events
|
||||
function EVENT:Remove( EventClass, EventID )
|
||||
function EVENT:RemoveEvent( EventClass, EventID )
|
||||
|
||||
self:E( { "Removing subscription for class: ", EventClass:GetClassNameAndID() } )
|
||||
self:F2( { "Removing subscription for class: ", EventClass:GetClassNameAndID() } )
|
||||
|
||||
local EventPriority = EventClass:GetEventPriority()
|
||||
|
||||
self.EventsDead = self.EventsDead or {}
|
||||
self.EventsDead[EventID] = self.EventsDead[EventID] or {}
|
||||
self.EventsDead[EventID][EventPriority] = self.EventsDead[EventID][EventPriority] or {}
|
||||
self.EventsDead[EventID][EventPriority][EventClass] = self.Events[EventID][EventPriority][EventClass]
|
||||
self.Events = self.Events or {}
|
||||
self.Events[EventID] = self.Events[EventID] or {}
|
||||
self.Events[EventID][EventPriority] = self.Events[EventID][EventPriority] or {}
|
||||
self.Events[EventID][EventPriority][EventClass] = self.Events[EventID][EventPriority][EventClass]
|
||||
|
||||
self.Events[EventID][EventPriority][EventClass] = nil
|
||||
|
||||
@@ -764,7 +743,10 @@ function EVENT:onEvent( Event )
|
||||
|
||||
local EventMeta = _EVENTMETA[Event.id]
|
||||
|
||||
if self and self.Events and self.Events[Event.id] then
|
||||
if self and
|
||||
self.Events and
|
||||
self.Events[Event.id] and
|
||||
( Event.initiator ~= nil or ( Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit ) ) then
|
||||
|
||||
if Event.initiator then
|
||||
|
||||
@@ -810,7 +792,7 @@ function EVENT:onEvent( Event )
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" -- TODO: Bug fix for 2.1!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -941,7 +923,7 @@ function EVENT:onEvent( Event )
|
||||
end
|
||||
else
|
||||
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
|
||||
self:Remove( EventClass, Event.id )
|
||||
self:RemoveEvent( EventClass, Event.id )
|
||||
end
|
||||
else
|
||||
|
||||
@@ -991,7 +973,7 @@ function EVENT:onEvent( Event )
|
||||
end
|
||||
else
|
||||
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
|
||||
self:Remove( EventClass, Event.id )
|
||||
self:RemoveEvent( EventClass, Event.id )
|
||||
end
|
||||
else
|
||||
|
||||
@@ -1004,7 +986,7 @@ function EVENT:onEvent( Event )
|
||||
|
||||
-- There is an EventFunction defined, so call the EventFunction.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:E( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
@@ -1018,7 +1000,7 @@ function EVENT:onEvent( Event )
|
||||
|
||||
-- Now call the default event function.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:E( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
|
||||
local Result, Value = xpcall(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Core** - The **FSM** (**F**inite **S**tate **M**achine) class and derived **FSM\_** classes
|
||||
--- **Core** -- The **FSM** (**F**inite **S**tate **M**achine) class and derived **FSM\_** classes
|
||||
-- are design patterns allowing efficient (long-lasting) processes and workflows.
|
||||
--
|
||||
-- 
|
||||
@@ -58,31 +58,11 @@
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction**( Params ) replaces CLASS:_OldFunction_( Params )
|
||||
-- YYYY-MM-DD: CLASS:**NewFunction( Params )** added
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- * 2016-12-18: Released.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * [**Pikey**](https://forums.eagle.ru/member.php?u=62835): Review of documentation & advice for improvements.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * [**FlightControl**](https://forums.eagle.ru/member.php?u=89536): Design & Programming & documentation.
|
||||
-- ====
|
||||
--
|
||||
-- @module Fsm
|
||||
|
||||
@@ -416,7 +396,7 @@ do -- FSM
|
||||
Transition.Event = Event
|
||||
Transition.To = To
|
||||
|
||||
self:T( Transition )
|
||||
self:T2( Transition )
|
||||
|
||||
self._Transitions[Transition] = Transition
|
||||
self:_eventmap( self.Events, Transition )
|
||||
@@ -438,7 +418,7 @@ do -- FSM
|
||||
-- @param #table ReturnEvents A table indicating for which returned events of the SubFSM which Event must be triggered in the FSM.
|
||||
-- @return Core.Fsm#FSM_PROCESS The SubFSM.
|
||||
function FSM:AddProcess( From, Event, Process, ReturnEvents )
|
||||
self:T( { From, Event, Process, ReturnEvents } )
|
||||
self:T( { From, Event } )
|
||||
|
||||
local Sub = {}
|
||||
Sub.From = From
|
||||
@@ -554,14 +534,14 @@ do -- FSM
|
||||
local __Event = "__" .. EventStructure.Event
|
||||
self[Event] = self[Event] or self:_create_transition(Event)
|
||||
self[__Event] = self[__Event] or self:_delayed_transition(Event)
|
||||
self:T( "Added methods: " .. Event .. ", " .. __Event )
|
||||
self:T2( "Added methods: " .. Event .. ", " .. __Event )
|
||||
Events[Event] = self.Events[Event] or { map = {} }
|
||||
self:_add_to_map( Events[Event].map, EventStructure )
|
||||
|
||||
end
|
||||
|
||||
function FSM:_submap( subs, sub, name )
|
||||
self:F( { sub = sub, name = name } )
|
||||
--self:F( { sub = sub, name = name } )
|
||||
subs[sub.From] = subs[sub.From] or {}
|
||||
subs[sub.From][sub.Event] = subs[sub.From][sub.Event] or {}
|
||||
|
||||
@@ -589,7 +569,7 @@ do -- FSM
|
||||
return errmsg
|
||||
end
|
||||
if self[handler] then
|
||||
self:T( "Calling " .. handler )
|
||||
self:T2( "Calling " .. handler )
|
||||
self._EventSchedules[EventName] = nil
|
||||
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler )
|
||||
return Value
|
||||
@@ -864,7 +844,7 @@ do -- FSM_CONTROLLABLE
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE FSMControllable
|
||||
-- @return #FSM_CONTROLLABLE
|
||||
function FSM_CONTROLLABLE:SetControllable( FSMControllable )
|
||||
self:F( FSMControllable )
|
||||
--self:F( FSMControllable:GetName() )
|
||||
self.Controllable = FSMControllable
|
||||
end
|
||||
|
||||
@@ -924,7 +904,7 @@ do -- FSM_PROCESS
|
||||
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
self:F( Controllable, Task )
|
||||
--self:F( Controllable )
|
||||
|
||||
self:Assign( Controllable, Task )
|
||||
|
||||
@@ -980,7 +960,7 @@ do -- FSM_PROCESS
|
||||
|
||||
-- Copy Processes
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
self:E( { Process} )
|
||||
--self:E( { Process:GetName() } )
|
||||
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
|
||||
end
|
||||
|
||||
@@ -1010,7 +990,6 @@ do -- FSM_PROCESS
|
||||
|
||||
-- Copy Processes
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
self:E( { Process} )
|
||||
if Process.fsm then
|
||||
Process.fsm:Remove()
|
||||
Process.fsm = nil
|
||||
@@ -1083,7 +1062,7 @@ end
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @return #FSM_PROCESS self
|
||||
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
||||
self:T( { Task, ProcessUnit } )
|
||||
--self:T( { Task:GetName(), ProcessUnit:GetName() } )
|
||||
|
||||
self:SetControllable( ProcessUnit )
|
||||
self:SetTask( Task )
|
||||
@@ -1104,12 +1083,7 @@ end
|
||||
|
||||
self.Task:Fail()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterSuccess( ProcessUnit )
|
||||
self:T( "Success" )
|
||||
|
||||
self.Task:Success()
|
||||
end
|
||||
|
||||
|
||||
--- StateMachine callback function for a FSM_PROCESS
|
||||
-- @param #FSM_PROCESS self
|
||||
@@ -1118,7 +1092,7 @@ end
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function FSM_PROCESS:onstatechange( ProcessUnit, Task, From, Event, To, Dummy )
|
||||
self:T( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
|
||||
self:T( { ProcessUnit:GetName(), From, Event, To, Dummy, self:IsTrace() } )
|
||||
|
||||
if self:IsTrace() then
|
||||
--MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
||||
|
||||
@@ -26,14 +26,11 @@
|
||||
-- * @{Menu#MENU_CLIENT_COMMAND}: Manages command menus for CLIENTs. This manages menus for units with the skill level "Client".
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
---
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming
|
||||
-- ====
|
||||
--
|
||||
-- @module Menu
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Core** - MESSAGE class takes are of the **real-time notifications** and **messages to players** during a simulation.
|
||||
--- **Core** -- MESSAGE class takes are of the **real-time notifications** and **messages to players** during a simulation.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -39,6 +39,13 @@
|
||||
-- * To all players using @{Message#MESSAGE.ToAllIf}().
|
||||
-- * To a coalition using @{Message#MESSAGE.ToCoalitionIf}().
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @field #MESSAGE
|
||||
MESSAGE = {
|
||||
ClassName = "MESSAGE",
|
||||
@@ -80,7 +87,7 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory )
|
||||
|
||||
self.MessageDuration = MessageDuration or 5
|
||||
self.MessageTime = timer.getTime()
|
||||
self.MessageText = MessageText
|
||||
self.MessageText = MessageText:gsub("^\n","",1):gsub("\n$","",1)
|
||||
|
||||
self.MessageSent = false
|
||||
self.MessageGroup = false
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
--- **Core** - The RADIO Module is responsible for everything that is related to radio transmission and you can hear in DCS, be it TACAN beacons, Radio transmissions...
|
||||
--- **Core** -- The RADIO Module is responsible for everything that is related to radio transmission and you can hear in DCS, be it TACAN beacons, Radio transmissions...
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -79,7 +79,7 @@
|
||||
-- @field #string Subtitle Subtitle of the transmission
|
||||
-- @field #number SubtitleDuration Duration of the Subtitle in seconds
|
||||
-- @field #number Power Power of the antenna is Watts
|
||||
-- @field #boolean Loop
|
||||
-- @field #boolean Loop (default true)
|
||||
-- @extends Core.Base#BASE
|
||||
RADIO = {
|
||||
ClassName = "RADIO",
|
||||
@@ -89,7 +89,7 @@ RADIO = {
|
||||
Subtitle = "",
|
||||
SubtitleDuration = 0,
|
||||
Power = 100,
|
||||
Loop = 0,
|
||||
Loop = true,
|
||||
}
|
||||
|
||||
--- Create a new RADIO Object. This doesn't broadcast a transmission, though, use @{#RADIO.Broadcast} to actually broadcast
|
||||
@@ -101,6 +101,7 @@ RADIO = {
|
||||
function RADIO:New(Positionable)
|
||||
local self = BASE:Inherit( self, BASE:New() ) -- Core.Radio#RADIO
|
||||
|
||||
self.Loop = true -- default Loop to true (not sure the above RADIO definition actually is working)
|
||||
self:F(Positionable)
|
||||
|
||||
if Positionable:GetPointVec2() then -- It's stupid, but the only way I found to make sure positionable is valid
|
||||
@@ -296,6 +297,7 @@ end
|
||||
-- @return #RADIO self
|
||||
function RADIO:Broadcast()
|
||||
self:F()
|
||||
|
||||
-- If the POSITIONABLE is actually a UNIT or a GROUP, use the more complicated DCS command system
|
||||
if self.Positionable.ClassName == "UNIT" or self.Positionable.ClassName == "GROUP" then
|
||||
self:T2("Broadcasting from a UNIT or a GROUP")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- This module defines the SCHEDULEDISPATCHER class, which is used by a central object called _SCHEDULEDISPATCHER.
|
||||
--- **Core** -- SCHEDULEDISPATCHER dispatches the different schedules.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -27,8 +27,6 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Contributions: -
|
||||
-- ### Authors: FlightControl : Design & Programming
|
||||
--
|
||||
@@ -64,7 +62,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
||||
|
||||
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
|
||||
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
|
||||
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } ) -- or {}
|
||||
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } )
|
||||
|
||||
if Scheduler.MasterObject then
|
||||
self.ObjectSchedulers[self.CallID] = Scheduler
|
||||
@@ -103,13 +101,13 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
||||
Scheduler = self.PersistentSchedulers[CallID]
|
||||
end
|
||||
|
||||
self:T3( { Scheduler = Scheduler } )
|
||||
--self:T3( { Scheduler = Scheduler } )
|
||||
|
||||
if Scheduler then
|
||||
|
||||
local Schedule = self.Schedule[Scheduler][CallID]
|
||||
|
||||
self:T3( { Schedule = Schedule } )
|
||||
--self:T3( { Schedule = Schedule } )
|
||||
|
||||
local ScheduleObject = Scheduler.SchedulerObject
|
||||
--local ScheduleObjectName = Scheduler.SchedulerObject:GetNameAndClassID()
|
||||
@@ -147,7 +145,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
||||
( Randomize * Repeat / 2 )
|
||||
) +
|
||||
0.01
|
||||
self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
|
||||
--self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
|
||||
return ScheduleTime -- returns the next time the function needs to be called.
|
||||
else
|
||||
self:Stop( Scheduler, CallID )
|
||||
@@ -156,7 +154,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
|
||||
self:Stop( Scheduler, CallID )
|
||||
end
|
||||
else
|
||||
self:E( "Scheduled obscolete call for CallID: " .. CallID )
|
||||
self:E( "Scheduled obsolete call for CallID: " .. CallID )
|
||||
end
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Core** - SCHEDULER prepares and handles the **execution of functions over scheduled time (intervals)**.
|
||||
--- **Core** -- SCHEDULER prepares and handles the **execution of functions over scheduled time (intervals)**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Core** - SET_ classes define **collections** of objects to perform **bulk actions** and logically **group** objects.
|
||||
--- **Core** -- SET_ classes define **collections** of objects to perform **bulk actions** and logically **group** objects.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -23,12 +23,12 @@
|
||||
-- * Validate the presence of objects in the SET.
|
||||
-- * Trigger events when objects in the SET change a zone presence.
|
||||
--
|
||||
-- ### Authors:
|
||||
-- ====
|
||||
--
|
||||
-- * FlightControl : Design & Programming
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Set
|
||||
|
||||
@@ -84,11 +84,6 @@ function SET_BASE:New( Database )
|
||||
self.TimeInterval = 0.001
|
||||
|
||||
self.Set = {}
|
||||
|
||||
self.List = {}
|
||||
self.List.__index = self.List
|
||||
self.List = setmetatable( { Count = 0 }, self.List )
|
||||
|
||||
self.Index = {}
|
||||
|
||||
self.CallScheduler = SCHEDULER:New( self )
|
||||
@@ -126,24 +121,8 @@ end
|
||||
function SET_BASE:Add( ObjectName, Object )
|
||||
self:F( ObjectName )
|
||||
|
||||
local t = { _ = Object }
|
||||
|
||||
if self.List.last then
|
||||
self.List.last._next = t
|
||||
t._prev = self.List.last
|
||||
self.List.last = t
|
||||
else
|
||||
-- this is the first node
|
||||
self.List.first = t
|
||||
self.List.last = t
|
||||
end
|
||||
|
||||
self.List.Count = self.List.Count + 1
|
||||
|
||||
self.Set[ObjectName] = Object
|
||||
|
||||
table.insert( self.Index, ObjectName )
|
||||
|
||||
end
|
||||
|
||||
--- Adds a @{Base#BASE} object in the @{Set#SET_BASE}, using the Object Name as the index.
|
||||
@@ -166,43 +145,19 @@ end
|
||||
-- @param #string ObjectName
|
||||
function SET_BASE:Remove( ObjectName )
|
||||
|
||||
local t = self.Set[ObjectName]
|
||||
local Object = self.Set[ObjectName]
|
||||
|
||||
self:F3( { ObjectName, t } )
|
||||
self:F3( { ObjectName, Object } )
|
||||
|
||||
if t then
|
||||
if t._next then
|
||||
if t._prev then
|
||||
t._next._prev = t._prev
|
||||
t._prev._next = t._next
|
||||
else
|
||||
-- this was the first node
|
||||
t._next._prev = nil
|
||||
self.List._first = t._next
|
||||
end
|
||||
elseif t._prev then
|
||||
-- this was the last node
|
||||
t._prev._next = nil
|
||||
self.List._last = t._prev
|
||||
else
|
||||
-- this was the only node
|
||||
self.List._first = nil
|
||||
self.List._last = nil
|
||||
end
|
||||
|
||||
t._next = nil
|
||||
t._prev = nil
|
||||
self.List.Count = self.List.Count - 1
|
||||
|
||||
if Object then
|
||||
for Index, Key in ipairs( self.Index ) do
|
||||
if Key == ObjectName then
|
||||
table.remove( self.Index, Index )
|
||||
self.Set[ObjectName] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self.Set[ObjectName] = nil
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -214,19 +169,16 @@ end
|
||||
function SET_BASE:Get( ObjectName )
|
||||
self:F( ObjectName )
|
||||
|
||||
local t = self.Set[ObjectName]
|
||||
|
||||
self:T3( { ObjectName, t } )
|
||||
|
||||
return t
|
||||
local Object = self.Set[ObjectName]
|
||||
|
||||
self:T3( { ObjectName, Object } )
|
||||
return Object
|
||||
end
|
||||
|
||||
--- Gets the first object from the @{Set#SET_BASE} and derived classes.
|
||||
-- @param #SET_BASE self
|
||||
-- @return Core.Base#BASE
|
||||
function SET_BASE:GetFirst()
|
||||
self:F()
|
||||
|
||||
local ObjectName = self.Index[1]
|
||||
local FirstObject = self.Set[ObjectName]
|
||||
@@ -238,7 +190,6 @@ end
|
||||
-- @param #SET_BASE self
|
||||
-- @return Core.Base#BASE
|
||||
function SET_BASE:GetLast()
|
||||
self:F()
|
||||
|
||||
local ObjectName = self.Index[#self.Index]
|
||||
local LastObject = self.Set[ObjectName]
|
||||
@@ -250,12 +201,9 @@ end
|
||||
-- @param #SET_BASE self
|
||||
-- @return Core.Base#BASE
|
||||
function SET_BASE:GetRandom()
|
||||
self:F()
|
||||
|
||||
local RandomItem = self.Set[self.Index[math.random(#self.Index)]]
|
||||
|
||||
self:T3( { RandomItem } )
|
||||
|
||||
return RandomItem
|
||||
end
|
||||
|
||||
@@ -265,7 +213,7 @@ end
|
||||
-- @return #number Count
|
||||
function SET_BASE:Count()
|
||||
|
||||
return #self.Index or 0
|
||||
return self.Index and #self.Index or 0
|
||||
end
|
||||
|
||||
|
||||
@@ -603,6 +551,20 @@ function SET_BASE:IsIncludeObject( Object )
|
||||
return true
|
||||
end
|
||||
|
||||
--- Gets a string with all the object names.
|
||||
-- @param #SET_BASE self
|
||||
-- @return #string A string with the names of the objects.
|
||||
function SET_BASE:GetObjectNames()
|
||||
self:F3()
|
||||
|
||||
local ObjectNames = ""
|
||||
for ObjectName, Object in pairs( self.Set ) do
|
||||
ObjectNames = ObjectNames .. ObjectName .. ", "
|
||||
end
|
||||
|
||||
return ObjectNames
|
||||
end
|
||||
|
||||
--- Flushes the current SET_BASE contents in the log ... (for debugging reasons).
|
||||
-- @param #SET_BASE self
|
||||
-- @return #string A string with the names of the objects.
|
||||
@@ -622,7 +584,7 @@ end
|
||||
--- @type SET_GROUP
|
||||
-- @extends Core.Set#SET_BASE
|
||||
|
||||
--- # 2) SET_GROUP class, extends @{Set#SET_BASE}
|
||||
--- # SET_GROUP class, extends @{Set#SET_BASE}
|
||||
--
|
||||
-- Mission designers can use the @{Set#SET_GROUP} class to build sets of groups belonging to certain:
|
||||
--
|
||||
@@ -631,18 +593,18 @@ end
|
||||
-- * Countries
|
||||
-- * Starting with certain prefix strings.
|
||||
--
|
||||
-- ## 2.1) SET_GROUP constructor
|
||||
-- ## 1. SET_GROUP constructor
|
||||
--
|
||||
-- Create a new SET_GROUP object with the @{#SET_GROUP.New} method:
|
||||
--
|
||||
-- * @{#SET_GROUP.New}: Creates a new SET_GROUP object.
|
||||
--
|
||||
-- ## 2.2) Add or Remove GROUP(s) from SET_GROUP
|
||||
-- ## 2. Add or Remove GROUP(s) from SET_GROUP
|
||||
--
|
||||
-- GROUPS can be added and removed using the @{Set#SET_GROUP.AddGroupsByName} and @{Set#SET_GROUP.RemoveGroupsByName} respectively.
|
||||
-- These methods take a single GROUP name or an array of GROUP names to be added or removed from SET_GROUP.
|
||||
--
|
||||
-- ## 2.3) SET_GROUP filter criteria
|
||||
-- ## 3. SET_GROUP filter criteria
|
||||
--
|
||||
-- You can set filter criteria to define the set of groups within the SET_GROUP.
|
||||
-- Filter criteria are defined by:
|
||||
@@ -651,6 +613,15 @@ end
|
||||
-- * @{#SET_GROUP.FilterCategories}: Builds the SET_GROUP with the groups belonging to the category(ies).
|
||||
-- * @{#SET_GROUP.FilterCountries}: Builds the SET_GROUP with the gruops belonging to the country(ies).
|
||||
-- * @{#SET_GROUP.FilterPrefixes}: Builds the SET_GROUP with the groups starting with the same prefix string(s).
|
||||
--
|
||||
-- For the Category Filter, extra methods have been added:
|
||||
--
|
||||
-- * @{#SET_GROUP.FilterCategoryAirplane}: Builds the SET_GROUP from airplanes.
|
||||
-- * @{#SET_GROUP.FilterCategoryHelicopter}: Builds the SET_GROUP from helicopters.
|
||||
-- * @{#SET_GROUP.FilterCategoryGround}: Builds the SET_GROUP from ground vehicles or infantry.
|
||||
-- * @{#SET_GROUP.FilterCategoryShip}: Builds the SET_GROUP from ships.
|
||||
-- * @{#SET_GROUP.FilterCategoryStructure}: Builds the SET_GROUP from structures.
|
||||
--
|
||||
--
|
||||
-- Once the filter criteria have been set for the SET_GROUP, you can start filtering using:
|
||||
--
|
||||
@@ -660,7 +631,7 @@ end
|
||||
--
|
||||
-- * @{#SET_GROUP.FilterZones}: Builds the SET_GROUP with the groups within a @{Zone#ZONE}.
|
||||
--
|
||||
-- ## 2.4) SET_GROUP iterators
|
||||
-- ## 4. SET_GROUP iterators
|
||||
--
|
||||
-- Once the filters have been defined and the SET_GROUP has been built, you can iterate the SET_GROUP with the available iterator methods.
|
||||
-- The iterator methods will walk the SET_GROUP set, and call for each element within the set a function that you provide.
|
||||
@@ -690,7 +661,7 @@ SET_GROUP = {
|
||||
Categories = {
|
||||
plane = Group.Category.AIRPLANE,
|
||||
helicopter = Group.Category.HELICOPTER,
|
||||
ground = Group.Category.GROUND_UNIT,
|
||||
ground = Group.Category.GROUND, -- R2.2
|
||||
ship = Group.Category.SHIP,
|
||||
structure = Group.Category.STRUCTURE,
|
||||
},
|
||||
@@ -819,6 +790,48 @@ function SET_GROUP:FilterCategories( Categories )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Builds a set of groups out of ground category.
|
||||
-- @param #SET_GROUP self
|
||||
-- @return #SET_GROUP self
|
||||
function SET_GROUP:FilterCategoryGround()
|
||||
self:FilterCategories( "ground" )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Builds a set of groups out of airplane category.
|
||||
-- @param #SET_GROUP self
|
||||
-- @return #SET_GROUP self
|
||||
function SET_GROUP:FilterCategoryAirplane()
|
||||
self:FilterCategories( "plane" )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Builds a set of groups out of helicopter category.
|
||||
-- @param #SET_GROUP self
|
||||
-- @return #SET_GROUP self
|
||||
function SET_GROUP:FilterCategoryHelicopter()
|
||||
self:FilterCategories( "helicopter" )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Builds a set of groups out of ship category.
|
||||
-- @param #SET_GROUP self
|
||||
-- @return #SET_GROUP self
|
||||
function SET_GROUP:FilterCategoryShip()
|
||||
self:FilterCategories( "ship" )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Builds a set of groups out of structure category.
|
||||
-- @param #SET_GROUP self
|
||||
-- @return #SET_GROUP self
|
||||
function SET_GROUP:FilterCategoryStructure()
|
||||
self:FilterCategories( "structure" )
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Builds a set of groups of defined countries.
|
||||
-- Possible current countries are those known within DCS world.
|
||||
-- @param #SET_GROUP self
|
||||
@@ -871,6 +884,23 @@ function SET_GROUP:FilterStart()
|
||||
return self
|
||||
end
|
||||
|
||||
--- Handles the OnDead or OnCrash event for alive groups set.
|
||||
-- Note: The GROUP object in the SET_GROUP collection will only be removed if the last unit is destroyed of the GROUP.
|
||||
-- @param #SET_GROUP self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function SET_GROUP:_EventOnDeadOrCrash( Event )
|
||||
self:F3( { Event } )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
local ObjectName, Object = self:FindInDatabase( Event )
|
||||
if ObjectName then
|
||||
if Event.IniDCSGroup:getSize() == 1 then -- Only remove if the last unit of the group was destroyed.
|
||||
self:Remove( ObjectName )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Handles the Database to check on an event (birth) that the Object was added in the Database.
|
||||
-- This is required, because sometimes the _DATABASE birth event gets called later than the SET_BASE birth event!
|
||||
-- @param #SET_GROUP self
|
||||
@@ -1231,7 +1261,7 @@ function SET_GROUP:IsIncludeObject( MooseGroup )
|
||||
local MooseGroupPrefix = false
|
||||
for GroupPrefixId, GroupPrefix in pairs( self.Filter.GroupPrefixes ) do
|
||||
self:T3( { "Prefix:", string.find( MooseGroup:GetName(), GroupPrefix, 1 ), GroupPrefix } )
|
||||
if string.find( MooseGroup:GetName(), GroupPrefix, 1 ) then
|
||||
if string.find( MooseGroup:GetName(), GroupPrefix:gsub ("-", "%%-"), 1 ) then
|
||||
MooseGroupPrefix = true
|
||||
end
|
||||
end
|
||||
@@ -2735,13 +2765,13 @@ SET_CARGO = {
|
||||
|
||||
--- (R2.1) Creates a new SET_CARGO object, building a set of cargos belonging to a coalitions and categories.
|
||||
-- @param #SET_CARGO self
|
||||
-- @return #SET_CARGO self
|
||||
-- @return #SET_CARGO
|
||||
-- @usage
|
||||
-- -- Define a new SET_CARGO Object. The DatabaseSet will contain a reference to all Cargos.
|
||||
-- DatabaseSet = SET_CARGO:New()
|
||||
function SET_CARGO:New() --R2.1
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.CARGOS ) )
|
||||
local self = BASE:Inherit( self, SET_BASE:New( _DATABASE.CARGOS ) ) -- #SET_CARGO
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
460
Moose Development/Moose/Core/Settings.lua
Normal file
460
Moose Development/Moose/Core/Settings.lua
Normal file
@@ -0,0 +1,460 @@
|
||||
--- **Core** -- **SETTINGS** classe defines the format settings management for measurement.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # Demo Missions
|
||||
--
|
||||
-- ### [SETTINGS Demo Missions source code]()
|
||||
--
|
||||
-- ### [SETTINGS Demo Missions, only for beta testers]()
|
||||
--
|
||||
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # YouTube Channel
|
||||
--
|
||||
-- ### [SETTINGS YouTube Channel]()
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Settings
|
||||
|
||||
|
||||
--- @type SETTINGS
|
||||
-- @field #number LL_Accuracy
|
||||
-- @field #boolean LL_DMS
|
||||
-- @field #number MGRS_Accuracy
|
||||
-- @field #string A2GSystem
|
||||
-- @field #string A2ASystem
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
--- # SETTINGS class, extends @{Base#BASE}
|
||||
--
|
||||
-- @field #SETTINGS
|
||||
SETTINGS = {
|
||||
ClassName = "SETTINGS",
|
||||
}
|
||||
|
||||
|
||||
|
||||
do -- SETTINGS
|
||||
|
||||
--- SETTINGS constructor.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:Set( PlayerName )
|
||||
|
||||
if PlayerName == nil then
|
||||
local self = BASE:Inherit( self, BASE:New() ) -- #SETTINGS
|
||||
self:SetMetric() -- Defaults
|
||||
self:SetA2G_BR() -- Defaults
|
||||
self:SetA2A_BRAA() -- Defaults
|
||||
self:SetLL_Accuracy( 2 ) -- Defaults
|
||||
self:SetLL_DMS( true ) -- Defaults
|
||||
self:SetMGRS_Accuracy( 5 ) -- Defaults
|
||||
return self
|
||||
else
|
||||
local Settings = _DATABASE:GetPlayerSettings( PlayerName )
|
||||
if not Settings then
|
||||
Settings = BASE:Inherit( self, BASE:New() ) -- #SETTINGS
|
||||
_DATABASE:SetPlayerSettings( PlayerName, Settings )
|
||||
end
|
||||
return Settings
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Sets the SETTINGS metric.
|
||||
-- @param #SETTINGS self
|
||||
function SETTINGS:SetMetric()
|
||||
self.Metric = true
|
||||
end
|
||||
|
||||
--- Gets if the SETTINGS is metric.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if metric.
|
||||
function SETTINGS:IsMetric()
|
||||
self:E( {Metric = ( self.Metric ~= nil and self.Metric == true ) or ( self.Metric == nil and _SETTINGS:IsMetric() ) } )
|
||||
return ( self.Metric ~= nil and self.Metric == true ) or ( self.Metric == nil and _SETTINGS:IsMetric() )
|
||||
end
|
||||
|
||||
--- Sets the SETTINGS imperial.
|
||||
-- @param #SETTINGS self
|
||||
function SETTINGS:SetImperial()
|
||||
self.Metric = false
|
||||
end
|
||||
|
||||
--- Gets if the SETTINGS is imperial.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if imperial.
|
||||
function SETTINGS:IsImperial()
|
||||
self:E( {Metric = ( self.Metric ~= nil and self.Metric == false ) or ( self.Metric == nil and _SETTINGS:IsMetric() ) } )
|
||||
return ( self.Metric ~= nil and self.Metric == false ) or ( self.Metric == nil and _SETTINGS:IsMetric() )
|
||||
end
|
||||
|
||||
--- Sets the SETTINGS LL accuracy.
|
||||
-- @param #SETTINGS self
|
||||
-- @param #number LL_Accuracy
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetLL_Accuracy( LL_Accuracy )
|
||||
self.LL_Accuracy = LL_Accuracy
|
||||
end
|
||||
|
||||
--- Gets the SETTINGS LL accuracy.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #number
|
||||
function SETTINGS:GetLL_Accuracy()
|
||||
return self.LL_Accuracy or _SETTINGS:GetLL_Accuracy()
|
||||
end
|
||||
|
||||
--- Sets the SETTINGS LL DMS.
|
||||
-- @param #SETTINGS self
|
||||
-- @param #number LL_DMS
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetLL_DMS( LL_DMS )
|
||||
self.LL_DMS = LL_DMS
|
||||
end
|
||||
|
||||
--- Gets the SETTINGS LL DMS.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #number
|
||||
function SETTINGS:GetLL_DMS()
|
||||
return self.LL_DMS or _SETTINGS:GetLL_DMS()
|
||||
end
|
||||
|
||||
--- Sets the SETTINGS MGRS accuracy.
|
||||
-- @param #SETTINGS self
|
||||
-- @param #number MGRS_Accuracy
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetMGRS_Accuracy( MGRS_Accuracy )
|
||||
self.MGRS_Accuracy = MGRS_Accuracy
|
||||
end
|
||||
|
||||
--- Gets the SETTINGS MGRS accuracy.
|
||||
-- @param #SETTINGS self
|
||||
-- @return #number
|
||||
function SETTINGS:GetMGRS_Accuracy()
|
||||
return self.MGRS_Accuracy or _SETTINGS:GetMGRS_Accuracy()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets A2G LL
|
||||
-- @param #SETTINGS self
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetA2G_LL()
|
||||
self.A2GSystem = "LL"
|
||||
end
|
||||
|
||||
--- Is LL
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if LL
|
||||
function SETTINGS:IsA2G_LL()
|
||||
return ( self.A2GSystem and self.A2GSystem == "LL" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_LL() )
|
||||
end
|
||||
|
||||
--- Sets A2G MGRS
|
||||
-- @param #SETTINGS self
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetA2G_MGRS()
|
||||
self.A2GSystem = "MGRS"
|
||||
end
|
||||
|
||||
--- Is MGRS
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if MGRS
|
||||
function SETTINGS:IsA2G_MGRS()
|
||||
return ( self.A2GSystem and self.A2GSystem == "MGRS" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_MGRS() )
|
||||
end
|
||||
|
||||
--- Sets A2G BRA
|
||||
-- @param #SETTINGS self
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetA2G_BR()
|
||||
self.A2GSystem = "BR"
|
||||
end
|
||||
|
||||
--- Is BRA
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if BRA
|
||||
function SETTINGS:IsA2G_BR()
|
||||
self:E( { BRA = ( self.A2GSystem and self.A2GSystem == "BR" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_BR() ) } )
|
||||
return ( self.A2GSystem and self.A2GSystem == "BR" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_BR() )
|
||||
end
|
||||
|
||||
--- Sets A2A BRA
|
||||
-- @param #SETTINGS self
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetA2A_BRAA()
|
||||
self.A2ASystem = "BRAA"
|
||||
end
|
||||
|
||||
--- Is BRA
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if BRA
|
||||
function SETTINGS:IsA2A_BRAA()
|
||||
self:E( { BRA = ( self.A2ASystem and self.A2ASystem == "BRAA" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BRAA() ) } )
|
||||
return ( self.A2ASystem and self.A2ASystem == "BRAA" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BRAA() )
|
||||
end
|
||||
|
||||
--- Sets A2A BULLS
|
||||
-- @param #SETTINGS self
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetA2A_BULLS()
|
||||
self.A2ASystem = "BULLS"
|
||||
end
|
||||
|
||||
--- Is BULLS
|
||||
-- @param #SETTINGS self
|
||||
-- @return #boolean true if BULLS
|
||||
function SETTINGS:IsA2A_BULLS()
|
||||
return ( self.A2ASystem and self.A2ASystem == "BULLS" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BULLS() )
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetSystemMenu( MenuGroup, RootMenu )
|
||||
|
||||
local MenuText = "System Settings"
|
||||
|
||||
local MenuTime = timer.getTime()
|
||||
|
||||
local SettingsMenu = MENU_GROUP:New( MenuGroup, MenuText, RootMenu ):SetTime( MenuTime )
|
||||
|
||||
local A2GCoordinateMenu = MENU_GROUP:New( MenuGroup, "A2G Coordinate System", SettingsMenu ):SetTime( MenuTime )
|
||||
|
||||
if self:IsA2G_LL() then
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lattitude Longitude (LL) Accuracy 1", A2GCoordinateMenu, self.MenuLL_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lattitude Longitude (LL) Accuracy 2", A2GCoordinateMenu, self.MenuLL_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lattitude Longitude (LL) Accuracy 3", A2GCoordinateMenu, self.MenuLL_Accuracy, self, MenuGroup, RootMenu, 3 ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lattitude Longitude (LL) Decimal On", A2GCoordinateMenu, self.MenuLL_DMS, self, MenuGroup, RootMenu, true ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lattitude Longitude (LL) Decimal Off", A2GCoordinateMenu, self.MenuLL_DMS, self, MenuGroup, RootMenu, false ):SetTime( MenuTime )
|
||||
end
|
||||
|
||||
if self:IsA2G_MGRS() then
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lattitude Longitude (LL)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL" ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS) Accuracy 1", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS) Accuracy 2", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS) Accuracy 3", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 3 ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS) Accuracy 4", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 4 ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS) Accuracy 5", A2GCoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 5 ):SetTime( MenuTime )
|
||||
end
|
||||
|
||||
if self:IsA2G_BR() then
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Lattitude Longitude (LL)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL" ):SetTime( MenuTime )
|
||||
end
|
||||
|
||||
local A2ACoordinateMenu = MENU_GROUP:New( MenuGroup, "A2A Coordinate System", SettingsMenu ):SetTime( MenuTime )
|
||||
|
||||
if self:IsA2A_BULLS() then
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Bearing Range Altitude Aspect (BRAA)", A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BRAA" ):SetTime( MenuTime )
|
||||
end
|
||||
|
||||
if self:IsA2A_BRAA() then
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Bullseye (BULLS)", A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BULLS" ):SetTime( MenuTime )
|
||||
end
|
||||
|
||||
local MetricsMenu = MENU_GROUP:New( MenuGroup, "Measures and Weights System", SettingsMenu ):SetTime( MenuTime )
|
||||
|
||||
if self:IsMetric() then
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Imperial (Miles,Feet)", MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, false ):SetTime( MenuTime )
|
||||
end
|
||||
|
||||
if self:IsImperial() then
|
||||
MENU_GROUP_COMMAND:New( MenuGroup, "Metric (Kilometers,Meters)", MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, true ):SetTime( MenuTime )
|
||||
end
|
||||
|
||||
SettingsMenu:Remove( MenuTime )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
-- @param RootMenu
|
||||
-- @param Wrapper.Client#CLIENT PlayerUnit
|
||||
-- @param #string MenuText
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:SetPlayerMenu( PlayerUnit )
|
||||
|
||||
local PlayerGroup = PlayerUnit:GetGroup()
|
||||
local PlayerName = PlayerUnit:GetPlayerName()
|
||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||
|
||||
local PlayerMenu = MENU_GROUP:New( PlayerGroup, 'Settings "' .. PlayerName .. '"' )
|
||||
|
||||
self.PlayerMenu = PlayerMenu
|
||||
|
||||
local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2G Coordinate System", PlayerMenu )
|
||||
|
||||
if self:IsA2G_LL() then
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing, Range (BR)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lattitude Longitude (LL) Accuracy 1", A2GCoordinateMenu, self.MenuGroupLL_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lattitude Longitude (LL) Accuracy 2", A2GCoordinateMenu, self.MenuGroupLL_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lattitude Longitude (LL) Accuracy 3", A2GCoordinateMenu, self.MenuGroupLL_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lattitude Longitude (LL) Decimal On", A2GCoordinateMenu, self.MenuGroupLL_DMSSystem, self, PlayerUnit, PlayerGroup, PlayerName, true )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lattitude Longitude (LL) Decimal Off", A2GCoordinateMenu, self.MenuGroupLL_DMSSystem, self, PlayerUnit, PlayerGroup, PlayerName, false )
|
||||
end
|
||||
|
||||
if self:IsA2G_MGRS() then
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing Range (BR)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lattitude Longitude (LL)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL" )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 1", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 2", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 3", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 4", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS) Accuracy 5", A2GCoordinateMenu, self.MenuGroupMGRS_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 5 )
|
||||
end
|
||||
|
||||
if self:IsA2G_BR() then
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Military Grid (MGRS)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Lattitude Longitude (LL)", A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL" )
|
||||
end
|
||||
|
||||
local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, "A2A Coordinate System", PlayerMenu )
|
||||
|
||||
if self:IsA2A_BULLS() then
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Bearing Range Altitude Aspect (BRAA)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" )
|
||||
end
|
||||
|
||||
if self:IsA2A_BRAA() then
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Bullseye (BULLS)", A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" )
|
||||
end
|
||||
|
||||
local MetricsMenu = MENU_GROUP:New( PlayerGroup, "Measures and Weights System", PlayerMenu )
|
||||
|
||||
if self:IsMetric() then
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Imperial (Miles,Feet)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false )
|
||||
end
|
||||
|
||||
if self:IsImperial() then
|
||||
MENU_GROUP_COMMAND:New( PlayerGroup, "Metric (Kilometers,Meters)", MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
-- @param RootMenu
|
||||
-- @param Wrapper.Client#CLIENT PlayerUnit
|
||||
-- @return #SETTINGS
|
||||
function SETTINGS:RemovePlayerMenu( PlayerUnit )
|
||||
|
||||
if self.PlayerMenu then
|
||||
self.PlayerMenu:Remove()
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
|
||||
self.A2GSystem = A2GSystem
|
||||
MESSAGE:New( string.format("Settings: Default A2G coordinate system set to %s for all players!.", A2GSystem ), 5 ):ToAll()
|
||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem )
|
||||
self.A2ASystem = A2ASystem
|
||||
MESSAGE:New( string.format("Settings: Default A2A coordinate system set to %s for all players!.", A2ASystem ), 5 ):ToAll()
|
||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuLL_Accuracy( MenuGroup, RootMenu, LL_Accuracy )
|
||||
self.LL_Accuracy = LL_Accuracy
|
||||
MESSAGE:New( string.format("Settings: Default LL accuracy set to %s for all players!.", LL_Accuracy ), 5 ):ToAll()
|
||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuLL_DMS( MenuGroup, RootMenu, LL_DMS )
|
||||
self.LL_DMS = LL_DMS
|
||||
MESSAGE:New( string.format("Settings: Default LL format set to %s for all players!.", LL_DMS or "Decimal" or "HMS" ), 5 ):ToAll()
|
||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy )
|
||||
self.MGRS_Accuracy = MGRS_Accuracy
|
||||
MESSAGE:New( string.format("Settings: Default MGRS accuracy set to %s for all players!.", MGRS_Accuracy ), 5 ):ToAll()
|
||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW )
|
||||
self.Metric = MW
|
||||
MESSAGE:New( string.format("Settings: Default measurement format set to %s for all players!.", MW and "Metric" or "Imperial" ), 5 ):ToAll()
|
||||
self:SetSystemMenu( MenuGroup, RootMenu )
|
||||
end
|
||||
|
||||
do
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem )
|
||||
BASE:E( {self, PlayerUnit:GetName(), A2GSystem} )
|
||||
self.A2GSystem = A2GSystem
|
||||
MESSAGE:New( string.format("Settings: A2G format set to %s for player %s.", A2GSystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||
self:RemovePlayerMenu(PlayerUnit)
|
||||
self:SetPlayerMenu(PlayerUnit)
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem )
|
||||
self.A2ASystem = A2ASystem
|
||||
MESSAGE:New( string.format("Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||
self:RemovePlayerMenu(PlayerUnit)
|
||||
self:SetPlayerMenu(PlayerUnit)
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuGroupLL_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy )
|
||||
self.LL_Accuracy = LL_Accuracy
|
||||
MESSAGE:New( string.format("Settings: A2G LL format accuracy set to %d for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||
self:RemovePlayerMenu(PlayerUnit)
|
||||
self:SetPlayerMenu(PlayerUnit)
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuGroupLL_DMSSystem( PlayerUnit, PlayerGroup, PlayerName, LL_DMS )
|
||||
self.LL_DMS = LL_DMS
|
||||
MESSAGE:New( string.format("Settings: A2G LL format mode set to %s for player %s.", LL_DMS and "Decimal" or "HMS", PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||
self:RemovePlayerMenu(PlayerUnit)
|
||||
self:SetPlayerMenu(PlayerUnit)
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy )
|
||||
self.MGRS_Accuracy = MGRS_Accuracy
|
||||
MESSAGE:New( string.format("Settings: A2G MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||
self:RemovePlayerMenu(PlayerUnit)
|
||||
self:SetPlayerMenu(PlayerUnit)
|
||||
end
|
||||
|
||||
--- @param #SETTINGS self
|
||||
function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW )
|
||||
self.Metric = MW
|
||||
MESSAGE:New( string.format("Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup )
|
||||
self:RemovePlayerMenu(PlayerUnit)
|
||||
self:SetPlayerMenu(PlayerUnit)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- (R2.1) **Core** -- Spawn dynamically new STATICs in your missions.
|
||||
--- **Core** -- Spawn dynamically new STATICs in your missions.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -24,24 +24,10 @@
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming
|
||||
-- ====
|
||||
--
|
||||
-- @module SpawnStatic
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
--- **Core 2.1** -- Management of SPOT logistics, that can be transported from and to transportation carriers.
|
||||
--- **Core** -- Management of SPOT logistics, that can be transported from and to transportation carriers.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- SPOT implements the DCS Spot class functionality, but adds additional luxury to be able to:
|
||||
--
|
||||
@@ -27,20 +27,16 @@
|
||||
--
|
||||
-- ### [SPOT YouTube Channel]()
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * [**Ciribob**](https://forums.eagle.ru/member.php?u=112175): Showing the way how to lase targets + how laser codes work!!! Explained the autolase script.
|
||||
-- * [**EasyEB**](https://forums.eagle.ru/member.php?u=112055): Ideas and Beta Testing
|
||||
-- * [**Wingthor**](https://forums.eagle.ru/member.php?u=123698): Beta Testing
|
||||
--
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming
|
||||
-- ====
|
||||
--
|
||||
-- @module Spot
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
--- **Core** - ZONE classes define **zones** within your mission of **various forms**, with **various capabilities**.
|
||||
--- **Core** -- ZONE classes define **zones** within your mission of **various forms**, with **various capabilities**.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- There are essentially two core functions that zones accomodate:
|
||||
--
|
||||
@@ -27,41 +27,12 @@
|
||||
-- * @{#ZONE_GROUP}: The ZONE_GROUP class defines by a zone around a @{Group#GROUP} with a radius.
|
||||
-- * @{#ZONE_POLYGON}: The ZONE_POLYGON class defines by a sequence of @{Group#GROUP} waypoints within the Mission Editor, forming a polygon.
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-02-28: ZONE\_BASE:**IsVec2InZone()** replaces ZONE\_BASE:_IsPointVec2InZone()_.
|
||||
-- 2017-02-28: ZONE\_BASE:**IsVec3InZone()** replaces ZONE\_BASE:_IsPointVec3InZone()_.
|
||||
-- 2017-02-28: ZONE\_RADIUS:**IsVec2InZone()** replaces ZONE\_RADIUS:_IsPointVec2InZone()_.
|
||||
-- 2017-02-28: ZONE\_RADIUS:**IsVec3InZone()** replaces ZONE\_RADIUS:_IsPointVec3InZone()_.
|
||||
-- 2017-02-28: ZONE\_POLYGON:**IsVec2InZone()** replaces ZONE\_POLYGON:_IsPointVec2InZone()_.
|
||||
-- 2017-02-28: ZONE\_POLYGON:**IsVec3InZone()** replaces ZONE\_POLYGON:_IsPointVec3InZone()_.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_POLYGON_BASE:**GetRandomPointVec2()** added.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_POLYGON_BASE:**GetRandomPointVec3()** added.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_RADIUS:**GetRandomPointVec3( inner, outer )** added.
|
||||
--
|
||||
-- 2017-02-18: ZONE\_RADIUS:**GetRandomPointVec2( inner, outer )** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**GetName()** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**SetZoneProbability( ZoneProbability )** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**GetZoneProbability()** added.
|
||||
--
|
||||
-- 2016-08-15: ZONE\_BASE:**GetZoneMaybe()** added.
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- @module Zone
|
||||
|
||||
@@ -225,7 +196,6 @@ end
|
||||
|
||||
--- Returns a @{Point#COORDINATE} of the zone.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param Dcs.DCSTypes#Distance Height The height to add to the land height where the center of the zone is located.
|
||||
-- @return Core.Point#COORDINATE The Coordinate of the zone.
|
||||
function ZONE_BASE:GetCoordinate()
|
||||
self:F2( self.ZoneName )
|
||||
@@ -251,7 +221,7 @@ function ZONE_BASE:GetVec3( Height )
|
||||
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
local Vec3 = { x = Vec2.x, y = land.getHeight( self:GetVec2() ) + Height, z = Vec2.y }
|
||||
local Vec3 = { x = Vec2.x, y = Height and Height or land.getHeight( self:GetVec2() ), z = Vec2.y }
|
||||
|
||||
self:T2( { Vec3 } )
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- This module contains the AIRBASEPOLICE classes.
|
||||
--- **Functional** -- This module monitors airbases traffic.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
|
||||
@@ -1,135 +1,234 @@
|
||||
--- The CLEANUP class keeps an area clean of crashing or colliding airplanes. It also prevents airplanes from firing within this area.
|
||||
--- **Functional** -- The CLEANUP_AIRBASE class keeps an area clean of crashing or colliding airplanes. It also prevents airplanes from firing within this area.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module CleanUp
|
||||
-- @author Flightcontrol
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- The CLEANUP class.
|
||||
-- @type CLEANUP
|
||||
--- @type CLEANUP_AIRBASE.__ Methods which are not intended for mission designers, but which are used interally by the moose designer :-)
|
||||
-- @field #map<#string,Wrapper.Airbase#AIRBASE> Airbases Map of Airbases.
|
||||
-- @extends Core.Base#BASE
|
||||
CLEANUP = {
|
||||
ClassName = "CLEANUP",
|
||||
ZoneNames = {},
|
||||
TimeInterval = 300,
|
||||
|
||||
--- @type CLEANUP_AIRBASE
|
||||
-- @extends #CLEANUP_AIRBASE.__
|
||||
|
||||
--- # CLEANUP_AIRBASE, extends @{Base#BASE}
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The CLEANUP_AIRBASE class keeps airbases clean, and tries to guarantee continuous airbase operations, even under combat.
|
||||
-- Specific airbases need to be provided that need to be guarded. Each airbase registered, will be guarded within a zone of 8 km around the airbase.
|
||||
-- Any unit that fires a missile, or shoots within the zone of an airbase, will be monitored by CLEANUP_AIRBASE.
|
||||
-- Within the 8km zone, units cannot fire any missile, which prevents the airbase runway to receive missile or bomb hits.
|
||||
-- Any airborne or ground unit that is on the runway below 30 meters (default value) will be automatically removed if it is damaged.
|
||||
--
|
||||
-- This is not a full 100% secure implementation. It is still possible that CLEANUP_AIRBASE cannot prevent (in-time) to keep the airbase clean.
|
||||
-- The following situations may happen that will still stop the runway of an airbase:
|
||||
--
|
||||
-- * A damaged unit is not removed on time when above the runway, and crashes on the runway.
|
||||
-- * A bomb or missile is still able to dropped on the runway.
|
||||
-- * Units collide on the airbase, and could not be removed on time.
|
||||
--
|
||||
-- When a unit is within the airbase zone and needs to be monitored,
|
||||
-- its status will be checked every 0.25 seconds! This is required to ensure that the airbase is kept clean.
|
||||
-- But as a result, there is more CPU overload.
|
||||
--
|
||||
-- So as an advise, I suggest you use the CLEANUP_AIRBASE class with care:
|
||||
--
|
||||
-- * Only monitor airbases that really need to be monitored!
|
||||
-- * Try not to monitor airbases that are likely to be invaded by enemy troops.
|
||||
-- For these airbases, there is little use to keep them clean, as they will be invaded anyway...
|
||||
--
|
||||
-- By following the above guidelines, you can add airbase cleanup with acceptable CPU overhead.
|
||||
--
|
||||
-- ## 1. CLEANUP_AIRBASE Constructor
|
||||
--
|
||||
-- Creates the main object which is preventing the airbase to get polluted with debris on the runway, which halts the airbase.
|
||||
--
|
||||
-- -- Clean these Zones.
|
||||
-- CleanUpAirports = CLEANUP_AIRBASE:New( { AIRBASE.Caucasus.Tbilisi, AIRBASE.Caucasus.Kutaisi )
|
||||
--
|
||||
-- -- or
|
||||
-- CleanUpTbilisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Tbilisi )
|
||||
-- CleanUpKutaisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Kutaisi )
|
||||
--
|
||||
-- ## 2. Add or Remove airbases
|
||||
--
|
||||
-- The method @{#CLEANUP_AIRBASE.AddAirbase}() to add an airbase to the cleanup validation process.
|
||||
-- The method @{#CLEANUP_AIRBASE.RemoveAirbase}() removes an airbase from the cleanup validation process.
|
||||
--
|
||||
-- ## 3. Clean missiles and bombs within the airbase zone.
|
||||
--
|
||||
-- When missiles or bombs hit the runway, the airbase operations stop.
|
||||
-- Use the method @{#CLEANUP_AIRBASE.SetCleanMissiles}() to control the cleaning of missiles, which will prevent airbases to stop.
|
||||
-- Note that this method will not allow anymore airbases to be attacked, so there is a trade-off here to do.
|
||||
--
|
||||
-- @field #CLEANUP_AIRBASE
|
||||
CLEANUP_AIRBASE = {
|
||||
ClassName = "CLEANUP_AIRBASE",
|
||||
TimeInterval = 0.2,
|
||||
CleanUpList = {},
|
||||
}
|
||||
|
||||
-- @field #CLEANUP_AIRBASE.__
|
||||
CLEANUP_AIRBASE.__ = {}
|
||||
|
||||
--- @field #CLEANUP_AIRBASE.__.Airbases
|
||||
CLEANUP_AIRBASE.__.Airbases = {}
|
||||
|
||||
--- Creates the main object which is handling the cleaning of the debris within the given Zone Names.
|
||||
-- @param #CLEANUP self
|
||||
-- @param #table ZoneNames Is a table of zone names where the debris should be cleaned. Also a single string can be passed with one zone name.
|
||||
-- @param #number TimeInterval The interval in seconds when the clean activity takes place. The default is 300 seconds, thus every 5 minutes.
|
||||
-- @return #CLEANUP
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param #list<#string> AirbaseNames Is a table of airbase names where the debris should be cleaned. Also a single string can be passed with one airbase name.
|
||||
-- @return #CLEANUP_AIRBASE
|
||||
-- @usage
|
||||
-- -- Clean these Zones.
|
||||
-- CleanUpAirports = CLEANUP:New( { 'CLEAN Tbilisi', 'CLEAN Kutaisi' }, 150 )
|
||||
-- CleanUpAirports = CLEANUP_AIRBASE:New( { AIRBASE.Caucasus.Tbilisi, AIRBASE.Caucasus.Kutaisi )
|
||||
-- or
|
||||
-- CleanUpTbilisi = CLEANUP:New( 'CLEAN Tbilisi', 150 )
|
||||
-- CleanUpKutaisi = CLEANUP:New( 'CLEAN Kutaisi', 600 )
|
||||
function CLEANUP:New( ZoneNames, TimeInterval )
|
||||
-- CleanUpTbilisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Tbilisi )
|
||||
-- CleanUpKutaisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Kutaisi )
|
||||
function CLEANUP_AIRBASE:New( AirbaseNames )
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() ) -- #CLEANUP
|
||||
self:F( { ZoneNames, TimeInterval } )
|
||||
local self = BASE:Inherit( self, BASE:New() ) -- #CLEANUP_AIRBASE
|
||||
self:F( { AirbaseNames } )
|
||||
|
||||
if type( ZoneNames ) == 'table' then
|
||||
self.ZoneNames = ZoneNames
|
||||
if type( AirbaseNames ) == 'table' then
|
||||
for AirbaseID, AirbaseName in pairs( AirbaseNames ) do
|
||||
self:AddAirbase( AirbaseName )
|
||||
end
|
||||
else
|
||||
self.ZoneNames = { ZoneNames }
|
||||
end
|
||||
if TimeInterval then
|
||||
self.TimeInterval = TimeInterval
|
||||
local AirbaseName = AirbaseNames
|
||||
self:AddAirbase( AirbaseName )
|
||||
end
|
||||
|
||||
self:HandleEvent( EVENTS.Birth )
|
||||
self:HandleEvent( EVENTS.Birth, self.__.OnEventBirth )
|
||||
|
||||
self.CleanUpScheduler = SCHEDULER:New( self, self._CleanUpScheduler, {}, 1, TimeInterval )
|
||||
self.__.CleanUpScheduler = SCHEDULER:New( self, self.__.CleanUpSchedule, {}, 1, self.TimeInterval )
|
||||
|
||||
self:HandleEvent( EVENTS.EngineShutdown , self.__.EventAddForCleanUp )
|
||||
self:HandleEvent( EVENTS.EngineStartup, self.__.EventAddForCleanUp )
|
||||
self:HandleEvent( EVENTS.Hit, self.__.EventAddForCleanUp )
|
||||
self:HandleEvent( EVENTS.PilotDead, self.__.OnEventCrash )
|
||||
self:HandleEvent( EVENTS.Dead, self.__.OnEventCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self.__.OnEventCrash )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Destroys a group from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP self
|
||||
-- @param Dcs.DCSWrapper.Group#Group GroupObject The object to be destroyed.
|
||||
-- @param #string CleanUpGroupName The groupname...
|
||||
function CLEANUP:_DestroyGroup( GroupObject, CleanUpGroupName )
|
||||
self:F( { GroupObject, CleanUpGroupName } )
|
||||
|
||||
if GroupObject then -- and GroupObject:isExist() then
|
||||
trigger.action.deactivateGroup(GroupObject)
|
||||
self:T( { "GroupObject Destroyed", GroupObject } )
|
||||
end
|
||||
--- Adds an airbase to the airbase validation list.
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param #string AirbaseName
|
||||
-- @return #CLEANUP_AIRBASE
|
||||
function CLEANUP_AIRBASE:AddAirbase( AirbaseName )
|
||||
self.__.Airbases[AirbaseName] = AIRBASE:FindByName( AirbaseName )
|
||||
self:F({"Airbase:", AirbaseName, self.__.Airbases[AirbaseName]:GetDesc()})
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Destroys a @{DCSWrapper.Unit#Unit} from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP self
|
||||
-- @param Dcs.DCSWrapper.Unit#Unit CleanUpUnit The object to be destroyed.
|
||||
-- @param #string CleanUpUnitName The Unit name ...
|
||||
function CLEANUP:_DestroyUnit( CleanUpUnit, CleanUpUnitName )
|
||||
self:F( { CleanUpUnit, CleanUpUnitName } )
|
||||
--- Removes an airbase from the airbase validation list.
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param #string AirbaseName
|
||||
-- @return #CLEANUP_AIRBASE
|
||||
function CLEANUP_AIRBASE:RemoveAirbase( AirbaseName )
|
||||
self.__.Airbases[AirbaseName] = nil
|
||||
return self
|
||||
end
|
||||
|
||||
--- Enables or disables the cleaning of missiles within the airbase zones.
|
||||
-- Airbase operations stop when a missile or bomb is dropped at a runway.
|
||||
-- Note that when this method is used, the airbase operations won't stop if
|
||||
-- the missile or bomb was cleaned within the airbase zone, which is 8km from the center of the airbase.
|
||||
-- However, there is a trade-off to make. Attacks on airbases won't be possible anymore if this method is used.
|
||||
-- Note, one can also use the method @{#CLEANUP_AIRBASE.RemoveAirbase}() to remove the airbase from the control process as a whole,
|
||||
-- when an enemy unit is near. That is also an option...
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param #string CleanMissiles (Default=true) If true, missiles fired are immediately destroyed. If false missiles are not controlled.
|
||||
-- @return #CLEANUP_AIRBASE
|
||||
function CLEANUP_AIRBASE:SetCleanMissiles( CleanMissiles )
|
||||
|
||||
if CleanMissiles then
|
||||
self:HandleEvent( EVENTS.Shot, self.__.OnEventShot )
|
||||
else
|
||||
self:UnHandleEvent( EVENTS.Shot )
|
||||
end
|
||||
end
|
||||
|
||||
function CLEANUP_AIRBASE.__:IsInAirbase( Vec2 )
|
||||
|
||||
local InAirbase = false
|
||||
for AirbaseName, Airbase in pairs( self.__.Airbases ) do
|
||||
local Airbase = Airbase -- Wrapper.Airbase#AIRBASE
|
||||
if Airbase:GetZone():IsVec2InZone( Vec2 ) then
|
||||
InAirbase = true
|
||||
break;
|
||||
end
|
||||
end
|
||||
|
||||
return InAirbase
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Destroys a @{Unit} from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param Wrapper.Unit#UNIT CleanUpUnit The object to be destroyed.
|
||||
function CLEANUP_AIRBASE.__:DestroyUnit( CleanUpUnit )
|
||||
self:F( { CleanUpUnit } )
|
||||
|
||||
if CleanUpUnit then
|
||||
local CleanUpGroup = Unit.getGroup(CleanUpUnit)
|
||||
local CleanUpUnitName = CleanUpUnit:GetName()
|
||||
local CleanUpGroup = CleanUpUnit:GetGroup()
|
||||
-- TODO Client bug in 1.5.3
|
||||
if CleanUpGroup and CleanUpGroup:isExist() then
|
||||
local CleanUpGroupUnits = CleanUpGroup:getUnits()
|
||||
if CleanUpGroup:IsAlive() then
|
||||
local CleanUpGroupUnits = CleanUpGroup:GetUnits()
|
||||
if #CleanUpGroupUnits == 1 then
|
||||
local CleanUpGroupName = CleanUpGroup:getName()
|
||||
--self:CreateEventCrash( timer.getTime(), CleanUpUnit )
|
||||
CleanUpGroup:destroy()
|
||||
self:T( { "Destroyed Group:", CleanUpGroupName } )
|
||||
local CleanUpGroupName = CleanUpGroup:GetName()
|
||||
CleanUpGroup:Destroy()
|
||||
else
|
||||
CleanUpUnit:destroy()
|
||||
self:T( { "Destroyed Unit:", CleanUpUnitName } )
|
||||
CleanUpUnit:Destroy()
|
||||
end
|
||||
self.CleanUpList[CleanUpUnitName] = nil -- Cleaning from the list
|
||||
CleanUpUnit = nil
|
||||
self.CleanUpList[CleanUpUnitName] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO check Dcs.DCSTypes#Weapon
|
||||
--- Destroys a missile from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP self
|
||||
-- @param Dcs.DCSTypes#Weapon MissileObject
|
||||
function CLEANUP:_DestroyMissile( MissileObject )
|
||||
self:F( { MissileObject } )
|
||||
|
||||
|
||||
--- Destroys a missile from the simulator, but checks first if it is still existing!
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param Dcs.DCSTypes#Weapon MissileObject
|
||||
function CLEANUP_AIRBASE.__:DestroyMissile( MissileObject )
|
||||
self:F( { MissileObject } )
|
||||
|
||||
if MissileObject and MissileObject:isExist() then
|
||||
MissileObject:destroy()
|
||||
self:T( "MissileObject Destroyed")
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #CLEANUP self
|
||||
--- @param #CLEANUP_AIRBASE self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CLEANUP:_OnEventBirth( EventData )
|
||||
function CLEANUP_AIRBASE.__:OnEventBirth( EventData )
|
||||
self:F( { EventData } )
|
||||
|
||||
self.CleanUpList[EventData.IniDCSUnitName] = {}
|
||||
self.CleanUpList[EventData.IniDCSUnitName].CleanUpUnit = EventData.IniDCSUnit
|
||||
self.CleanUpList[EventData.IniDCSUnitName].CleanUpGroup = EventData.IniDCSGroup
|
||||
self.CleanUpList[EventData.IniDCSUnitName].CleanUpUnit = EventData.IniUnit
|
||||
self.CleanUpList[EventData.IniDCSUnitName].CleanUpGroup = EventData.IniGroup
|
||||
self.CleanUpList[EventData.IniDCSUnitName].CleanUpGroupName = EventData.IniDCSGroupName
|
||||
self.CleanUpList[EventData.IniDCSUnitName].CleanUpUnitName = EventData.IniDCSUnitName
|
||||
|
||||
EventData.IniUnit:HandleEvent( EVENTS.EngineShutdown , self._EventAddForCleanUp )
|
||||
EventData.IniUnit:HandleEvent( EVENTS.EngineStartup, self._EventAddForCleanUp )
|
||||
EventData.IniUnit:HandleEvent( EVENTS.Hit, self._EventAddForCleanUp )
|
||||
EventData.IniUnit:HandleEvent( EVENTS.PilotDead, self._EventCrash )
|
||||
EventData.IniUnit:HandleEvent( EVENTS.Dead, self._EventCrash )
|
||||
EventData.IniUnit:HandleEvent( EVENTS.Crash, self._EventCrash )
|
||||
EventData.IniUnit:HandleEvent( EVENTS.Shot, self._EventShot )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Detects if a crash event occurs.
|
||||
-- Crashed units go into a CleanUpList for removal.
|
||||
-- @param #CLEANUP self
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventCrash( Event )
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function CLEANUP_AIRBASE.__:OnEventCrash( Event )
|
||||
self:F( { Event } )
|
||||
|
||||
--TODO: This stuff is not working due to a DCS bug. Burning units cannot be destroyed.
|
||||
@@ -140,171 +239,164 @@ function CLEANUP:_EventCrash( Event )
|
||||
-- self:T("after deactivateGroup")
|
||||
-- event.initiator:destroy()
|
||||
|
||||
self.CleanUpList[Event.IniDCSUnitName] = {}
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniDCSUnit
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniDCSGroup
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName
|
||||
if Event.IniDCSUnitName and Event.IniCategory == Object.Category.UNIT then
|
||||
self.CleanUpList[Event.IniDCSUnitName] = {}
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpUnit = Event.IniUnit
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpGroup = Event.IniGroup
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpGroupName = Event.IniDCSGroupName
|
||||
self.CleanUpList[Event.IniDCSUnitName].CleanUpUnitName = Event.IniDCSUnitName
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Detects if a unit shoots a missile.
|
||||
-- If this occurs within one of the zones, then the weapon used must be destroyed.
|
||||
-- @param #CLEANUP self
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventShot( Event )
|
||||
-- If this occurs within one of the airbases, then the weapon used must be destroyed.
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function CLEANUP_AIRBASE.__:OnEventShot( Event )
|
||||
self:F( { Event } )
|
||||
|
||||
-- Test if the missile was fired within one of the CLEANUP.ZoneNames.
|
||||
local CurrentLandingZoneID = 0
|
||||
CurrentLandingZoneID = routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames )
|
||||
if ( CurrentLandingZoneID ) then
|
||||
-- Okay, the missile was fired within the CLEANUP.ZoneNames, destroy the fired weapon.
|
||||
--_SEADmissile:destroy()
|
||||
SCHEDULER:New( self, CLEANUP._DestroyMissile, { Event.Weapon }, 0.1 )
|
||||
-- Test if the missile was fired within one of the CLEANUP_AIRBASE.AirbaseNames.
|
||||
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
|
||||
-- Okay, the missile was fired within the CLEANUP_AIRBASE.AirbaseNames, destroy the fired weapon.
|
||||
self:DestroyMissile( Event.Weapon )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Detects if the Unit has an S_EVENT_HIT within the given ZoneNames. If this is the case, destroy the unit.
|
||||
-- @param #CLEANUP self
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventHitCleanUp( Event )
|
||||
--- Detects if the Unit has an S_EVENT_HIT within the given AirbaseNames. If this is the case, destroy the unit.
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function CLEANUP_AIRBASE.__:OnEventHit( Event )
|
||||
self:F( { Event } )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
if routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) ~= nil then
|
||||
self:T( { "Life: ", Event.IniDCSUnitName, ' = ', Event.IniDCSUnit:getLife(), "/", Event.IniDCSUnit:getLife0() } )
|
||||
if Event.IniDCSUnit:getLife() < Event.IniDCSUnit:getLife0() then
|
||||
if Event.IniUnit then
|
||||
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
|
||||
self:T( { "Life: ", Event.IniDCSUnitName, ' = ', Event.IniUnit:GetLife(), "/", Event.IniUnit:GetLife0() } )
|
||||
if Event.IniUnit:GetLife() < Event.IniUnit:GetLife0() then
|
||||
self:T( "CleanUp: Destroy: " .. Event.IniDCSUnitName )
|
||||
SCHEDULER:New( self, CLEANUP._DestroyUnit, { Event.IniDCSUnit }, 0.1 )
|
||||
CLEANUP_AIRBASE.__:DestroyUnit( Event.IniUnit )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Event.TgtDCSUnit then
|
||||
if routines.IsUnitInZones( Event.TgtDCSUnit, self.ZoneNames ) ~= nil then
|
||||
self:T( { "Life: ", Event.TgtDCSUnitName, ' = ', Event.TgtDCSUnit:getLife(), "/", Event.TgtDCSUnit:getLife0() } )
|
||||
if Event.TgtDCSUnit:getLife() < Event.TgtDCSUnit:getLife0() then
|
||||
if Event.TgtUnit then
|
||||
if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then
|
||||
self:T( { "Life: ", Event.TgtDCSUnitName, ' = ', Event.TgtUnit:GetLife(), "/", Event.TgtUnit:GetLife0() } )
|
||||
if Event.TgtUnit:GetLife() < Event.TgtUnit:GetLife0() then
|
||||
self:T( "CleanUp: Destroy: " .. Event.TgtDCSUnitName )
|
||||
SCHEDULER:New( self, CLEANUP._DestroyUnit, { Event.TgtDCSUnit }, 0.1 )
|
||||
CLEANUP_AIRBASE.__:DestroyUnit( Event.TgtUnit )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Add the @{DCSWrapper.Unit#Unit} to the CleanUpList for CleanUp.
|
||||
function CLEANUP:_AddForCleanUp( CleanUpUnit, CleanUpUnitName )
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
-- @param Wrapper.Unit#UNIT CleanUpUnit
|
||||
-- @oaram #string CleanUpUnitName
|
||||
function CLEANUP_AIRBASE.__:AddForCleanUp( CleanUpUnit, CleanUpUnitName )
|
||||
self:F( { CleanUpUnit, CleanUpUnitName } )
|
||||
|
||||
self.CleanUpList[CleanUpUnitName] = {}
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpUnit = CleanUpUnit
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpUnitName = CleanUpUnitName
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpGroup = Unit.getGroup(CleanUpUnit)
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpGroupName = Unit.getGroup(CleanUpUnit):getName()
|
||||
|
||||
local CleanUpGroup = CleanUpUnit:GetGroup()
|
||||
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpGroup = CleanUpGroup
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpGroupName = CleanUpGroup:GetName()
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpTime = timer.getTime()
|
||||
self.CleanUpList[CleanUpUnitName].CleanUpMoved = false
|
||||
|
||||
self:T( { "CleanUp: Add to CleanUpList: ", Unit.getGroup(CleanUpUnit):getName(), CleanUpUnitName } )
|
||||
self:T( { "CleanUp: Add to CleanUpList: ", CleanUpGroup:GetName(), CleanUpUnitName } )
|
||||
|
||||
end
|
||||
|
||||
--- Detects if the Unit has an S_EVENT_ENGINE_SHUTDOWN or an S_EVENT_HIT within the given ZoneNames. If this is the case, add the Group to the CLEANUP List.
|
||||
-- @param #CLEANUP self
|
||||
-- @param Dcs.DCSTypes#Event event
|
||||
function CLEANUP:_EventAddForCleanUp( Event )
|
||||
--- Detects if the Unit has an S_EVENT_ENGINE_SHUTDOWN or an S_EVENT_HIT within the given AirbaseNames. If this is the case, add the Group to the CLEANUP_AIRBASE List.
|
||||
-- @param #CLEANUP_AIRBASE.__ self
|
||||
-- @param Core.Event#EVENTDATA Event
|
||||
function CLEANUP_AIRBASE.__:EventAddForCleanUp( Event )
|
||||
|
||||
if Event.IniDCSUnit then
|
||||
self:F({Event})
|
||||
|
||||
|
||||
if Event.IniDCSUnit and Event.IniCategory == Object.Category.UNIT then
|
||||
if self.CleanUpList[Event.IniDCSUnitName] == nil then
|
||||
if routines.IsUnitInZones( Event.IniDCSUnit, self.ZoneNames ) ~= nil then
|
||||
self:_AddForCleanUp( Event.IniDCSUnit, Event.IniDCSUnitName )
|
||||
if self:IsInAirbase( Event.IniUnit:GetVec2() ) then
|
||||
self:AddForCleanUp( Event.IniUnit, Event.IniDCSUnitName )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Event.TgtDCSUnit then
|
||||
if Event.TgtDCSUnit and Event.TgtCategory == Object.Category.UNIT then
|
||||
if self.CleanUpList[Event.TgtDCSUnitName] == nil then
|
||||
if routines.IsUnitInZones( Event.TgtDCSUnit, self.ZoneNames ) ~= nil then
|
||||
self:_AddForCleanUp( Event.TgtDCSUnit, Event.TgtDCSUnitName )
|
||||
if self:IsInAirbase( Event.TgtUnit:GetVec2() ) then
|
||||
self:AddForCleanUp( Event.TgtUnit, Event.TgtDCSUnitName )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local CleanUpSurfaceTypeText = {
|
||||
"LAND",
|
||||
"SHALLOW_WATER",
|
||||
"WATER",
|
||||
"ROAD",
|
||||
"RUNWAY"
|
||||
}
|
||||
|
||||
--- At the defined time interval, CleanUp the Groups within the CleanUpList.
|
||||
-- @param #CLEANUP self
|
||||
function CLEANUP:_CleanUpScheduler()
|
||||
self:F( { "CleanUp Scheduler" } )
|
||||
-- @param #CLEANUP_AIRBASE self
|
||||
function CLEANUP_AIRBASE.__:CleanUpSchedule()
|
||||
|
||||
local CleanUpCount = 0
|
||||
for CleanUpUnitName, UnitData in pairs( self.CleanUpList ) do
|
||||
for CleanUpUnitName, CleanUpListData in pairs( self.CleanUpList ) do
|
||||
CleanUpCount = CleanUpCount + 1
|
||||
|
||||
self:T( { CleanUpUnitName, UnitData } )
|
||||
local CleanUpUnit = Unit.getByName(UnitData.CleanUpUnitName)
|
||||
local CleanUpGroupName = UnitData.CleanUpGroupName
|
||||
local CleanUpUnitName = UnitData.CleanUpUnitName
|
||||
if CleanUpUnit then
|
||||
self:T( { "CleanUp Scheduler", "Checking:", CleanUpUnitName } )
|
||||
local CleanUpUnit = CleanUpListData.CleanUpUnit -- Wrapper.Unit#UNIT
|
||||
local CleanUpGroupName = CleanUpListData.CleanUpGroupName
|
||||
|
||||
if CleanUpUnit:IsAlive() ~= nil then
|
||||
|
||||
if _DATABASE:GetStatusGroup( CleanUpGroupName ) ~= "ReSpawn" then
|
||||
local CleanUpUnitVec3 = CleanUpUnit:getPoint()
|
||||
--self:T( CleanUpUnitVec3 )
|
||||
local CleanUpUnitVec2 = {}
|
||||
CleanUpUnitVec2.x = CleanUpUnitVec3.x
|
||||
CleanUpUnitVec2.y = CleanUpUnitVec3.z
|
||||
--self:T( CleanUpUnitVec2 )
|
||||
local CleanUpSurfaceType = land.getSurfaceType(CleanUpUnitVec2)
|
||||
--self:T( CleanUpSurfaceType )
|
||||
|
||||
if CleanUpUnit and CleanUpUnit:getLife() <= CleanUpUnit:getLife0() * 0.95 then
|
||||
if CleanUpSurfaceType == land.SurfaceType.RUNWAY then
|
||||
if CleanUpUnit:inAir() then
|
||||
local CleanUpLandHeight = land.getHeight(CleanUpUnitVec2)
|
||||
local CleanUpUnitHeight = CleanUpUnitVec3.y - CleanUpLandHeight
|
||||
self:T( { "CleanUp Scheduler", "Height = " .. CleanUpUnitHeight } )
|
||||
if CleanUpUnitHeight < 30 then
|
||||
|
||||
local CleanUpCoordinate = CleanUpUnit:GetCoordinate()
|
||||
|
||||
self:T( { "CleanUp Scheduler", CleanUpUnitName } )
|
||||
if CleanUpUnit:GetLife() <= CleanUpUnit:GetLife0() * 0.95 then
|
||||
if CleanUpUnit:IsAboveRunway() then
|
||||
if CleanUpUnit:InAir() then
|
||||
|
||||
local CleanUpLandHeight = CleanUpCoordinate:GetLandHeight()
|
||||
local CleanUpUnitHeight = CleanUpCoordinate.y - CleanUpLandHeight
|
||||
|
||||
if CleanUpUnitHeight < 100 then
|
||||
self:T( { "CleanUp Scheduler", "Destroy " .. CleanUpUnitName .. " because below safe height and damaged." } )
|
||||
self:_DestroyUnit(CleanUpUnit, CleanUpUnitName)
|
||||
self:DestroyUnit( CleanUpUnit )
|
||||
end
|
||||
else
|
||||
self:T( { "CleanUp Scheduler", "Destroy " .. CleanUpUnitName .. " because on runway and damaged." } )
|
||||
self:_DestroyUnit(CleanUpUnit, CleanUpUnitName)
|
||||
self:DestroyUnit( CleanUpUnit )
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Clean Units which are waiting for a very long time in the CleanUpZone.
|
||||
if CleanUpUnit then
|
||||
local CleanUpUnitVelocity = CleanUpUnit:getVelocity()
|
||||
local CleanUpUnitVelocityTotal = math.abs(CleanUpUnitVelocity.x) + math.abs(CleanUpUnitVelocity.y) + math.abs(CleanUpUnitVelocity.z)
|
||||
if CleanUpUnitVelocityTotal < 1 then
|
||||
if UnitData.CleanUpMoved then
|
||||
if UnitData.CleanUpTime + 180 <= timer.getTime() then
|
||||
local CleanUpUnitVelocity = CleanUpUnit:GetVelocityKMH()
|
||||
if CleanUpUnitVelocity < 1 then
|
||||
if CleanUpListData.CleanUpMoved then
|
||||
if CleanUpListData.CleanUpTime + 180 <= timer.getTime() then
|
||||
self:T( { "CleanUp Scheduler", "Destroy due to not moving anymore " .. CleanUpUnitName } )
|
||||
self:_DestroyUnit(CleanUpUnit, CleanUpUnitName)
|
||||
self:DestroyUnit( CleanUpUnit )
|
||||
end
|
||||
end
|
||||
else
|
||||
UnitData.CleanUpTime = timer.getTime()
|
||||
UnitData.CleanUpMoved = true
|
||||
CleanUpListData.CleanUpTime = timer.getTime()
|
||||
CleanUpListData.CleanUpMoved = true
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
-- Do nothing ...
|
||||
self.CleanUpList[CleanUpUnitName] = nil -- Not anymore in the DCSRTE
|
||||
self.CleanUpList[CleanUpUnitName] = nil
|
||||
end
|
||||
else
|
||||
self:T( "CleanUp: Group " .. CleanUpUnitName .. " cannot be found in DCS RTE, removing ..." )
|
||||
self.CleanUpList[CleanUpUnitName] = nil -- Not anymore in the DCSRTE
|
||||
self.CleanUpList[CleanUpUnitName] = nil
|
||||
end
|
||||
end
|
||||
self:T(CleanUpCount)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Funtional R2.1** -- Management of target **Designation**.
|
||||
--- **Functional** -- Management of target **Designation**.
|
||||
--
|
||||
-- --
|
||||
--
|
||||
@@ -538,7 +538,7 @@ do -- DESIGNATE
|
||||
|
||||
for Index, DetectedItemData in pairs( DetectedItems ) do
|
||||
|
||||
local Report = self.Detection:DetectedItemReportSummary( Index )
|
||||
local Report = self.Detection:DetectedItemReportSummary( Index, AttackGroup )
|
||||
DetectedReport:Add(" - " .. Report)
|
||||
end
|
||||
|
||||
@@ -639,7 +639,7 @@ do -- DESIGNATE
|
||||
|
||||
for Index, DetectedItemData in pairs( DetectedItems ) do
|
||||
|
||||
local Report = self.Detection:DetectedItemMenu( Index )
|
||||
local Report = self.Detection:DetectedItemMenu( Index, AttackGroup )
|
||||
|
||||
if not self.Designating[Index] then
|
||||
local DetectedMenu = MENU_GROUP:New( AttackGroup, Report, DesignateMenu )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Functional** - DETECTION_ classes model the detection of enemy units by FACs or RECCEs and group them according various methods.
|
||||
--- **Functional** -- DETECTION_ classes model the detection of enemy units by FACs or RECCEs and group them according various methods.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -37,6 +37,10 @@
|
||||
--
|
||||
-- @module Detection
|
||||
|
||||
----BASE:TraceClass("DETECTION_BASE")
|
||||
----BASE:TraceClass("DETECTION_AREAS")
|
||||
----BASE:TraceClass("DETECTION_UNITS")
|
||||
----BASE:TraceClass("DETECTION_TYPES")
|
||||
|
||||
do -- DETECTION_BASE
|
||||
|
||||
@@ -239,6 +243,11 @@ do -- DETECTION_BASE
|
||||
--
|
||||
-- -- Start the Detection.
|
||||
-- Detection:Start()
|
||||
--
|
||||
-- ## Detection of Friendlies Nearby
|
||||
--
|
||||
-- Use the method @{Detection#DETECTION_BASE.SetFriendliesRange}() to set the range what will indicate when friendlies are nearby
|
||||
-- a DetectedItem. The default range is 6000 meters. For air detections, it is advisory to use about 30.000 meters.
|
||||
--
|
||||
-- ## DETECTION_BASE is a Finite State Machine
|
||||
--
|
||||
@@ -329,6 +338,8 @@ do -- DETECTION_BASE
|
||||
Unit.Category.SHIP,
|
||||
Unit.Category.STRUCTURE
|
||||
} )
|
||||
|
||||
self:SetFriendliesRange( 6000 )
|
||||
|
||||
-- Create FSM transitions.
|
||||
|
||||
@@ -505,18 +516,20 @@ do -- DETECTION_BASE
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function DETECTION_BASE:onafterDetect(From,Event,To)
|
||||
self:E( {From,Event,To})
|
||||
self:E( { From, Event, To } )
|
||||
|
||||
local DetectDelay = 0.1
|
||||
self.DetectionCount = 0
|
||||
self.DetectionRun = 0
|
||||
self:UnIdentifyAllDetectedObjects() -- Resets the DetectedObjectsIdentified table
|
||||
|
||||
local DetectionTimeStamp = timer.getTime()
|
||||
|
||||
for DetectionGroupID, DetectionGroupData in pairs( self.DetectionSetGroup:GetSet() ) do
|
||||
self:E( {DetectionGroupData})
|
||||
self:__DetectionGroup( DetectDelay, DetectionGroupData ) -- Process each detection asynchronously.
|
||||
--self:E( { DetectionGroupData } )
|
||||
self:__DetectionGroup( DetectDelay, DetectionGroupData, DetectionTimeStamp ) -- Process each detection asynchronously.
|
||||
self.DetectionCount = self.DetectionCount + 1
|
||||
DetectDelay = DetectDelay + 0.1
|
||||
DetectDelay = DetectDelay + 1
|
||||
end
|
||||
end
|
||||
|
||||
@@ -525,8 +538,8 @@ do -- DETECTION_BASE
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @param Wrapper.Group#GROUP DetectionGroup The Group detecting.
|
||||
function DETECTION_BASE:onafterDetectionGroup( From, Event, To, DetectionGroup )
|
||||
self:E( {From,Event,To})
|
||||
function DETECTION_BASE:onafterDetectionGroup( From, Event, To, DetectionGroup, DetectionTimeStamp )
|
||||
self:E( { From, Event, To } )
|
||||
|
||||
self.DetectionRun = self.DetectionRun + 1
|
||||
|
||||
@@ -550,7 +563,7 @@ do -- DETECTION_BASE
|
||||
self.DetectDLINK
|
||||
)
|
||||
|
||||
self:T( DetectedTargets )
|
||||
self:F( DetectedTargets )
|
||||
|
||||
for DetectionObjectID, Detection in pairs( DetectedTargets ) do
|
||||
local DetectedObject = Detection.object -- Dcs.DCSWrapper.Object#Object
|
||||
@@ -585,7 +598,7 @@ do -- DETECTION_BASE
|
||||
|
||||
local DetectedUnitCategory = DetectedObject:getDesc().category
|
||||
|
||||
self:T2( { "Detected Target:", DetectionGroupName, DetectedObjectName, Distance, DetectedUnitCategory } )
|
||||
self:F( { "Detected Target:", DetectionGroupName, DetectedObjectName, Distance, DetectedUnitCategory } )
|
||||
|
||||
-- Calculate Acceptance
|
||||
|
||||
@@ -598,7 +611,7 @@ do -- DETECTION_BASE
|
||||
if self.AcceptZones then
|
||||
for AcceptZoneID, AcceptZone in pairs( self.AcceptZones ) do
|
||||
local AcceptZone = AcceptZone -- Core.Zone#ZONE_BASE
|
||||
if AcceptZone:IsPointVec2InZone( DetectedObjectVec2 ) == false then
|
||||
if AcceptZone:IsVec2InZone( DetectedObjectVec2 ) == false then
|
||||
DetectionAccepted = false
|
||||
end
|
||||
end
|
||||
@@ -669,6 +682,7 @@ do -- DETECTION_BASE
|
||||
|
||||
self.DetectedObjects[DetectedObjectName] = self.DetectedObjects[DetectedObjectName] or {}
|
||||
self.DetectedObjects[DetectedObjectName].Name = DetectedObjectName
|
||||
self.DetectedObjects[DetectedObjectName].IsDetected = TargetIsDetected
|
||||
self.DetectedObjects[DetectedObjectName].IsVisible = TargetIsVisible
|
||||
self.DetectedObjects[DetectedObjectName].LastTime = TargetLastTime
|
||||
self.DetectedObjects[DetectedObjectName].LastPos = TargetLastPos
|
||||
@@ -676,6 +690,7 @@ do -- DETECTION_BASE
|
||||
self.DetectedObjects[DetectedObjectName].KnowType = TargetKnowType
|
||||
self.DetectedObjects[DetectedObjectName].KnowDistance = Detection.distance -- TargetKnowDistance
|
||||
self.DetectedObjects[DetectedObjectName].Distance = Distance
|
||||
self.DetectedObjects[DetectedObjectName].DetectionTimeStamp = DetectionTimeStamp
|
||||
|
||||
local DetectedUnit = UNIT:FindByName( DetectedObjectName )
|
||||
|
||||
@@ -699,9 +714,23 @@ do -- DETECTION_BASE
|
||||
|
||||
if self.DetectionCount > 0 and self.DetectionRun == self.DetectionCount then
|
||||
self:T( "--> Create Detection Sets" )
|
||||
|
||||
-- First check if all DetectedObjects were detected.
|
||||
-- This is important. When there are DetectedObjects in the list, but were not detected,
|
||||
-- And these remain undetected for more than 60 seconds, then these DetectedObjects will be flagged as not Detected.
|
||||
-- IsDetected = false!
|
||||
-- This is used in A2A_TASK_DISPATCHER to initiate fighter sweeping! The TASK_A2A_INTERCEPT tasks will be replaced with TASK_A2A_SWEEP tasks.
|
||||
for DetectedObjectName, DetectedObject in pairs( self.DetectedObjects ) do
|
||||
if self.DetectedObjects[DetectedObjectName].IsDetected == true and self.DetectedObjects[DetectedObjectName].DetectionTimeStamp + 60 <= DetectionTimeStamp then
|
||||
self.DetectedObjects[DetectedObjectName].IsDetected = false
|
||||
end
|
||||
end
|
||||
|
||||
self:CreateDetectionItems() -- Polymorphic call to Create/Update the DetectionItems list for the DETECTION_ class grouping method.
|
||||
self:CleanDetectionItems() -- Any DetectionItem that has a Set with zero elements in it, must be removed from the DetectionItems list.
|
||||
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
|
||||
self:UpdateDetectedItemDetection( DetectedItem )
|
||||
self:CleanDetectionItem( DetectedItem, DetectedItemID ) -- Any DetectionItem that has a Set with zero elements in it, must be removed from the DetectionItems list.
|
||||
end
|
||||
|
||||
self:__Detect( self.DetectionInterval )
|
||||
end
|
||||
@@ -713,22 +742,37 @@ do -- DETECTION_BASE
|
||||
|
||||
do -- DetectionItems Creation
|
||||
|
||||
--- Make a DetectionSet table. This function will be overridden in the derived clsses.
|
||||
-- Clean the DetectedItem table.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #DETECTION_BASE
|
||||
function DETECTION_BASE:CleanDetectionItems() --R2.1 Clean the DetectionItems list
|
||||
function DETECTION_BASE:CleanDetectionItem( DetectedItem, DetectedItemID )
|
||||
self:F2()
|
||||
|
||||
-- We clean all DetectedItems.
|
||||
-- if there are any remaining DetectedItems with no Set Objects then the Item in the DetectedItems must be deleted.
|
||||
|
||||
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do
|
||||
local DetectedSet = DetectedItem.Set
|
||||
|
||||
if DetectedSet:Count() == 0 then
|
||||
self:RemoveDetectedItem( DetectedItemID )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
|
||||
local DetectedSet = DetectedItem.Set
|
||||
|
||||
if DetectedSet:Count() == 0 then
|
||||
self:RemoveDetectedItem(DetectedItemID)
|
||||
--- Forget a Unit from a DetectionItem
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #string UnitName The UnitName that needs to be forgotten from the DetectionItem Sets.
|
||||
-- @return #DETECTION_BASE
|
||||
function DETECTION_BASE:ForgetDetectedUnit( UnitName )
|
||||
self:F2()
|
||||
|
||||
local DetectedItems = self:GetDetectedItems()
|
||||
|
||||
for DetectedItemIndex, DetectedItem in pairs( DetectedItems ) do
|
||||
local DetectedSet = self:GetDetectedSet( DetectedItemIndex )
|
||||
if DetectedSet then
|
||||
DetectedSet:RemoveUnitsByName( UnitName )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -879,6 +923,22 @@ do -- DETECTION_BASE
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- Friendlies Radius
|
||||
|
||||
--- Set the radius in meters to validate if friendlies are nearby.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #number FriendliesRange Radius to use when checking if Friendlies are nearby.
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:SetFriendliesRange( FriendliesRange ) --R2.2 Friendlies range
|
||||
self:F2()
|
||||
|
||||
self.FriendliesRange = FriendliesRange
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- Accept / Reject detected units
|
||||
|
||||
@@ -1049,8 +1109,39 @@ do -- DETECTION_BASE
|
||||
-- @return #boolean trhe if there are friendlies nearby
|
||||
function DETECTION_BASE:IsFriendliesNearBy( DetectedItem )
|
||||
|
||||
self:T3( DetectedItem.FriendliesNearBy )
|
||||
return DetectedItem.FriendliesNearBy or false
|
||||
return DetectedItem.FriendliesNearBy ~= nil or false
|
||||
end
|
||||
|
||||
--- Returns friendly units nearby the FAC units ...
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #map<#string,Wrapper.Unit#UNIT> The map of Friendly UNITs.
|
||||
function DETECTION_BASE:GetFriendliesNearBy( DetectedItem )
|
||||
|
||||
return DetectedItem.FriendliesNearBy
|
||||
end
|
||||
|
||||
--- Returns friendly units nearby the FAC units sorted per distance ...
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #map<#number,Wrapper.Unit#UNIT> The map of Friendly UNITs.
|
||||
function DETECTION_BASE:GetFriendliesDistance( DetectedItem )
|
||||
|
||||
return DetectedItem.FriendliesDistance
|
||||
end
|
||||
|
||||
--- Returns if there are friendlies nearby the FAC units ...
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #boolean trhe if there are friendlies nearby
|
||||
function DETECTION_BASE:IsPlayersNearBy( DetectedItem )
|
||||
|
||||
return DetectedItem.PlayersNearBy ~= nil
|
||||
end
|
||||
|
||||
--- Returns friendly units nearby the FAC units ...
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #map<#string,Wrapper.Unit#UNIT> The map of Friendly UNITs.
|
||||
function DETECTION_BASE:GetPlayersNearBy( DetectedItem )
|
||||
|
||||
return DetectedItem.PlayersNearBy
|
||||
end
|
||||
|
||||
--- Background worker function to determine if there are friendlies nearby ...
|
||||
@@ -1062,7 +1153,7 @@ do -- DETECTION_BASE
|
||||
local DetectedSet = ReportGroupData.DetectedItem.Set
|
||||
local DetectedUnit = DetectedSet:GetFirst()
|
||||
|
||||
DetectedItem.FriendliesNearBy = false
|
||||
DetectedItem.FriendliesNearBy = nil
|
||||
|
||||
if DetectedUnit then
|
||||
|
||||
@@ -1071,40 +1162,74 @@ do -- DETECTION_BASE
|
||||
id = world.VolumeType.SPHERE,
|
||||
params = {
|
||||
point = DetectedUnit:GetVec3(),
|
||||
radius = 6000,
|
||||
radius = self.FriendliesRange,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
--- @param Dcs.DCSWrapper.Unit#Unit FoundDCSUnit
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
-- @param Set#SET_GROUP ReportSetGroup
|
||||
local FindNearByFriendlies = function( FoundDCSUnit, ReportGroupData )
|
||||
|
||||
local DetectedItem = ReportGroupData.DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||
local DetectedSet = ReportGroupData.DetectedItem.Set
|
||||
local DetectedUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
|
||||
local ReportSetGroup = ReportGroupData.ReportSetGroup
|
||||
|
||||
local EnemyCoalition = DetectedUnit:GetCoalition()
|
||||
|
||||
local FoundUnitCoalition = FoundDCSUnit:getCoalition()
|
||||
local FoundUnitName = FoundDCSUnit:getName()
|
||||
local FoundUnitGroupName = FoundDCSUnit:getGroup():getName()
|
||||
local EnemyUnitName = DetectedUnit:GetName()
|
||||
local FoundUnitInReportSetGroup = ReportSetGroup:FindGroup( FoundUnitGroupName ) ~= nil
|
||||
|
||||
self:T3( { "Friendlies search:", FoundUnitName, FoundUnitCoalition, EnemyUnitName, EnemyCoalition, FoundUnitInReportSetGroup } )
|
||||
|
||||
if FoundUnitCoalition ~= EnemyCoalition and FoundUnitInReportSetGroup == false then
|
||||
DetectedItem.FriendliesNearBy = true
|
||||
return false
|
||||
end
|
||||
--- @param Dcs.DCSWrapper.Unit#Unit FoundDCSUnit
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
-- @param Set#SET_GROUP ReportSetGroup
|
||||
local FindNearByFriendlies = function( FoundDCSUnit, ReportGroupData )
|
||||
|
||||
local DetectedItem = ReportGroupData.DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||
local DetectedSet = ReportGroupData.DetectedItem.Set
|
||||
local DetectedUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT
|
||||
local CenterCoord = DetectedUnit:GetCoordinate()
|
||||
local ReportSetGroup = ReportGroupData.ReportSetGroup
|
||||
|
||||
local EnemyCoalition = DetectedUnit:GetCoalition()
|
||||
|
||||
local FoundUnitCoalition = FoundDCSUnit:getCoalition()
|
||||
local FoundUnitName = FoundDCSUnit:getName()
|
||||
local FoundUnitGroupName = FoundDCSUnit:getGroup():getName()
|
||||
local EnemyUnitName = DetectedUnit:GetName()
|
||||
local FoundUnitInReportSetGroup = ReportSetGroup:FindGroup( FoundUnitGroupName ) ~= nil
|
||||
|
||||
--self:F( { "Friendlies search:", FoundUnitName, FoundUnitCoalition, EnemyUnitName, EnemyCoalition, FoundUnitInReportSetGroup } )
|
||||
|
||||
if FoundUnitCoalition ~= EnemyCoalition and FoundUnitInReportSetGroup == false then
|
||||
DetectedItem.FriendliesNearBy = DetectedItem.FriendliesNearBy or {}
|
||||
local FriendlyUnit = UNIT:Find( FoundDCSUnit )
|
||||
local FriendlyUnitName = FriendlyUnit:GetName()
|
||||
DetectedItem.FriendliesNearBy[FriendlyUnitName] = FriendlyUnit
|
||||
local Distance = CenterCoord:Get2DDistance( FriendlyUnit:GetCoordinate() )
|
||||
DetectedItem.FriendliesDistance = DetectedItem.FriendliesDistance or {}
|
||||
DetectedItem.FriendliesDistance[Distance] = FriendlyUnit
|
||||
return true
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
world.searchObjects( Object.Category.UNIT, SphereSearch, FindNearByFriendlies, ReportGroupData )
|
||||
|
||||
DetectedItem.PlayersNearBy = nil
|
||||
local DetectionZone = ZONE_UNIT:New( "DetectionPlayers", DetectedUnit, self.FriendliesRange )
|
||||
|
||||
_DATABASE:ForEachPlayer(
|
||||
--- @param Wrapper.Unit#UNIT PlayerUnit
|
||||
function( PlayerUnitName )
|
||||
local PlayerUnit = UNIT:FindByName( PlayerUnitName )
|
||||
|
||||
if PlayerUnit and PlayerUnit:IsInZone(DetectionZone) then
|
||||
|
||||
DetectedItem.FriendliesNearBy = DetectedItem.FriendliesNearBy or {}
|
||||
local PlayerUnitName = PlayerUnit:GetName()
|
||||
|
||||
DetectedItem.PlayersNearBy = DetectedItem.PlayersNearBy or {}
|
||||
DetectedItem.PlayersNearBy[PlayerUnitName] = PlayerUnit
|
||||
|
||||
DetectedItem.FriendliesNearBy = DetectedItem.FriendliesNearBy or {}
|
||||
DetectedItem.FriendliesNearBy[PlayerUnitName] = PlayerUnit
|
||||
|
||||
local CenterCoord = DetectedUnit:GetCoordinate()
|
||||
local Distance = CenterCoord:Get2DDistance( PlayerUnit:GetCoordinate() )
|
||||
DetectedItem.FriendliesDistance = DetectedItem.FriendliesDistance or {}
|
||||
DetectedItem.FriendliesDistance[Distance] = PlayerUnit
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1302,6 +1427,69 @@ do -- DETECTION_BASE
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Set IsDetected flag for all DetectedItems.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #DETECTION_BASE.DetectedItem DetectedItem
|
||||
-- @return #boolean true if at least one UNIT is detected from the DetectedSet, false if no UNIT was detected from the DetectedSet.
|
||||
function DETECTION_BASE:UpdateDetectedItemDetection( DetectedItem )
|
||||
|
||||
local IsDetected = false
|
||||
|
||||
for UnitName, UnitData in pairs( DetectedItem.Set:GetSet() ) do
|
||||
local DetectedObject = self.DetectedObjects[UnitName]
|
||||
if DetectedObject.IsDetected then
|
||||
IsDetected = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self:F( { IsDetected = DetectedItem.IsDetected } )
|
||||
|
||||
DetectedItem.IsDetected = IsDetected
|
||||
|
||||
return IsDetected
|
||||
end
|
||||
|
||||
--- Checks if there is at least one UNIT detected in the Set of the the DetectedItem.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #boolean true if at least one UNIT is detected from the DetectedSet, false if no UNIT was detected from the DetectedSet.
|
||||
function DETECTION_BASE:IsDetectedItemDetected( DetectedItem )
|
||||
|
||||
return DetectedItem.IsDetected
|
||||
end
|
||||
|
||||
do -- Coordinates
|
||||
|
||||
--- Get the COORDINATE of a detection item using a given numeric index.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #number Index
|
||||
-- @return Core.Point#COORDINATE
|
||||
function DETECTION_BASE:GetDetectedItemCoordinate( Index )
|
||||
|
||||
-- If the Zone is set, return the coordinate of the Zone.
|
||||
local DetectedItemSet = self:GetDetectedSet( Index )
|
||||
local FirstUnit = DetectedItemSet:GetFirst()
|
||||
|
||||
local DetectedZone = self:GetDetectedItemZone( Index )
|
||||
if DetectedZone then
|
||||
local Coordinate = DetectedZone:GetPointVec2()
|
||||
Coordinate:SetHeading(FirstUnit:GetHeading())
|
||||
Coordinate:SetAlt( FirstUnit:GetAltitude() )
|
||||
return Coordinate
|
||||
end
|
||||
|
||||
-- If no Zone is set, return the coordinate of the first unit in the Set
|
||||
if FirstUnit then
|
||||
local Coordinate = FirstUnit:GetPointVec3()
|
||||
FirstUnit:SetHeading(FirstUnit:GetHeading())
|
||||
return Coordinate
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- Zones
|
||||
|
||||
@@ -1309,13 +1497,15 @@ do -- DETECTION_BASE
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #number Index
|
||||
-- @return Core.Zone#ZONE_UNIT DetectedZone
|
||||
function DETECTION_BASE:GetDetectedZone( Index )
|
||||
function DETECTION_BASE:GetDetectedItemZone( Index )
|
||||
|
||||
local DetectedZone = self.DetectedItems[Index].Zone
|
||||
if DetectedZone then
|
||||
return DetectedZone
|
||||
end
|
||||
|
||||
local Detected
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -1325,7 +1515,7 @@ do -- DETECTION_BASE
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_BASE:DetectedItemMenu( Index )
|
||||
function DETECTION_BASE:DetectedItemMenu( Index, AttackGroup )
|
||||
self:F( Index )
|
||||
return nil
|
||||
end
|
||||
@@ -1335,7 +1525,7 @@ do -- DETECTION_BASE
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_BASE:DetectedItemReportSummary( Index )
|
||||
function DETECTION_BASE:DetectedItemReportSummary( Index, AttackGroup )
|
||||
self:F( Index )
|
||||
return nil
|
||||
end
|
||||
@@ -1343,7 +1533,7 @@ do -- DETECTION_BASE
|
||||
--- Report detailed of a detectedion result.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #string
|
||||
function DETECTION_BASE:DetectedReportDetailed()
|
||||
function DETECTION_BASE:DetectedReportDetailed( AttackGroup )
|
||||
self:F()
|
||||
return nil
|
||||
end
|
||||
@@ -1377,7 +1567,7 @@ end
|
||||
|
||||
do -- DETECTION_UNITS
|
||||
|
||||
--- # 2) DETECTION_UNITS class, extends @{Detection#DETECTION_BASE}
|
||||
--- # DETECTION_UNITS class, extends @{Detection#DETECTION_BASE}
|
||||
--
|
||||
-- The DETECTION_UNITS class will detect units within the battle zone.
|
||||
-- It will build a DetectedItems list filled with DetectedItems. Each DetectedItem will contain a field Set, which contains a @{Set#SET_UNIT} containing ONE @{UNIT} object reference.
|
||||
@@ -1464,7 +1654,7 @@ do -- DETECTION_UNITS
|
||||
local DetectedUnit = DetectedUnitData -- Wrapper.Unit#UNIT
|
||||
|
||||
local DetectedObject = nil
|
||||
self:E( DetectedUnit )
|
||||
--self:E( DetectedUnit )
|
||||
if DetectedUnit:IsAlive() then
|
||||
--self:E(DetectedUnit:GetName())
|
||||
DetectedObject = self:GetDetectedObject( DetectedUnit:GetName() )
|
||||
@@ -1540,7 +1730,7 @@ do -- DETECTION_UNITS
|
||||
-- @param #DETECTION_UNITS self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_UNITS:DetectedItemMenu( Index )
|
||||
function DETECTION_UNITS:DetectedItemMenu( Index, AttackGroup )
|
||||
self:F( Index )
|
||||
|
||||
local DetectedItem = self:GetDetectedItem( Index )
|
||||
@@ -1559,7 +1749,7 @@ do -- DETECTION_UNITS
|
||||
self:T(DetectedItemUnit)
|
||||
|
||||
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
|
||||
|
||||
ReportSummary = string.format(
|
||||
"%s - %s",
|
||||
@@ -1578,8 +1768,8 @@ do -- DETECTION_UNITS
|
||||
-- @param #DETECTION_UNITS self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_UNITS:DetectedItemReportSummary( Index )
|
||||
self:F( Index )
|
||||
function DETECTION_UNITS:DetectedItemReportSummary( Index, AttackGroup )
|
||||
self:F( { Index, self.DetectedItems } )
|
||||
|
||||
local DetectedItem = self:GetDetectedItem( Index )
|
||||
local DetectedSet = self:GetDetectedSet( Index )
|
||||
@@ -1620,7 +1810,7 @@ do -- DETECTION_UNITS
|
||||
end
|
||||
|
||||
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
|
||||
|
||||
local ThreatLevelA2G = DetectedItemUnit:GetThreatLevel( DetectedItem )
|
||||
|
||||
@@ -1645,13 +1835,13 @@ do -- DETECTION_UNITS
|
||||
--- Report detailed of a detection result.
|
||||
-- @param #DETECTION_UNITS self
|
||||
-- @return #string
|
||||
function DETECTION_UNITS:DetectedReportDetailed()
|
||||
function DETECTION_UNITS:DetectedReportDetailed( AttackGroup )
|
||||
self:F()
|
||||
|
||||
local Report = REPORT:New( "Detected units:" )
|
||||
for DetectedItemID, DetectedItem in pairs( self.DetectedItems ) do
|
||||
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
|
||||
local ReportSummary = self:DetectedItemReportSummary( DetectedItemID )
|
||||
local ReportSummary = self:DetectedItemReportSummary( DetectedItemID, AttackGroup )
|
||||
Report:Add( ReportSummary )
|
||||
end
|
||||
|
||||
@@ -1810,7 +2000,7 @@ do -- DETECTION_TYPES
|
||||
-- @param #DETECTION_TYPES self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_TYPES:DetectedItemMenu( DetectedTypeName )
|
||||
function DETECTION_TYPES:DetectedItemMenu( DetectedTypeName, AttackGroup )
|
||||
self:F( DetectedTypeName )
|
||||
|
||||
local DetectedItem = self:GetDetectedItem( DetectedTypeName )
|
||||
@@ -1823,10 +2013,10 @@ do -- DETECTION_TYPES
|
||||
local DetectedItemUnit = DetectedSet:GetFirst()
|
||||
|
||||
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
|
||||
|
||||
self:E( { DetectedItemID,
|
||||
DetectedItemCoordText } )
|
||||
--self:E( { DetectedItemID,
|
||||
-- DetectedItemCoordText } )
|
||||
|
||||
local ReportSummary = string.format(
|
||||
"%s - %s",
|
||||
@@ -1843,7 +2033,7 @@ do -- DETECTION_TYPES
|
||||
-- @param #DETECTION_TYPES self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_TYPES:DetectedItemReportSummary( DetectedTypeName )
|
||||
function DETECTION_TYPES:DetectedItemReportSummary( DetectedTypeName, AttackGroup )
|
||||
self:F( DetectedTypeName )
|
||||
|
||||
local DetectedItem = self:GetDetectedItem( DetectedTypeName )
|
||||
@@ -1860,7 +2050,7 @@ do -- DETECTION_TYPES
|
||||
local DetectedItemUnit = DetectedSet:GetFirst()
|
||||
|
||||
local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
|
||||
|
||||
local ReportSummary = string.format(
|
||||
"%s - %s - Threat:[%s](%2d) - %2d of %s",
|
||||
@@ -1880,13 +2070,13 @@ do -- DETECTION_TYPES
|
||||
--- Report detailed of a detection result.
|
||||
-- @param #DETECTION_TYPES self
|
||||
-- @return #string
|
||||
function DETECTION_TYPES:DetectedReportDetailed()
|
||||
function DETECTION_TYPES:DetectedReportDetailed( AttackGroup )
|
||||
self:F()
|
||||
|
||||
local Report = REPORT:New( "Detected types:" )
|
||||
for DetectedItemTypeName, DetectedItem in pairs( self.DetectedItems ) do
|
||||
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
|
||||
local ReportSummary = self:DetectedItemReportSummary( DetectedItemTypeName )
|
||||
local ReportSummary = self:DetectedItemReportSummary( DetectedItemTypeName, AttackGroup )
|
||||
Report:Add( ReportSummary )
|
||||
end
|
||||
|
||||
@@ -1967,7 +2157,7 @@ do -- DETECTION_AREAS
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_AREAS:DetectedItemMenu( Index )
|
||||
function DETECTION_AREAS:DetectedItemMenu( Index, AttackGroup )
|
||||
self:F( Index )
|
||||
|
||||
local DetectedItem = self:GetDetectedItem( Index )
|
||||
@@ -1977,9 +2167,9 @@ do -- DETECTION_AREAS
|
||||
local DetectedSet = self:GetDetectedSet( Index )
|
||||
local ReportSummaryItem
|
||||
|
||||
local DetectedZone = self:GetDetectedZone( Index )
|
||||
local DetectedZone = self:GetDetectedItemZone( Index )
|
||||
local DetectedItemCoordinate = DetectedZone:GetCoordinate()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
|
||||
|
||||
local ReportSummary = string.format(
|
||||
"%s - %s",
|
||||
@@ -1997,7 +2187,7 @@ do -- DETECTION_AREAS
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param Index
|
||||
-- @return #string
|
||||
function DETECTION_AREAS:DetectedItemReportSummary( Index )
|
||||
function DETECTION_AREAS:DetectedItemReportSummary( Index, AttackGroup )
|
||||
self:F( Index )
|
||||
|
||||
local DetectedItem = self:GetDetectedItem( Index )
|
||||
@@ -2007,9 +2197,9 @@ do -- DETECTION_AREAS
|
||||
local DetectedSet = self:GetDetectedSet( Index )
|
||||
local ReportSummaryItem
|
||||
|
||||
local DetectedZone = self:GetDetectedZone( Index )
|
||||
local DetectedZone = self:GetDetectedItemZone( Index )
|
||||
local DetectedItemCoordinate = DetectedZone:GetCoordinate()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString()
|
||||
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup )
|
||||
|
||||
local ThreatLevelA2G = self:GetTreatLevelA2G( DetectedItem )
|
||||
local DetectedItemsCount = DetectedSet:Count()
|
||||
@@ -2034,13 +2224,13 @@ do -- DETECTION_AREAS
|
||||
--- Report detailed of a detection result.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #string
|
||||
function DETECTION_AREAS:DetectedReportDetailed() --R2.1 Fixed missing report
|
||||
function DETECTION_AREAS:DetectedReportDetailed( AttackGroup) --R2.1 Fixed missing report
|
||||
self:F()
|
||||
|
||||
local Report = REPORT:New( "Detected areas:" )
|
||||
for DetectedItemIndex, DetectedItem in pairs( self.DetectedItems ) do
|
||||
local DetectedItem = DetectedItem -- #DETECTION_BASE.DetectedItem
|
||||
local ReportSummary = self:DetectedItemReportSummary( DetectedItemIndex )
|
||||
local ReportSummary = self:DetectedItemReportSummary( DetectedItemIndex, AttackGroup )
|
||||
Report:Add( ReportSummary )
|
||||
end
|
||||
|
||||
@@ -2050,16 +2240,6 @@ do -- DETECTION_AREAS
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Returns if there are friendlies nearby the FAC units ...
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #boolean trhe if there are friendlies nearby
|
||||
function DETECTION_AREAS:IsFriendliesNearBy( DetectedItem )
|
||||
|
||||
self:T3( DetectedItem.FriendliesNearBy )
|
||||
return DetectedItem.FriendliesNearBy or false
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the DetectedItem.
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
||||
@@ -2106,7 +2286,7 @@ do -- DETECTION_AREAS
|
||||
DetectedItem.NearestFAC = NearestFAC
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Returns the A2G threat level of the units in the DetectedItem
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem
|
||||
@@ -2236,6 +2416,7 @@ do -- DETECTION_AREAS
|
||||
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do
|
||||
|
||||
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
|
||||
|
||||
if DetectedItem then
|
||||
|
||||
self:T( { "Detected Item ID:", DetectedItemID } )
|
||||
@@ -2276,7 +2457,7 @@ do -- DETECTION_AREAS
|
||||
self:IdentifyDetectedObject( DetectedObject )
|
||||
AreaExists = true
|
||||
|
||||
DetectedItem.Zone:BoundZone( 12, self.CountryID, true)
|
||||
--DetectedItem.Zone:BoundZone( 12, self.CountryID, true)
|
||||
|
||||
-- Assign the Unit as the new center unit of the detected area.
|
||||
DetectedItem.Zone = ZONE_UNIT:New( DetectedUnit:GetName(), DetectedUnit, self.DetectionZoneRange )
|
||||
@@ -2285,6 +2466,9 @@ do -- DETECTION_AREAS
|
||||
|
||||
-- We don't need to add the DetectedObject to the area set, because it is already there ...
|
||||
break
|
||||
else
|
||||
DetectedSet:Remove( DetectedUnitName )
|
||||
self:AddChangeUnit( DetectedItem, "RU", DetectedUnit:GetTypeName() )
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -2329,13 +2513,15 @@ do -- DETECTION_AREAS
|
||||
end
|
||||
end
|
||||
else
|
||||
DetectedItem.Zone:BoundZone( 12, self.CountryID, true)
|
||||
--DetectedItem.Zone:BoundZone( 12, self.CountryID, true)
|
||||
self:RemoveDetectedItem( DetectedItemID )
|
||||
self:AddChangeItem( DetectedItem, "RA" )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- We iterated through the existing detection areas and:
|
||||
-- - We checked which units are still detected in each detection area. Those units were flagged as Identified.
|
||||
-- - We recentered the detection area to new center units where it was needed.
|
||||
@@ -2395,15 +2581,18 @@ do -- DETECTION_AREAS
|
||||
self:ReportFriendliesNearBy( { DetectedItem = DetectedItem, ReportSetGroup = self.DetectionSetGroup } ) -- Fill the Friendlies table
|
||||
self:CalculateThreatLevelA2G( DetectedItem ) -- Calculate A2G threat level
|
||||
self:NearestFAC( DetectedItem )
|
||||
|
||||
|
||||
if DETECTION_AREAS._SmokeDetectedUnits or self._SmokeDetectedUnits then
|
||||
DetectedZone.ZoneUNIT:SmokeRed()
|
||||
end
|
||||
|
||||
--DetectedSet:Flush()
|
||||
|
||||
DetectedSet:ForEachUnit(
|
||||
--- @param Wrapper.Unit#UNIT DetectedUnit
|
||||
function( DetectedUnit )
|
||||
if DetectedUnit:IsAlive() then
|
||||
self:T( "Detected Set #" .. DetectedItem.ItemID .. ":" .. DetectedUnit:GetName() )
|
||||
--self:T( "Detected Set #" .. DetectedItem.ItemID .. ":" .. DetectedUnit:GetName() )
|
||||
if DETECTION_AREAS._FlareDetectedUnits or self._FlareDetectedUnits then
|
||||
DetectedUnit:FlareGreen()
|
||||
end
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
--- Taking the lead of AI escorting your flight.
|
||||
--- **Functional** -- Taking the lead of AI escorting your flight.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @{#ESCORT} class
|
||||
-- ================
|
||||
@@ -1164,7 +1166,7 @@ function ESCORT:_ReportTargetsScheduler()
|
||||
self:E( { DetectedItemID, DetectedItem } )
|
||||
-- Remove the sub menus of the Attack menu of the Escort for the EscortGroup.
|
||||
|
||||
local DetectedItemReportSummary = self.Detection:DetectedItemReportSummary( DetectedItemID )
|
||||
local DetectedItemReportSummary = self.Detection:DetectedItemReportSummary( DetectedItemID, EscortGroupData )
|
||||
|
||||
if ClientEscortGroupName == EscortGroupName then
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- This module contains the MISSILETRAINER class.
|
||||
--- **Functional** -- MISSILETRAINER helps you to train missile avoidance.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -570,72 +570,76 @@ function MISSILETRAINER:_TrackMissiles()
|
||||
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
|
||||
|
||||
local Client = ClientData.Client
|
||||
self:T2( { Client:GetName() } )
|
||||
|
||||
if Client and Client:IsAlive() then
|
||||
|
||||
for MissileDataID, MissileData in pairs( ClientData.MissileData ) do
|
||||
self:T3( MissileDataID )
|
||||
|
||||
local TrainerSourceUnit = MissileData.TrainerSourceUnit
|
||||
local TrainerWeapon = MissileData.TrainerWeapon
|
||||
local TrainerTargetUnit = MissileData.TrainerTargetUnit
|
||||
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
|
||||
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
|
||||
for MissileDataID, MissileData in pairs( ClientData.MissileData ) do
|
||||
self:T3( MissileDataID )
|
||||
|
||||
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
|
||||
local PositionMissile = TrainerWeapon:getPosition().p
|
||||
local TargetVec3 = Client:GetVec3()
|
||||
|
||||
local Distance = ( ( PositionMissile.x - TargetVec3.x )^2 +
|
||||
( PositionMissile.y - TargetVec3.y )^2 +
|
||||
( PositionMissile.z - TargetVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
if Distance <= self.Distance then
|
||||
-- Hit alert
|
||||
TrainerWeapon:destroy()
|
||||
if self.MessagesOnOff == true and self.AlertsHitsOnOff == true then
|
||||
|
||||
self:T( "killed" )
|
||||
|
||||
local Message = MESSAGE:New(
|
||||
string.format( "%s launched by %s killed %s",
|
||||
TrainerWeapon:getTypeName(),
|
||||
TrainerSourceUnit:GetTypeName(),
|
||||
TrainerTargetUnit:GetPlayerName()
|
||||
), 15, "Hit Alert" )
|
||||
|
||||
if self.AlertsToAll == true then
|
||||
Message:ToAll()
|
||||
else
|
||||
Message:ToClient( Client )
|
||||
local TrainerSourceUnit = MissileData.TrainerSourceUnit
|
||||
local TrainerWeapon = MissileData.TrainerWeapon
|
||||
local TrainerTargetUnit = MissileData.TrainerTargetUnit
|
||||
local TrainerWeaponTypeName = MissileData.TrainerWeaponTypeName
|
||||
local TrainerWeaponLaunched = MissileData.TrainerWeaponLaunched
|
||||
|
||||
if Client and Client:IsAlive() and TrainerSourceUnit and TrainerSourceUnit:IsAlive() and TrainerWeapon and TrainerWeapon:isExist() and TrainerTargetUnit and TrainerTargetUnit:IsAlive() then
|
||||
local PositionMissile = TrainerWeapon:getPosition().p
|
||||
local TargetVec3 = Client:GetVec3()
|
||||
|
||||
local Distance = ( ( PositionMissile.x - TargetVec3.x )^2 +
|
||||
( PositionMissile.y - TargetVec3.y )^2 +
|
||||
( PositionMissile.z - TargetVec3.z )^2
|
||||
) ^ 0.5 / 1000
|
||||
|
||||
if Distance <= self.Distance then
|
||||
-- Hit alert
|
||||
TrainerWeapon:destroy()
|
||||
if self.MessagesOnOff == true and self.AlertsHitsOnOff == true then
|
||||
|
||||
self:T( "killed" )
|
||||
|
||||
local Message = MESSAGE:New(
|
||||
string.format( "%s launched by %s killed %s",
|
||||
TrainerWeapon:getTypeName(),
|
||||
TrainerSourceUnit:GetTypeName(),
|
||||
TrainerTargetUnit:GetPlayerName()
|
||||
), 15, "Hit Alert" )
|
||||
|
||||
if self.AlertsToAll == true then
|
||||
Message:ToAll()
|
||||
else
|
||||
Message:ToClient( Client )
|
||||
end
|
||||
|
||||
MissileData = nil
|
||||
table.remove( ClientData.MissileData, MissileDataID )
|
||||
self:T(ClientData.MissileData)
|
||||
end
|
||||
end
|
||||
else
|
||||
if not ( TrainerWeapon and TrainerWeapon:isExist() ) then
|
||||
if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then
|
||||
-- Weapon does not exist anymore. Delete from Table
|
||||
local Message = MESSAGE:New(
|
||||
string.format( "%s launched by %s self destructed!",
|
||||
TrainerWeaponTypeName,
|
||||
TrainerSourceUnit:GetTypeName()
|
||||
), 5, "Tracking" )
|
||||
|
||||
if self.AlertsToAll == true then
|
||||
Message:ToAll()
|
||||
else
|
||||
Message:ToClient( Client )
|
||||
end
|
||||
end
|
||||
|
||||
MissileData = nil
|
||||
table.remove( ClientData.MissileData, MissileDataID )
|
||||
self:T(ClientData.MissileData)
|
||||
self:T( ClientData.MissileData )
|
||||
end
|
||||
end
|
||||
else
|
||||
if not ( TrainerWeapon and TrainerWeapon:isExist() ) then
|
||||
if self.MessagesOnOff == true and self.AlertsLaunchesOnOff == true then
|
||||
-- Weapon does not exist anymore. Delete from Table
|
||||
local Message = MESSAGE:New(
|
||||
string.format( "%s launched by %s self destructed!",
|
||||
TrainerWeaponTypeName,
|
||||
TrainerSourceUnit:GetTypeName()
|
||||
), 5, "Tracking" )
|
||||
|
||||
if self.AlertsToAll == true then
|
||||
Message:ToAll()
|
||||
else
|
||||
Message:ToClient( Client )
|
||||
end
|
||||
end
|
||||
MissileData = nil
|
||||
table.remove( ClientData.MissileData, MissileDataID )
|
||||
self:T( ClientData.MissileData )
|
||||
end
|
||||
end
|
||||
else
|
||||
self.TrackingMissiles[ClientDataID] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -651,7 +655,7 @@ function MISSILETRAINER:_TrackMissiles()
|
||||
for ClientDataID, ClientData in pairs( self.TrackingMissiles ) do
|
||||
|
||||
local Client = ClientData.Client
|
||||
self:T2( { Client:GetName() } )
|
||||
--self:T2( { Client:GetName() } )
|
||||
|
||||
|
||||
ClientData.MessageToClient = ""
|
||||
@@ -661,7 +665,7 @@ function MISSILETRAINER:_TrackMissiles()
|
||||
for TrackingDataID, TrackingData in pairs( self.TrackingMissiles ) do
|
||||
|
||||
for MissileDataID, MissileData in pairs( TrackingData.MissileData ) do
|
||||
self:T3( MissileDataID )
|
||||
--self:T3( MissileDataID )
|
||||
|
||||
local TrainerSourceUnit = MissileData.TrainerSourceUnit
|
||||
local TrainerWeapon = MissileData.TrainerWeapon
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
--- Limit the simultaneous movement of Groups within a running Mission.
|
||||
--- **Functional** -- Limit the MOVEMENT of simulaneous moving ground vehicles.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- Limit the simultaneous movement of Groups within a running Mission.
|
||||
-- This module is defined to improve the performance in missions, and to bring additional realism for GROUND vehicles.
|
||||
-- Performance: If in a DCSRTE there are a lot of moving GROUND units, then in a multi player mission, this WILL create lag if
|
||||
-- the main DCS execution core of your CPU is fully utilized. So, this class will limit the amount of simultaneous moving GROUND units
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- Single-Player:**Yes** / Multi-Player:**Yes** / Core:**Yes** -- **Administer the scoring of player achievements,
|
||||
--- **Functional** -- **Administer the SCORING of player achievements,
|
||||
-- and create a CSV file logging the scoring events for use at team or squadron websites.**
|
||||
--
|
||||
-- 
|
||||
@@ -125,6 +125,32 @@
|
||||
--
|
||||
-- The above documents that 2 Scoring objects are created, ScoringFirstMission and ScoringSecondMission.
|
||||
--
|
||||
-- ### **IMPORTANT!!!*
|
||||
-- In order to allow DCS world to write CSV files, you need to adapt a configuration file in your DCS world installation **on the server**.
|
||||
-- For this, browse to the **missionscripting.lua** file in your DCS world installation folder.
|
||||
-- For me, this installation folder is in _D:\\Program Files\\Eagle Dynamics\\DCS World\Scripts_.
|
||||
--
|
||||
-- Edit a few code lines in the MissionScripting.lua file. Comment out the lines **os**, **io** and **lfs**:
|
||||
--
|
||||
-- do
|
||||
-- --sanitizeModule('os')
|
||||
-- --sanitizeModule('io')
|
||||
-- --sanitizeModule('lfs')
|
||||
-- require = nil
|
||||
-- loadlib = nil
|
||||
-- end
|
||||
--
|
||||
-- When these lines are not sanitized, functions become available to check the time, and to write files to your system at the above specified location.
|
||||
-- Note that the MissionScripting.lua file provides a warning. So please beware of this warning as outlined by Eagle Dynamics!
|
||||
--
|
||||
-- --Sanitize Mission Scripting environment
|
||||
-- --This makes unavailable some unsecure functions.
|
||||
-- --Mission downloaded from server to client may contain potentialy harmful lua code that may use these functions.
|
||||
-- --You can remove the code below and make availble these functions at your own risk.
|
||||
--
|
||||
-- The MOOSE designer cannot take any responsibility of any damage inflicted as a result of the de-sanitization.
|
||||
-- That being said, I hope that the SCORING class provides you with a great add-on to score your squad mates achievements.
|
||||
--
|
||||
-- ## 1.9) Configure messages.
|
||||
--
|
||||
-- When players hit or destroy targets, messages are sent.
|
||||
@@ -247,6 +273,8 @@ function SCORING:New( GameName )
|
||||
-- Default penalty when a player changes coalition.
|
||||
self:SetCoalitionChangePenalty( self.ScaleDestroyPenalty )
|
||||
|
||||
self:SetDisplayMessagePrefix()
|
||||
|
||||
-- Event handlers
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
@@ -261,15 +289,23 @@ function SCORING:New( GameName )
|
||||
|
||||
end
|
||||
|
||||
--- Set a prefix string that will be displayed at each scoring message sent.
|
||||
-- @param #SCORING self
|
||||
-- @param #string DisplayMessagePrefix (Default="Scoring: ") The scoring prefix string.
|
||||
-- @return #SCORING
|
||||
function SCORING:SetDisplayMessagePrefix( DisplayMessagePrefix )
|
||||
self.DisplayMessagePrefix = DisplayMessagePrefix or ""
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set the scale for scoring valid destroys (enemy destroys).
|
||||
-- A default calculated score is a value between 1 and 10.
|
||||
-- The scale magnifies the scores given to the players.
|
||||
-- @param #SCORING self
|
||||
-- @param #number Scale The scale of the score given.
|
||||
function SCORING:SetScaleDestroyScore( Scale )
|
||||
|
||||
self.ScaleDestroyScore = Scale
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -572,7 +608,7 @@ function SCORING:_AddPlayerFromUnit( UnitData )
|
||||
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then
|
||||
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
|
||||
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
|
||||
MESSAGE:New( "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] ..
|
||||
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] ..
|
||||
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
|
||||
2
|
||||
):ToAll()
|
||||
@@ -590,7 +626,7 @@ function SCORING:_AddPlayerFromUnit( UnitData )
|
||||
|
||||
if self.Players[PlayerName].Penalty > self.Fratricide * 0.50 then
|
||||
if self.Players[PlayerName].PenaltyWarning < 1 then
|
||||
MESSAGE:New( "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than " .. self.Fratricide .. ", you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
|
||||
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than " .. self.Fratricide .. ", you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
|
||||
30
|
||||
):ToAll()
|
||||
self.Players[PlayerName].PenaltyWarning = self.Players[PlayerName].PenaltyWarning + 1
|
||||
@@ -598,10 +634,10 @@ function SCORING:_AddPlayerFromUnit( UnitData )
|
||||
end
|
||||
|
||||
if self.Players[PlayerName].Penalty > self.Fratricide then
|
||||
--UnitData:Destroy()
|
||||
MESSAGE:New( "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!",
|
||||
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!",
|
||||
10
|
||||
):ToAll()
|
||||
UnitData:GetGroup():Destroy()
|
||||
end
|
||||
|
||||
end
|
||||
@@ -632,7 +668,7 @@ function SCORING:AddGoalScore( PlayerUnit, GoalTag, Text, Score )
|
||||
PlayerData.Goals[GoalTag].Score = PlayerData.Goals[GoalTag].Score + Score
|
||||
PlayerData.Score = PlayerData.Score + Score
|
||||
|
||||
MESSAGE:New( Text, 30 ):ToAll()
|
||||
MESSAGE:New( self.DisplayMessagePrefix .. Text, 30 ):ToAll()
|
||||
|
||||
self:ScoreCSV( PlayerName, "", "GOAL_" .. string.upper( GoalTag ), 1, Score, PlayerUnit:GetName() )
|
||||
end
|
||||
@@ -668,9 +704,7 @@ function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score )
|
||||
PlayerData.Score = self.Players[PlayerName].Score + Score
|
||||
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
|
||||
|
||||
MESSAGE:New( "Player '" .. PlayerName .. "' has " .. Text .. " in Mission '" .. MissionName .. "'. " ..
|
||||
Score .. " task score!",
|
||||
30 ):ToAll()
|
||||
MESSAGE:New( self.DisplayMessagePrefix .. MissionName .. " : " .. Text .. " Score: " .. Score, 30 ):ToAll()
|
||||
|
||||
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:GetName() )
|
||||
end
|
||||
@@ -698,7 +732,7 @@ function SCORING:_AddMissionScore( Mission, Text, Score )
|
||||
PlayerData.Score = PlayerData.Score + Score
|
||||
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
|
||||
|
||||
MESSAGE:New( "Player '" .. PlayerName .. "' has " .. Text .. " in Mission '" .. MissionName .. "'. " ..
|
||||
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in Mission '" .. MissionName .. "'. " ..
|
||||
Score .. " mission score!",
|
||||
60 ):ToAll()
|
||||
|
||||
@@ -868,7 +902,7 @@ function SCORING:_EventOnHit( Event )
|
||||
|
||||
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
||||
MESSAGE
|
||||
:New( "Player '" .. InitPlayerName .. "' hit friendly player '" .. TargetPlayerName .. "' " ..
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly player '" .. TargetPlayerName .. "' " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
|
||||
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
2
|
||||
@@ -877,7 +911,7 @@ function SCORING:_EventOnHit( Event )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||
else
|
||||
MESSAGE
|
||||
:New( "Player '" .. InitPlayerName .. "' hit a friendly target " ..
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly target " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
|
||||
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
2
|
||||
@@ -892,7 +926,7 @@ function SCORING:_EventOnHit( Event )
|
||||
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
|
||||
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
||||
MESSAGE
|
||||
:New( "Player '" .. InitPlayerName .. "' hit enemy player '" .. TargetPlayerName .. "' " ..
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy player '" .. TargetPlayerName .. "' " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
|
||||
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
2
|
||||
@@ -901,7 +935,7 @@ function SCORING:_EventOnHit( Event )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||
else
|
||||
MESSAGE
|
||||
:New( "Player '" .. InitPlayerName .. "' hit an enemy target " ..
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
|
||||
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
2
|
||||
@@ -913,7 +947,7 @@ function SCORING:_EventOnHit( Event )
|
||||
end
|
||||
else -- A scenery object was hit.
|
||||
MESSAGE
|
||||
:New( "Player '" .. InitPlayerName .. "' hit a scenery object.",
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object.",
|
||||
2
|
||||
)
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
@@ -974,9 +1008,9 @@ function SCORING:_EventOnHit( Event )
|
||||
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1
|
||||
|
||||
MESSAGE
|
||||
:New( "Player '" .. Event.WeaponPlayerName .. "' hit a friendly target " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
|
||||
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||
"Penalty: -" .. PlayerHit.Penalty .. " = " .. Player.Score - Player.Penalty,
|
||||
2
|
||||
)
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
@@ -987,9 +1021,9 @@ function SCORING:_EventOnHit( Event )
|
||||
PlayerHit.Score = PlayerHit.Score + 1
|
||||
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
|
||||
MESSAGE
|
||||
:New( "Player '" .. Event.WeaponPlayerName .. "' hit an enemy target " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
|
||||
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " ..
|
||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||
"Score: +" .. PlayerHit.Score .. " = " .. Player.Score - Player.Penalty,
|
||||
2
|
||||
)
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
@@ -998,7 +1032,7 @@ function SCORING:_EventOnHit( Event )
|
||||
end
|
||||
else -- A scenery object was hit.
|
||||
MESSAGE
|
||||
:New( "Player '" .. Event.WeaponPlayerName .. "' hit a scenery object.",
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit scenery object.",
|
||||
2
|
||||
)
|
||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||
@@ -1097,18 +1131,18 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
|
||||
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
|
||||
MESSAGE
|
||||
:New( "Player '" .. PlayerName .. "' destroyed friendly player '" .. TargetPlayerName .. "' " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. TargetDestroy.PenaltyDestroy .. " times. " ..
|
||||
"Penalty: -" .. TargetDestroy.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly player '" .. TargetPlayerName .. "' " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
|
||||
15
|
||||
)
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
|
||||
else
|
||||
MESSAGE
|
||||
:New( "Player '" .. PlayerName .. "' destroyed a friendly target " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. TargetDestroy.PenaltyDestroy .. " times. " ..
|
||||
"Penalty: -" .. TargetDestroy.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly target " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
|
||||
15
|
||||
)
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
@@ -1131,18 +1165,18 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
TargetDestroy.ScoreDestroy = TargetDestroy.ScoreDestroy + 1
|
||||
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
|
||||
MESSAGE
|
||||
:New( "Player '" .. PlayerName .. "' destroyed enemy player '" .. TargetPlayerName .. "' " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. TargetDestroy.ScoreDestroy .. " times. " ..
|
||||
"Score: " .. TargetDestroy.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy player '" .. TargetPlayerName .. "' " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
|
||||
15
|
||||
)
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
|
||||
else
|
||||
MESSAGE
|
||||
:New( "Player '" .. PlayerName .. "' destroyed an enemy " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. TargetDestroy.ScoreDestroy .. " times. " ..
|
||||
"Score: " .. TargetDestroy.Score .. ". Total:" .. Player.Score - Player.Penalty,
|
||||
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy " ..
|
||||
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
|
||||
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
|
||||
15
|
||||
)
|
||||
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
|
||||
@@ -1157,7 +1191,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
Player.Score = Player.Score + Score
|
||||
TargetDestroy.Score = TargetDestroy.Score + Score
|
||||
MESSAGE
|
||||
:New( "Special target '" .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. " destroyed! " ..
|
||||
:New( self.DisplayMessagePrefix .. "Special target '" .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. " destroyed! " ..
|
||||
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! Total: " .. Player.Score - Player.Penalty,
|
||||
15
|
||||
)
|
||||
@@ -1176,7 +1210,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
Player.Score = Player.Score + Score
|
||||
TargetDestroy.Score = TargetDestroy.Score + Score
|
||||
MESSAGE
|
||||
:New( "Target destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
|
||||
:New( self.DisplayMessagePrefix .. "Target destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
|
||||
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " ..
|
||||
"Total: " .. Player.Score - Player.Penalty,
|
||||
15 )
|
||||
@@ -1198,7 +1232,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
||||
Player.Score = Player.Score + Score
|
||||
TargetDestroy.Score = TargetDestroy.Score + Score
|
||||
MESSAGE
|
||||
:New( "Scenery destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
|
||||
:New( self.DisplayMessagePrefix .. "Scenery destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
|
||||
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " ..
|
||||
"Total: " .. Player.Score - Player.Penalty,
|
||||
15
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
--- Provides defensive behaviour to a set of SAM sites within a running Mission.
|
||||
--- **Functional** -- Provides defensive behaviour to a set of SAM sites within a running Mission.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Sead
|
||||
-- @author to be searched on the forum
|
||||
-- @author (co) Flightcontrol (Modified and enriched with functionality)
|
||||
|
||||
--- The SEAD class
|
||||
-- @type SEAD
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
--
|
||||
-- @module Spawn
|
||||
|
||||
----BASE:TraceClass("SPAWN")
|
||||
|
||||
|
||||
--- SPAWN Class
|
||||
@@ -264,6 +265,14 @@ SPAWN = {
|
||||
}
|
||||
|
||||
|
||||
--- Enumerator for spawns at airbases
|
||||
-- @type SPAWN.Takeoff
|
||||
-- @extends Wrapper.Group#GROUP.Takeoff
|
||||
|
||||
--- @field #SPAWN.Takeoff Takeoff
|
||||
SPAWN.Takeoff = GROUP.Takeoff
|
||||
|
||||
|
||||
--- @type SPAWN.SpawnZoneTable
|
||||
-- @list <Core.Zone#ZONE_BASE> SpawnZone
|
||||
|
||||
@@ -299,6 +308,7 @@ function SPAWN:New( SpawnTemplatePrefix )
|
||||
self.SpawnUnControlled = false
|
||||
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
|
||||
self.DelayOnOff = false -- No intial delay when spawning the first group.
|
||||
self.Grouping = nil -- No grouping
|
||||
|
||||
self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned.
|
||||
else
|
||||
@@ -343,6 +353,7 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
|
||||
self.SpawnUnControlled = false
|
||||
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
|
||||
self.DelayOnOff = false -- No intial delay when spawning the first group.
|
||||
self.Grouping = nil
|
||||
|
||||
self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned.
|
||||
else
|
||||
@@ -509,6 +520,20 @@ function SPAWN:InitRandomizeTemplate( SpawnTemplatePrefixTable )
|
||||
return self
|
||||
end
|
||||
|
||||
--- When spawning a new group, make the grouping of the units according the InitGrouping setting.
|
||||
-- @param #SPAWN self
|
||||
-- @param #number Grouping Indicates the maximum amount of units in the group.
|
||||
-- @return #SPAWN
|
||||
function SPAWN:InitGrouping( Grouping ) -- R2.2
|
||||
self:F( { self.SpawnTemplatePrefix, Grouping } )
|
||||
|
||||
self.SpawnGrouping = Grouping
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--TODO: Add example.
|
||||
--- This method provides the functionality to randomize the spawning of the Groups at a given list of zones of different types.
|
||||
-- @param #SPAWN self
|
||||
@@ -855,7 +880,10 @@ function SPAWN:SpawnWithIndex( SpawnIndex )
|
||||
|
||||
-- If there is a SpawnFunction hook defined, call it.
|
||||
if self.SpawnFunctionHook then
|
||||
self.SpawnFunctionHook( self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments ) )
|
||||
-- delay calling this for .1 seconds so that it hopefully comes after the BIRTH event of the group.
|
||||
self.SpawnHookScheduler = SCHEDULER:New()
|
||||
self.SpawnHookScheduler:Schedule( nil, self.SpawnFunctionHook, { self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments)}, 0.1 )
|
||||
-- self.SpawnFunctionHook( self.SpawnGroups[self.SpawnIndex].Group, unpack( self.SpawnFunctionArguments ) )
|
||||
end
|
||||
-- TODO: Need to fix this by putting an "R" in the name of the group when the group repeats.
|
||||
--if self.Repeat then
|
||||
@@ -954,6 +982,64 @@ function SPAWN:OnSpawnGroup( SpawnCallBackFunction, ... )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Will spawn a group at an airbase.
|
||||
-- This method is mostly advisable to be used if you want to simulate spawning units at an airbase.
|
||||
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
||||
-- You can use the returned group to further define the route to be followed.
|
||||
-- @param #SPAWN self
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase The @{Airbase} where to spawn the group.
|
||||
-- @param #SPAWN.Takeoff Takeoff (optional) The location and takeoff method. Default is Hot.
|
||||
-- @return Wrapper.Group#GROUP that was spawned.
|
||||
-- @return #nil Nothing was spawned.
|
||||
function SPAWN:SpawnAtAirbase( Airbase, Takeoff ) -- R2.2
|
||||
self:F( { self.SpawnTemplatePrefix, Airbase } )
|
||||
|
||||
local PointVec3 = Airbase:GetPointVec3()
|
||||
self:T2(PointVec3)
|
||||
|
||||
Takeoff = Takeoff or SPAWN.Takeoff.Hot
|
||||
|
||||
if self:_GetSpawnIndex( self.SpawnIndex + 1 ) then
|
||||
|
||||
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
||||
|
||||
if SpawnTemplate then
|
||||
|
||||
self:T( { "Current point of ", self.SpawnTemplatePrefix, Airbase } )
|
||||
|
||||
-- Translate the position of the Group Template to the Vec3.
|
||||
for UnitID = 1, #SpawnTemplate.units do
|
||||
self:T( 'Before Translation SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||
local UnitTemplate = SpawnTemplate.units[UnitID]
|
||||
local SX = UnitTemplate.x
|
||||
local SY = UnitTemplate.y
|
||||
local BX = SpawnTemplate.route.points[1].x
|
||||
local BY = SpawnTemplate.route.points[1].y
|
||||
local TX = PointVec3.x + ( SX - BX )
|
||||
local TY = PointVec3.z + ( SY - BY )
|
||||
SpawnTemplate.units[UnitID].x = TX
|
||||
SpawnTemplate.units[UnitID].y = TY
|
||||
SpawnTemplate.units[UnitID].alt = PointVec3.y
|
||||
self:T( 'After Translation SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||
end
|
||||
|
||||
SpawnTemplate.route.points[1].x = PointVec3.x
|
||||
SpawnTemplate.route.points[1].y = PointVec3.z
|
||||
SpawnTemplate.route.points[1].alt = Airbase.y
|
||||
SpawnTemplate.route.points[1].type = GROUPTEMPLATE.Takeoff[Takeoff]
|
||||
SpawnTemplate.route.points[1].airdromeId = Airbase:GetID()
|
||||
|
||||
SpawnTemplate.x = PointVec3.x
|
||||
SpawnTemplate.y = PointVec3.z
|
||||
|
||||
return self:SpawnWithIndex( self.SpawnIndex )
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Will spawn a group from a Vec3 in 3D space.
|
||||
-- This method is mostly advisable to be used if you want to simulate spawning units in the air, like helicopters or airplanes.
|
||||
@@ -1109,6 +1195,19 @@ function SPAWN:InitUnControlled( UnControlled )
|
||||
end
|
||||
|
||||
|
||||
--- Get the Coordinate of the Group that is Late Activated as the template for the SPAWN object.
|
||||
-- @param #SPAWN self
|
||||
-- @return Core.Point#COORDINATE The Coordinate
|
||||
function SPAWN:GetCoordinate()
|
||||
|
||||
local LateGroup = GROUP:FindByName( self.SpawnTemplatePrefix )
|
||||
if LateGroup then
|
||||
return LateGroup:GetCoordinate()
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Will return the SpawnGroupName either with with a specific count number or without any count.
|
||||
-- @param #SPAWN self
|
||||
@@ -1367,7 +1466,7 @@ end
|
||||
-- @param #string SpawnTemplatePrefix
|
||||
-- @param #number SpawnIndex
|
||||
-- @return #SPAWN self
|
||||
function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex )
|
||||
function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) --R2.2
|
||||
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
|
||||
|
||||
local SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix )
|
||||
@@ -1382,6 +1481,23 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex )
|
||||
SpawnTemplate.visible = false
|
||||
end
|
||||
|
||||
if self.SpawnGrouping then
|
||||
local UnitAmount = #SpawnTemplate.units
|
||||
self:F( { UnitAmount = UnitAmount, SpawnGrouping = self.SpawnGrouping } )
|
||||
if UnitAmount > self.SpawnGrouping then
|
||||
for UnitID = self.SpawnGrouping + 1, UnitAmount do
|
||||
SpawnTemplate.units[UnitID] = nil
|
||||
end
|
||||
else
|
||||
if UnitAmount < self.SpawnGrouping then
|
||||
for UnitID = UnitAmount + 1, self.SpawnGrouping do
|
||||
SpawnTemplate.units[UnitID] = UTILS.DeepCopy( SpawnTemplate.units[1] )
|
||||
SpawnTemplate.units[UnitID].unitId = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.SpawnInitKeepUnitNames == false then
|
||||
for UnitID = 1, #SpawnTemplate.units do
|
||||
SpawnTemplate.units[UnitID].name = string.format( SpawnTemplate.name .. '-%02d', UnitID )
|
||||
|
||||
@@ -7,6 +7,7 @@ _EVENTDISPATCHER = EVENT:New() -- Core.Event#EVENT
|
||||
_SCHEDULEDISPATCHER = SCHEDULEDISPATCHER:New() -- Core.Timer#SCHEDULEDISPATCHER
|
||||
|
||||
--- Declare the main database object, which is used internally by the MOOSE classes.
|
||||
_DATABASE = DATABASE:New() -- Database#DATABASE
|
||||
_DATABASE = DATABASE:New() -- Core.Database#DATABASE
|
||||
|
||||
_SETTINGS = SETTINGS:Set()
|
||||
|
||||
--COORDINATE:CoordinateMenu()
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
--- A COMMANDCENTER is the owner of multiple missions within MOOSE.
|
||||
--- **Tasking** -- A COMMANDCENTER is the owner of multiple missions within MOOSE.
|
||||
-- A COMMANDCENTER governs multiple missions, the tasking and the reporting.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module CommandCenter
|
||||
|
||||
|
||||
@@ -26,6 +35,8 @@ function REPORT:New( Title )
|
||||
if Title then
|
||||
self.Title = Title
|
||||
end
|
||||
|
||||
self:SetIndent( 3 )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -83,13 +94,64 @@ end
|
||||
-- @field Dcs.DCSCoalitionWrapper.Object#coalition CommandCenterCoalition
|
||||
-- @list<Tasking.Mission#MISSION> Missions
|
||||
-- @extends Core.Base#BASE
|
||||
|
||||
|
||||
--- # COMMANDCENTER class, extends @{Base#BASE}
|
||||
--
|
||||
-- The COMMANDCENTER class governs multiple missions, the tasking and the reporting.
|
||||
--
|
||||
-- The commandcenter communicates important messages between the various groups of human players executing tasks in missions.
|
||||
--
|
||||
-- ## COMMANDCENTER constructor
|
||||
--
|
||||
-- * @{#COMMANDCENTER.New}(): Creates a new COMMANDCENTER object.
|
||||
--
|
||||
-- ## Mission Management
|
||||
--
|
||||
-- * @{#COMMANDCENTER.AddMission}(): Adds a mission to the commandcenter control.
|
||||
-- * @{#COMMANDCENTER.RemoveMission}(): Removes a mission to the commandcenter control.
|
||||
-- * @{#COMMANDCENTER.GetMissions}(): Retrieves the missions table controlled by the commandcenter.
|
||||
--
|
||||
-- ## Reference Zones
|
||||
--
|
||||
-- Command Centers may be aware of certain Reference Zones within the battleground. These Reference Zones can refer to
|
||||
-- known areas, recognizable buildings or sites, or any other point of interest.
|
||||
-- Command Centers will use these Reference Zones to help pilots with defining coordinates in terms of navigation
|
||||
-- during the WWII era.
|
||||
-- The Reference Zones are related to the WWII mode that the Command Center will operate in.
|
||||
-- Use the method @{#COMMANDCENTER.SetModeWWII}() to set the mode of communication to the WWII mode.
|
||||
--
|
||||
-- In WWII mode, the Command Center will receive detected targets, and will select for each target the closest
|
||||
-- nearby Reference Zone. This allows pilots to navigate easier through the battle field readying for combat.
|
||||
--
|
||||
-- The Reference Zones need to be set by the Mission Designer in the Mission Editor.
|
||||
-- Reference Zones are set by normal trigger zones. One can color the zones in a specific color,
|
||||
-- and the radius of the zones doesn't matter, only the point is important. Place the center of these Reference Zones at
|
||||
-- specific scenery objects or points of interest (like cities, rivers, hills, crossing etc).
|
||||
-- The trigger zones indicating a Reference Zone need to follow a specific syntax.
|
||||
-- The name of each trigger zone expressing a Reference Zone need to start with a classification name of the object,
|
||||
-- followed by a #, followed by a symbolic name of the Reference Zone.
|
||||
-- A few examples:
|
||||
--
|
||||
-- * A church at Tskinvali would be indicated as: *Church#Tskinvali*
|
||||
-- * A train station near Kobuleti would be indicated as: *Station#Kobuleti*
|
||||
--
|
||||
-- The COMMANDCENTER class contains a method to indicate which trigger zones need to be used as Reference Zones.
|
||||
-- This is done by using the method @{#COMMANDCENTER.SetReferenceZones}().
|
||||
-- For the moment, only one Reference Zone class can be specified, but in the future, more classes will become possible.
|
||||
--
|
||||
-- @field #COMMANDCENTER
|
||||
COMMANDCENTER = {
|
||||
ClassName = "COMMANDCENTER",
|
||||
CommandCenterName = "",
|
||||
CommandCenterCoalition = nil,
|
||||
CommandCenterPositionable = nil,
|
||||
Name = "",
|
||||
ReferencePoints = {},
|
||||
ReferenceNames = {},
|
||||
CommunicationMode = "80",
|
||||
}
|
||||
|
||||
--- The constructor takes an IDENTIFIABLE as the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param Wrapper.Positionable#POSITIONABLE CommandCenterPositionable
|
||||
@@ -116,13 +178,14 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
local MenuMissionsSummary = MENU_GROUP_COMMAND:New( EventGroup, "Missions Status Report", MenuReporting, self.ReportMissionsStatus, self, EventGroup )
|
||||
local MenuMissionsDetails = MENU_GROUP_COMMAND:New( EventGroup, "Missions Players Report", MenuReporting, self.ReportMissionsPlayers, self, EventGroup )
|
||||
self:ReportSummary( EventGroup )
|
||||
end
|
||||
local PlayerUnit = EventData.IniUnit
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
Mission:ReportDetails()
|
||||
local PlayerUnit = EventData.IniUnit
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
end
|
||||
self:SetMenu()
|
||||
_DATABASE:PlayerSettingsMenu( PlayerUnit )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -143,7 +206,6 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
local PlayerGroup = EventData.IniGroup -- The GROUP object should be filled!
|
||||
Mission:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
Mission:ReportDetails()
|
||||
end
|
||||
end
|
||||
)
|
||||
@@ -198,6 +260,8 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
)
|
||||
|
||||
self:SetMenu()
|
||||
|
||||
_SETTINGS:SetSystemMenu( CommandCenterPositionable )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -248,6 +312,66 @@ function COMMANDCENTER:RemoveMission( Mission )
|
||||
return Mission
|
||||
end
|
||||
|
||||
--- Set special Reference Zones known by the Command Center to guide airborne pilots during WWII.
|
||||
--
|
||||
-- These Reference Zones are normal trigger zones, with a special naming.
|
||||
-- The Reference Zones need to be set by the Mission Designer in the Mission Editor.
|
||||
-- Reference Zones are set by normal trigger zones. One can color the zones in a specific color,
|
||||
-- and the radius of the zones doesn't matter, only the center of the zone is important. Place the center of these Reference Zones at
|
||||
-- specific scenery objects or points of interest (like cities, rivers, hills, crossing etc).
|
||||
-- The trigger zones indicating a Reference Zone need to follow a specific syntax.
|
||||
-- The name of each trigger zone expressing a Reference Zone need to start with a classification name of the object,
|
||||
-- followed by a #, followed by a symbolic name of the Reference Zone.
|
||||
-- A few examples:
|
||||
--
|
||||
-- * A church at Tskinvali would be indicated as: *Church#Tskinvali*
|
||||
-- * A train station near Kobuleti would be indicated as: *Station#Kobuleti*
|
||||
--
|
||||
-- Taking the above example, this is how this method would be used:
|
||||
--
|
||||
-- CC:SetReferenceZones( "Church" )
|
||||
-- CC:SetReferenceZones( "Station" )
|
||||
--
|
||||
--
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param #string ReferenceZonePrefix The name before the #-mark indicating the class of the Reference Zones.
|
||||
-- @return #COMMANDCENTER
|
||||
function COMMANDCENTER:SetReferenceZones( ReferenceZonePrefix )
|
||||
local MatchPattern = "(.*)#(.*)"
|
||||
self:F( { MatchPattern = MatchPattern } )
|
||||
for ReferenceZoneName in pairs( _DATABASE.ZONENAMES ) do
|
||||
local ZoneName, ReferenceName = string.match( ReferenceZoneName, MatchPattern )
|
||||
self:F( { ZoneName = ZoneName, ReferenceName = ReferenceName } )
|
||||
if ZoneName and ReferenceName and ZoneName == ReferenceZonePrefix then
|
||||
self.ReferencePoints[ReferenceZoneName] = ZONE:New( ReferenceZoneName )
|
||||
self.ReferenceNames[ReferenceZoneName] = ReferenceName
|
||||
end
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set the commandcenter operations in WWII mode
|
||||
-- This will disable LL, MGRS, BRA, BULLS navigatin messages sent by the Command Center,
|
||||
-- and will be replaced by a navigation using Reference Zones.
|
||||
-- It will also disable the settings at the settings menu for these.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return #COMMANDCENTER
|
||||
function COMMANDCENTER:SetModeWWII()
|
||||
self.CommunicationMode = "WWII"
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Returns if the commandcenter operations is in WWII mode
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return #boolean true if in WWII mode.
|
||||
function COMMANDCENTER:IsModeWWII()
|
||||
return self.CommunicationMode == "WWII"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Sets the menu structure of the Missions governed by the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:SetMenu()
|
||||
|
||||
@@ -70,14 +70,67 @@ do -- DETECTION MANAGER
|
||||
|
||||
self:SetStartState( "Stopped" )
|
||||
self:AddTransition( "Stopped", "Start", "Started" )
|
||||
|
||||
--- Start Handler OnBefore for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] OnBeforeStart
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Start Handler OnAfter for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] OnAfterStart
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Start Trigger for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] Start
|
||||
-- @param #DETECTION_MANAGER self
|
||||
|
||||
--- Start Asynchronous Trigger for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] __Start
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
|
||||
self:AddTransition( "Started", "Stop", "Stopped" )
|
||||
|
||||
--- Stop Handler OnBefore for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] OnBeforeStop
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- Stop Handler OnAfter for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] OnAfterStop
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- Stop Trigger for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] Stop
|
||||
-- @param #DETECTION_MANAGER self
|
||||
|
||||
--- Stop Asynchronous Trigger for DETECTION_MANAGER
|
||||
-- @function [parent=#DETECTION_MANAGER] __Stop
|
||||
-- @param #DETECTION_MANAGER self
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
self:AddTransition( "Started", "Report", "Started" )
|
||||
|
||||
self:SetReportInterval( 30 )
|
||||
self:SetReportDisplayTime( 25 )
|
||||
|
||||
self:E( { Detection = Detection } )
|
||||
Detection:__Start( 1 )
|
||||
Detection:__Start( 3 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
--- A MISSION is the main owner of a Mission orchestration within MOOSE . The Mission framework orchestrates @{CLIENT}s, @{TASK}s, @{STAGE}s etc.
|
||||
-- A @{CLIENT} needs to be registered within the @{MISSION} through the function @{AddClient}. A @{TASK} needs to be registered within the @{MISSION} through the function @{AddTask}.
|
||||
--- **Tasking** -- A MISSION is the main owner of a Mission orchestration within MOOSE.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Mission
|
||||
|
||||
--- The MISSION class
|
||||
@@ -38,6 +46,7 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
|
||||
self.MissionCoalition = MissionCoalition
|
||||
|
||||
self.Tasks = {}
|
||||
self.PlayerNames = {} -- These are the players that achieved progress in the mission.
|
||||
|
||||
self:SetStartState( "IDLE" )
|
||||
|
||||
@@ -220,6 +229,33 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
|
||||
-- @param #MISSION self
|
||||
-- @param #number Delay The delay in seconds.
|
||||
|
||||
|
||||
self:AddTransition( "*", "MissionGoals", "*" )
|
||||
|
||||
--- MissionGoals Handler OnBefore for MISSION
|
||||
-- @function [parent=#MISSION] OnBeforeMissionGoals
|
||||
-- @param #MISSION self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @return #boolean
|
||||
|
||||
--- MissionGoals Handler OnAfter for MISSION
|
||||
-- @function [parent=#MISSION] OnAfterMissionGoals
|
||||
-- @param #MISSION self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
|
||||
--- MissionGoals Trigger for MISSION
|
||||
-- @function [parent=#MISSION] MissionGoals
|
||||
-- @param #MISSION self
|
||||
|
||||
--- MissionGoals Asynchronous Trigger for MISSION
|
||||
-- @function [parent=#MISSION] __MissionGoals
|
||||
-- @param #MISSION self
|
||||
-- @param #number Delay
|
||||
|
||||
-- Private implementations
|
||||
|
||||
CommandCenter:SetMenu()
|
||||
@@ -265,8 +301,6 @@ function MISSION:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
end
|
||||
end
|
||||
|
||||
self:GetCommandCenter():SetMenu()
|
||||
|
||||
return PlayerUnitAdded
|
||||
end
|
||||
|
||||
@@ -416,7 +450,7 @@ do -- Group Assignment
|
||||
local MissionGroupName = MissionGroup:GetName()
|
||||
|
||||
self.AssignedGroups[MissionGroupName] = nil
|
||||
self:E( string.format( "Mission %s is unassigned to %s", MissionName, MissionGroupName ) )
|
||||
--self:E( string.format( "Mission %s is unassigned to %s", MissionName, MissionGroupName ) )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -460,13 +494,17 @@ function MISSION:GetMenu( TaskGroup ) -- R2.1 -- Changed Menu Structure
|
||||
Menu.MainMenu = Menu.MainMenu or MENU_GROUP:New( TaskGroup, self:GetName(), CommandCenterMenu )
|
||||
Menu.BriefingMenu = Menu.BriefingMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Mission Briefing", Menu.MainMenu, self.MenuReportBriefing, self, TaskGroup )
|
||||
|
||||
Menu.ReportsMenu = Menu.ReportsMenu or MENU_GROUP:New( TaskGroup, "Reports", Menu.MainMenu )
|
||||
Menu.ReportTasksMenu = Menu.ReportTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Tasks", Menu.ReportsMenu, self.MenuReportSummary, self, TaskGroup )
|
||||
Menu.ReportPlannedTasksMenu = Menu.ReportPlannedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Planned Tasks", Menu.ReportsMenu, self.MenuReportOverview, self, TaskGroup, "Planned" )
|
||||
Menu.ReportAssignedTasksMenu = Menu.ReportAssignedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Assigned Tasks", Menu.ReportsMenu, self.MenuReportOverview, self, TaskGroup, "Assigned" )
|
||||
Menu.ReportSuccessTasksMenu = Menu.ReportSuccessTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Successful Tasks", Menu.ReportsMenu, self.MenuReportOverview, self, TaskGroup, "Success" )
|
||||
Menu.ReportFailedTasksMenu = Menu.ReportFailedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Failed Tasks", Menu.ReportsMenu, self.MenuReportOverview, self, TaskGroup, "Failed" )
|
||||
Menu.ReportHeldTasksMenu = Menu.ReportHeldTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Held Tasks", Menu.ReportsMenu, self.MenuReportOverview, self, TaskGroup, "Hold" )
|
||||
Menu.TaskReportsMenu = Menu.TaskReportsMenu or MENU_GROUP:New( TaskGroup, "Task Reports", Menu.MainMenu )
|
||||
Menu.ReportTasksMenu = Menu.ReportTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Tasks", Menu.TaskReportsMenu, self.MenuReportTasksSummary, self, TaskGroup )
|
||||
Menu.ReportPlannedTasksMenu = Menu.ReportPlannedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Planned Tasks", Menu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Planned" )
|
||||
Menu.ReportAssignedTasksMenu = Menu.ReportAssignedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Assigned Tasks", Menu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Assigned" )
|
||||
Menu.ReportSuccessTasksMenu = Menu.ReportSuccessTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Successful Tasks", Menu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Success" )
|
||||
Menu.ReportFailedTasksMenu = Menu.ReportFailedTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Failed Tasks", Menu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Failed" )
|
||||
Menu.ReportHeldTasksMenu = Menu.ReportHeldTasksMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Held Tasks", Menu.TaskReportsMenu, self.MenuReportTasksPerStatus, self, TaskGroup, "Hold" )
|
||||
|
||||
Menu.PlayerReportsMenu = Menu.PlayerReportsMenu or MENU_GROUP:New( TaskGroup, "Statistics Reports", Menu.MainMenu )
|
||||
Menu.ReportMissionHistory = Menu.ReportPlayersHistory or MENU_GROUP_COMMAND:New( TaskGroup, "Report Mission Progress", Menu.PlayerReportsMenu, self.MenuReportPlayersProgress, self, TaskGroup )
|
||||
Menu.ReportPlayersPerTaskMenu = Menu.ReportPlayersPerTaskMenu or MENU_GROUP_COMMAND:New( TaskGroup, "Report Players per Task", Menu.PlayerReportsMenu, self.MenuReportPlayersPerTask, self, TaskGroup )
|
||||
|
||||
return Menu.MainMenu
|
||||
end
|
||||
@@ -625,6 +663,18 @@ function MISSION:GetTaskTypes()
|
||||
return TaskTypeList
|
||||
end
|
||||
|
||||
|
||||
function MISSION:AddPlayerName( PlayerName )
|
||||
self.PlayerNames = self.PlayerNames or {}
|
||||
self.PlayerNames[PlayerName] = PlayerName
|
||||
return self
|
||||
end
|
||||
|
||||
function MISSION:GetPlayerNames()
|
||||
return self.PlayerNames
|
||||
end
|
||||
|
||||
|
||||
--- Create a briefing report of the Mission.
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
@@ -636,10 +686,9 @@ function MISSION:ReportBriefing()
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
local TasksRemaining = self:GetTasksRemaining()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( "Mission " .. Name .. " - " .. Status .. " - Briefing Report." )
|
||||
Report:Add( string.format( '%s - %s - Mission Briefing Report', Name, Status ) )
|
||||
|
||||
Report:Add( self.MissionBriefing )
|
||||
|
||||
@@ -670,8 +719,7 @@ function MISSION:ReportStatus()
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
local TasksRemaining = self:GetTasksRemaining()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
|
||||
|
||||
@@ -700,17 +748,18 @@ function MISSION:ReportStatus()
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Create a player report of the Mission.
|
||||
|
||||
--- Create an active player report of the Mission.
|
||||
-- This reports provides a one liner of the mission status. It indicates how many players and how many Tasks.
|
||||
--
|
||||
-- Mission "<MissionName>" - Status "<MissionStatus>"
|
||||
-- Mission "<MissionName>" - <MissionStatus> - Active Players Report
|
||||
-- - Player "<PlayerName>: Task <TaskName> <TaskStatus>, Task <TaskName> <TaskStatus>
|
||||
-- - Player <PlayerName>: Task <TaskName> <TaskStatus>, Task <TaskName> <TaskStatus>
|
||||
-- - ..
|
||||
--
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
function MISSION:ReportPlayers()
|
||||
function MISSION:ReportPlayersPerTask( ReportGroup )
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
@@ -718,10 +767,9 @@ function MISSION:ReportPlayers()
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
local TasksRemaining = self:GetTasksRemaining()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
|
||||
Report:Add( string.format( '%s - %s - Players per Task Report', Name, Status ) )
|
||||
|
||||
local PlayerList = {}
|
||||
|
||||
@@ -729,7 +777,7 @@ function MISSION:ReportPlayers()
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
local PlayerNames = Task:GetPlayerNames()
|
||||
for PlayerID, PlayerName in pairs( PlayerNames ) do
|
||||
for PlayerName, PlayerGroup in pairs( PlayerNames ) do
|
||||
PlayerList[PlayerName] = Task:GetName()
|
||||
end
|
||||
|
||||
@@ -742,6 +790,56 @@ function MISSION:ReportPlayers()
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Create an Mission Progress report of the Mission.
|
||||
-- This reports provides a one liner per player of the mission achievements per task.
|
||||
--
|
||||
-- Mission "<MissionName>" - <MissionStatus> - Active Players Report
|
||||
-- - Player <PlayerName>: Task <TaskName> <TaskStatus>: <Progress>
|
||||
-- - Player <PlayerName>: Task <TaskName> <TaskStatus>: <Progress>
|
||||
-- - ..
|
||||
--
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
function MISSION:ReportPlayersProgress( ReportGroup )
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
-- List the name of the mission.
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( string.format( '%s - %s - Players per Task Progress Report', Name, Status ) )
|
||||
|
||||
local PlayerList = {}
|
||||
|
||||
-- Determine how many tasks are remaining.
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
local TaskGoalTotal = Task:GetGoalTotal() or 0
|
||||
local TaskName = Task:GetName()
|
||||
PlayerList[TaskName] = PlayerList[TaskName] or {}
|
||||
if TaskGoalTotal ~= 0 then
|
||||
local PlayerNames = self:GetPlayerNames()
|
||||
for PlayerName, PlayerData in pairs( PlayerNames ) do
|
||||
PlayerList[TaskName][PlayerName] = string.format( 'Player (%s): Task "%s": %d%%', PlayerName, TaskName, Task:GetPlayerProgress( PlayerName ) * 100 / TaskGoalTotal )
|
||||
end
|
||||
else
|
||||
PlayerList[TaskName]["_"] = string.format( 'Player (---): Task "%s": %d%%', TaskName, 0 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for TaskName, TaskData in pairs( PlayerList ) do
|
||||
for PlayerName, TaskText in pairs( TaskData ) do
|
||||
Report:Add( string.format( ' - %s', TaskText ) )
|
||||
end
|
||||
end
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
|
||||
--- Create a summary report of the Mission (one line).
|
||||
-- @param #MISSION self
|
||||
@@ -754,10 +852,9 @@ function MISSION:ReportSummary()
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
local TasksRemaining = self:GetTasksRemaining()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( "Mission " .. Name .. " - " .. Status .. " - " .. TasksRemaining .. " tasks remaining." )
|
||||
Report:Add( string.format( '%s - %s - Task Overview Report', Name, Status ) )
|
||||
|
||||
-- Determine how many tasks are remaining.
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
@@ -771,7 +868,7 @@ end
|
||||
--- Create a overview report of the Mission (multiple lines).
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
function MISSION:ReportOverview( TaskStatus )
|
||||
function MISSION:ReportOverview( ReportGroup, TaskStatus )
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
@@ -779,17 +876,16 @@ function MISSION:ReportOverview( TaskStatus )
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
local TasksRemaining = self:GetTasksRemaining()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
|
||||
Report:Add( string.format( '%s - %s - %s Tasks Report', Name, Status, TaskStatus ) )
|
||||
|
||||
-- Determine how many tasks are remaining.
|
||||
local TasksRemaining = 0
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
for TaskID, Task in UTILS.spairs( self:GetTasks(), function( t, a, b ) return t[a]:ReportOrder( ReportGroup ) < t[b]:ReportOrder( ReportGroup ) end ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
if Task:Is( TaskStatus ) then
|
||||
Report:Add( "\n - " .. Task:ReportOverview() )
|
||||
Report:Add( " - " .. Task:ReportOverview( ReportGroup ) )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -799,7 +895,7 @@ end
|
||||
--- Create a detailed report of the Mission, listing all the details of the Task.
|
||||
-- @param #MISSION self
|
||||
-- @return #string
|
||||
function MISSION:ReportDetails()
|
||||
function MISSION:ReportDetails( ReportGroup )
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
@@ -807,15 +903,15 @@ function MISSION:ReportDetails()
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the mission.
|
||||
local Status = self:GetState()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( string.format( '%s - Status "%s"', Name, Status ) )
|
||||
Report:Add( string.format( '%s - %s - Task Detailed Report', Name, Status ) )
|
||||
|
||||
-- Determine how many tasks are remaining.
|
||||
local TasksRemaining = 0
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Report:Add( Task:ReportDetails() )
|
||||
Report:Add( Task:ReportDetails( ReportGroup ) )
|
||||
end
|
||||
|
||||
return Report:Text()
|
||||
@@ -832,6 +928,9 @@ function MISSION:GetTasks()
|
||||
return self.Tasks
|
||||
end
|
||||
|
||||
--- Reports the briefing.
|
||||
-- @param #MISSION self
|
||||
-- @param Wrapper.Group#GROUP ReportGroup The group to which the report needs to be sent.
|
||||
function MISSION:MenuReportBriefing( ReportGroup )
|
||||
|
||||
local Report = self:ReportBriefing()
|
||||
@@ -840,21 +939,50 @@ function MISSION:MenuReportBriefing( ReportGroup )
|
||||
end
|
||||
|
||||
|
||||
--- @param #MISSION self
|
||||
|
||||
--- Report the task summary.
|
||||
-- @param #MISSION self
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
function MISSION:MenuReportSummary( ReportGroup )
|
||||
function MISSION:MenuReportTasksSummary( ReportGroup )
|
||||
|
||||
local Report = self:ReportSummary()
|
||||
|
||||
self:GetCommandCenter():MessageToGroup( Report, ReportGroup )
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- @param #MISSION self
|
||||
-- @param #string TaskStatus The status
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
function MISSION:MenuReportOverview( ReportGroup, TaskStatus )
|
||||
function MISSION:MenuReportTasksPerStatus( ReportGroup, TaskStatus )
|
||||
|
||||
local Report = self:ReportOverview( TaskStatus )
|
||||
local Report = self:ReportOverview( ReportGroup, TaskStatus )
|
||||
|
||||
self:GetCommandCenter():MessageToGroup( Report, ReportGroup )
|
||||
end
|
||||
|
||||
|
||||
--- @param #MISSION self
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
function MISSION:MenuReportPlayersPerTask( ReportGroup )
|
||||
|
||||
local Report = self:ReportPlayersPerTask()
|
||||
|
||||
self:GetCommandCenter():MessageToGroup( Report, ReportGroup )
|
||||
end
|
||||
|
||||
--- @param #MISSION self
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
function MISSION:MenuReportPlayersProgress( ReportGroup )
|
||||
|
||||
local Report = self:ReportPlayersProgress()
|
||||
|
||||
self:GetCommandCenter():MessageToGroup( Report, ReportGroup )
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
--- **Tasking** -- This module contains the TASK class.
|
||||
--- **Tasking** -- This module contains the TASK class, the main engine to run human taskings.
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ===
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Authors: FlightControl - Design and Programming
|
||||
-- ====
|
||||
--
|
||||
-- @module Task
|
||||
|
||||
@@ -169,6 +170,36 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
||||
self:AddTransition( "Assigned", "Fail", "Failed" )
|
||||
self:AddTransition( "Assigned", "Abort", "Aborted" )
|
||||
self:AddTransition( "Assigned", "Cancel", "Cancelled" )
|
||||
self:AddTransition( "Assigned", "Goal", "*" )
|
||||
|
||||
--- 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
|
||||
-- @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
|
||||
|
||||
--- Goal Trigger for TASK
|
||||
-- @function [parent=#TASK] Goal
|
||||
-- @param #TASK self
|
||||
|
||||
--- Goal Asynchronous Trigger for TASK
|
||||
-- @function [parent=#TASK] __Goal
|
||||
-- @param #TASK self
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
|
||||
self:AddTransition( "*", "PlayerCrashed", "*" )
|
||||
self:AddTransition( "*", "PlayerAborted", "*" )
|
||||
self:AddTransition( "*", "PlayerDead", "*" )
|
||||
@@ -195,6 +226,8 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
||||
|
||||
self.TaskInfo = {}
|
||||
|
||||
self.TaskProgress = {}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -276,7 +309,7 @@ function TASK:AbortGroup( PlayerGroup )
|
||||
self:E( { IsGroupAssigned = IsGroupAssigned } )
|
||||
if IsGroupAssigned then
|
||||
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
|
||||
self:MessageToGroups( PlayerName .. " aborted Task " .. self:GetName() )
|
||||
--self:MessageToGroups( PlayerName .. " aborted Task " .. self:GetName() )
|
||||
self:UnAssignFromGroup( PlayerGroup )
|
||||
--self:Abort()
|
||||
|
||||
@@ -436,7 +469,7 @@ do -- Group Assignment
|
||||
local TaskGroupName = TaskGroup:GetName()
|
||||
|
||||
self.AssignedGroups[TaskGroupName] = nil
|
||||
self:E( string.format( "Task %s is unassigned to %s", TaskName, TaskGroupName ) )
|
||||
--self:E( string.format( "Task %s is unassigned to %s", TaskName, TaskGroupName ) )
|
||||
|
||||
-- Set the group to be assigned at mission level. This allows to decide the menu options on mission level for this group.
|
||||
self:GetMission():ClearGroupAssignment( TaskGroup )
|
||||
@@ -446,9 +479,9 @@ do -- Group Assignment
|
||||
SetAssignedGroups:ForEachGroup(
|
||||
function( AssignedGroup )
|
||||
if self:IsGroupAssigned(AssignedGroup) then
|
||||
self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is unassigned from group %s.", TaskName, TaskGroupName ), AssignedGroup )
|
||||
--self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is unassigned from group %s.", TaskName, TaskGroupName ), AssignedGroup )
|
||||
else
|
||||
self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is unassigned from your group.", TaskName ), AssignedGroup )
|
||||
--self:GetMission():GetCommandCenter():MessageToGroup( string.format( "Task %s is unassigned from your group.", TaskName ), AssignedGroup )
|
||||
end
|
||||
end
|
||||
)
|
||||
@@ -478,7 +511,7 @@ do -- Group Assignment
|
||||
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local PlayerName = TaskUnit:GetPlayerName()
|
||||
self:E(PlayerName)
|
||||
if PlayerName ~= nil or PlayerName ~= "" then
|
||||
if PlayerName ~= nil and PlayerName ~= "" then
|
||||
self:AssignToUnit( TaskUnit )
|
||||
CommandCenter:MessageToGroup(
|
||||
string.format( 'Task "%s": Briefing for player (%s):\n%s',
|
||||
@@ -497,8 +530,9 @@ do -- Group Assignment
|
||||
|
||||
--- UnAssign the @{Task} from a @{Group}.
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
function TASK:UnAssignFromGroup( TaskGroup )
|
||||
self:F2( { TaskGroup } )
|
||||
self:F2( { TaskGroup = TaskGroup:GetName() } )
|
||||
|
||||
self:ClearGroupAssignment( TaskGroup )
|
||||
|
||||
@@ -506,7 +540,7 @@ do -- Group Assignment
|
||||
for UnitID, UnitData in pairs( TaskUnits ) do
|
||||
local TaskUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local PlayerName = TaskUnit:GetPlayerName()
|
||||
if PlayerName ~= nil or PlayerName ~= "" then
|
||||
if PlayerName ~= nil and PlayerName ~= "" then -- Only remove units that have players!
|
||||
self:UnAssignFromUnit( TaskUnit )
|
||||
end
|
||||
end
|
||||
@@ -540,7 +574,6 @@ function TASK:AssignToUnit( TaskUnit )
|
||||
|
||||
-- Assign a new FsmUnit to TaskUnit.
|
||||
local FsmUnit = self:SetStateMachine( TaskUnit, FsmTemplate:Copy( TaskUnit, self ) ) -- Core.Fsm#FSM_PROCESS
|
||||
self:E({"Address FsmUnit", tostring( FsmUnit ) } )
|
||||
|
||||
FsmUnit:SetStartState( "Planned" )
|
||||
|
||||
@@ -669,9 +702,11 @@ end
|
||||
-- @return #TASK
|
||||
function TASK:SetMenuForGroup( TaskGroup, MenuTime )
|
||||
|
||||
self:SetPlannedMenuForGroup( TaskGroup, MenuTime )
|
||||
if self:IsGroupAssigned( TaskGroup ) then
|
||||
self:SetAssignedMenuForGroup( TaskGroup, MenuTime )
|
||||
if self:IsStatePlanned() or self:IsStateAssigned() then
|
||||
self:SetPlannedMenuForGroup( TaskGroup, MenuTime )
|
||||
if self:IsGroupAssigned( TaskGroup ) then
|
||||
self:SetAssignedMenuForGroup( TaskGroup, MenuTime )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -703,7 +738,7 @@ function TASK:SetPlannedMenuForGroup( TaskGroup, MenuTime )
|
||||
|
||||
--local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
|
||||
local TaskPlannedMenu = MENU_GROUP:New( TaskGroup, "Planned Tasks", MissionMenu ):SetTime( MenuTime )
|
||||
local TaskPlannedMenu = MENU_GROUP:New( TaskGroup, "Join Planned Task", MissionMenu, Mission.MenuReportTasksPerStatus, Mission, TaskGroup, "Planned" ):SetTime( MenuTime )
|
||||
local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskType, TaskPlannedMenu ):SetTime( MenuTime ):SetRemoveParent( true )
|
||||
local TaskTypeMenu = MENU_GROUP:New( TaskGroup, TaskText, TaskTypeMenu ):SetTime( MenuTime ):SetRemoveParent( true )
|
||||
local ReportTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Status" ), TaskTypeMenu, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetRemoveParent( true )
|
||||
@@ -825,7 +860,7 @@ end
|
||||
-- @param #TASK self
|
||||
function TASK:MenuTaskStatus( TaskGroup )
|
||||
|
||||
local ReportText = self:ReportDetails()
|
||||
local ReportText = self:ReportDetails( TaskGroup )
|
||||
|
||||
self:T( ReportText )
|
||||
self:GetMission():GetCommandCenter():MessageToGroup( ReportText, TaskGroup )
|
||||
@@ -912,7 +947,7 @@ end
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK self
|
||||
function TASK:RemoveStateMachine( TaskUnit )
|
||||
self:F( { TaskUnit, self.Fsm[TaskUnit] ~= nil } )
|
||||
self:F( { TaskUnit = TaskUnit:GetName(), HasFsm = ( self.Fsm[TaskUnit] ~= nil ) } )
|
||||
|
||||
--self:E( self.Fsm )
|
||||
--for TaskUnitT, Fsm in pairs( self.Fsm ) do
|
||||
@@ -921,13 +956,16 @@ function TASK:RemoveStateMachine( TaskUnit )
|
||||
--self.Fsm[TaskUnit] = nil
|
||||
--end
|
||||
|
||||
self.Fsm[TaskUnit]:Remove()
|
||||
self.Fsm[TaskUnit] = nil
|
||||
if self.Fsm[TaskUnit] then
|
||||
self.Fsm[TaskUnit]:Remove()
|
||||
self.Fsm[TaskUnit] = nil
|
||||
end
|
||||
|
||||
collectgarbage()
|
||||
self:E( "Garbage Collected, Processes should be finalized now ...")
|
||||
end
|
||||
|
||||
|
||||
--- Checks if there is a FiniteStateMachine assigned to Task@{Unit} for @{Task}
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
@@ -981,10 +1019,15 @@ end
|
||||
|
||||
--- Sets the Information on the Task
|
||||
-- @param #TASK self
|
||||
-- @param #string TaskInfo
|
||||
function TASK:SetInfo( TaskInfo, TaskInfoText )
|
||||
-- @param #string TaskInfo The key and title of the task information.
|
||||
-- @param #string TaskInfoText The Task info text.
|
||||
-- @param #number TaskInfoOrder The ordering, a number between 0 and 99.
|
||||
function TASK:SetInfo( TaskInfo, TaskInfoText, TaskInfoOrder )
|
||||
|
||||
self.TaskInfo[TaskInfo] = TaskInfoText
|
||||
self.TaskInfo = self.TaskInfo or {}
|
||||
self.TaskInfo[TaskInfo] = self.TaskInfo[TaskInfo] or {}
|
||||
self.TaskInfo[TaskInfo].TaskInfoText = TaskInfoText
|
||||
self.TaskInfo[TaskInfo].TaskInfoOrder = TaskInfoOrder
|
||||
end
|
||||
|
||||
--- Gets the Type of the Task
|
||||
@@ -1146,10 +1189,17 @@ end
|
||||
-- @param #string To
|
||||
function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
|
||||
|
||||
self:E( { "Task Assigned", self.Dispatcher } )
|
||||
|
||||
|
||||
--- This test is required, because the state transition will be fired also when the state does not change in case of an event.
|
||||
if From ~= "Assigned" then
|
||||
self:E( { From, Event, To, PlayerUnit:GetName(), PlayerName } )
|
||||
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is assigned." )
|
||||
|
||||
-- Set the total Progress to be achieved.
|
||||
|
||||
self:SetGoalTotal() -- Polymorphic to set the initial goal total!
|
||||
|
||||
if self.Dispatcher then
|
||||
self:E( "Firing Assign event " )
|
||||
self.Dispatcher:Assign( self, PlayerUnit, PlayerName )
|
||||
@@ -1157,6 +1207,9 @@ 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:SetMenu()
|
||||
end
|
||||
end
|
||||
@@ -1174,7 +1227,7 @@ function TASK:onenterSuccess( From, Event, To )
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is successful! Good job!" )
|
||||
self:UnAssignFromGroups()
|
||||
|
||||
--self:GetMission():__Complete( 1 )
|
||||
self:GetMission():__MissionGoals( 1 )
|
||||
|
||||
end
|
||||
|
||||
@@ -1296,9 +1349,9 @@ function TASK:ReportSummary() --R2.1 fixed report. Now nicely formatted and cont
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the Task.
|
||||
local State = self:GetState()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
Report:Add( "Task " .. Name .. " - State '" .. State )
|
||||
Report:Add( 'Task ' .. Name .. ' - State ' .. Status )
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
@@ -1307,20 +1360,53 @@ end
|
||||
-- List the Task Name and Status
|
||||
-- @param #TASK self
|
||||
-- @return #string
|
||||
function TASK:ReportOverview() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
function TASK:ReportOverview( ReportGroup ) --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
|
||||
local Report = REPORT:New()
|
||||
|
||||
-- List the name of the Task.
|
||||
local Name = self:GetName()
|
||||
local TaskName = self:GetName()
|
||||
local Report = REPORT:New()
|
||||
|
||||
-- Determine the status of the Task.
|
||||
local State = self:GetState()
|
||||
|
||||
local Detection = self.TaskInfo["Detection"] and " - " .. self.TaskInfo["Detection"] or ""
|
||||
|
||||
Report:Add( "Task " .. Name .. Detection )
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
local Line = 0
|
||||
local LineReport = REPORT:New()
|
||||
|
||||
for TaskInfoID, TaskInfo in UTILS.spairs( self.TaskInfo, function( t, a, b ) return t[a].TaskInfoOrder < t[b].TaskInfoOrder end ) do
|
||||
|
||||
self:F( { TaskInfo = TaskInfo } )
|
||||
|
||||
if Line < math.floor( TaskInfo.TaskInfoOrder / 10 ) then
|
||||
if Line ~= 0 then
|
||||
Report:AddIndent( LineReport:Text( ", " ) )
|
||||
else
|
||||
Report:Add( TaskName .. ":" .. LineReport:Text( ", " ))
|
||||
end
|
||||
LineReport = REPORT:New()
|
||||
Line = math.floor( TaskInfo.TaskInfoOrder / 10 )
|
||||
end
|
||||
|
||||
local TaskInfoIDText = string.format( "%s: ", TaskInfoID )
|
||||
|
||||
if type( TaskInfo.TaskInfoText ) == "string" then
|
||||
LineReport: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 )
|
||||
LineReport:Add( ToCoordinate:ToString( ReportGroup ) )
|
||||
--Report:AddIndent( ToCoordinate:ToStringBULLS( ReportGroup:GetCoalition() ) )
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
Report:AddIndent( LineReport:Text( ", " ) )
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
@@ -1369,8 +1455,9 @@ end
|
||||
--- Create a detailed report of the Task.
|
||||
-- List the Task Status, and the Players assigned to the Task.
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @return #string
|
||||
function TASK:ReportDetails() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
function TASK:ReportDetails( ReportGroup )
|
||||
|
||||
local Report = REPORT:New():SetIndent( 3 )
|
||||
|
||||
@@ -1378,7 +1465,7 @@ function TASK:ReportDetails() --R2.1 fixed report. Now nicely formatted and cont
|
||||
local Name = self:GetName()
|
||||
|
||||
-- Determine the status of the Task.
|
||||
local State = self:GetState()
|
||||
local Status = "<" .. self:GetState() .. ">"
|
||||
|
||||
-- Loop each Unit active in the Task, and find Player Names.
|
||||
local PlayerNames = self:GetPlayerNames()
|
||||
@@ -1389,19 +1476,111 @@ function TASK:ReportDetails() --R2.1 fixed report. Now nicely formatted and cont
|
||||
end
|
||||
local Players = PlayerReport:Text()
|
||||
|
||||
local Detection = self.TaskInfo["Detection"] or ""
|
||||
local Changes = self.TaskInfo["Changes"] or ""
|
||||
|
||||
Report:Add( "Task: " .. Name .. " - " .. State .. " - Detailed Report" )
|
||||
Report:Add( "\n - Players:" )
|
||||
Report:Add( "Task: " .. Name .. " - " .. Status .. " - Detailed Report" )
|
||||
Report:Add( " - Players:" )
|
||||
Report:AddIndent( Players )
|
||||
Report:Add( "\n - Detection:" )
|
||||
Report:AddIndent( Detection )
|
||||
Report:Add( "\n - Detection Changes:" )
|
||||
Report:AddIndent( Changes )
|
||||
|
||||
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 )
|
||||
Report:AddIndent( ToCoordinate:ToStringBRA( FromCoordinate ) .. ", " .. TaskInfo.TaskInfoText:ToStringAspect( FromCoordinate ) )
|
||||
Report:AddIndent( ToCoordinate:ToStringBULLS( ReportGroup:GetCoalition() ) )
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
|
||||
end -- Reporting
|
||||
|
||||
|
||||
do -- Additional Task Scoring and Task Progress
|
||||
|
||||
--- Add Task Progress for a Player Name
|
||||
-- @param #TASK self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #string ProgressText The text that explains the Progress achieved.
|
||||
-- @param #number ProgressTime The time the progress was achieved.
|
||||
-- @oaram #number ProgressPoints The amount of points of magnitude granted. This will determine the shared Mission Success scoring.
|
||||
-- @return #TASK
|
||||
function TASK:AddProgress( PlayerName, ProgressText, ProgressTime, ProgressPoints )
|
||||
self.TaskProgress = self.TaskProgress or {}
|
||||
self.TaskProgress[ProgressTime] = self.TaskProgress[ProgressTime] or {}
|
||||
self.TaskProgress[ProgressTime].PlayerName = PlayerName
|
||||
self.TaskProgress[ProgressTime].ProgressText = ProgressText
|
||||
self.TaskProgress[ProgressTime].ProgressPoints = ProgressPoints
|
||||
self:GetMission():AddPlayerName( PlayerName )
|
||||
return self
|
||||
end
|
||||
|
||||
function TASK:GetPlayerProgress( PlayerName )
|
||||
local ProgressPlayer = 0
|
||||
for ProgressTime, ProgressData in pairs( self.TaskProgress ) do
|
||||
if PlayerName == ProgressData.PlayerName then
|
||||
ProgressPlayer = ProgressPlayer + ProgressData.ProgressPoints
|
||||
end
|
||||
end
|
||||
return ProgressPlayer
|
||||
end
|
||||
|
||||
--- Set a score when progress has been made by the player.
|
||||
-- @param #TASK self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK
|
||||
function TASK:SetScoreOnProgress( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "AccountPlayer", "Player " .. PlayerName .. " has achieved progress.", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a score when all the targets in scope of the A2A attack, have been destroyed.
|
||||
-- @param #TASK self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK
|
||||
function TASK:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Success", "The task is a success!", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a penalty when the A2A attack has failed.
|
||||
-- @param #TASK self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Penalty The penalty in points, must be a negative value!
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK
|
||||
function TASK:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
|
||||
self:F( { PlayerName, Penalty, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Failed", "The task is a failure!", Penalty )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
668
Moose Development/Moose/Tasking/Task_A2A.lua
Normal file
668
Moose Development/Moose/Tasking/Task_A2A.lua
Normal file
@@ -0,0 +1,668 @@
|
||||
--- **Tasking** - The TASK_A2A models tasks for players in Air to Air engagements.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Task_A2A
|
||||
|
||||
do -- TASK_A2A
|
||||
|
||||
--- The TASK_A2A class
|
||||
-- @type TASK_A2A
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
|
||||
--- # TASK_A2A class, extends @{Task#TASK}
|
||||
--
|
||||
-- The TASK_A2A class defines Air To Air tasks for a @{Set} of Target Units,
|
||||
-- based on the tasking capabilities defined in @{Task#TASK}.
|
||||
-- The TASK_A2A is implemented using a @{Fsm#FSM_TASK}, and has the following statuses:
|
||||
--
|
||||
-- * **None**: Start of the process
|
||||
-- * **Planned**: The A2A task is planned.
|
||||
-- * **Assigned**: The A2A task is assigned to a @{Group#GROUP}.
|
||||
-- * **Success**: The A2A task is successfully completed.
|
||||
-- * **Failed**: The A2A task has failed. This will happen if the player exists the task early, without communicating a possible cancellation to HQ.
|
||||
--
|
||||
-- # 1.1) Set the scoring of achievements in an A2A attack.
|
||||
--
|
||||
-- Scoring or penalties can be given in the following circumstances:
|
||||
--
|
||||
-- * @{#TASK_A2A.SetScoreOnDestroy}(): Set a score when a target in scope of the A2A attack, has been destroyed.
|
||||
-- * @{#TASK_A2A.SetScoreOnSuccess}(): Set a score when all the targets in scope of the A2A attack, have been destroyed.
|
||||
-- * @{#TASK_A2A.SetPenaltyOnFailed}(): Set a penalty when the A2A attack has failed.
|
||||
--
|
||||
-- @field #TASK_A2A
|
||||
TASK_A2A = {
|
||||
ClassName = "TASK_A2A",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_A2A.
|
||||
-- @param #TASK_A2A self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @param Set#SET_GROUP SetAttack The set of groups for which the Task can be assigned.
|
||||
-- @param #string TaskName The name of the Task.
|
||||
-- @param Set#SET_UNIT UnitSetTargets
|
||||
-- @param #number TargetDistance The distance to Target when the Player is considered to have "arrived" at the engagement range.
|
||||
-- @param Core.Zone#ZONE_BASE TargetZone The target zone, if known.
|
||||
-- If the TargetZone parameter is specified, the player will be routed to the center of the zone where all the targets are assumed to be.
|
||||
-- @return #TASK_A2A self
|
||||
function TASK_A2A:New( Mission, SetAttack, TaskName, TargetSetUnit, TaskType, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK:New( Mission, SetAttack, TaskName, TaskType, TaskBriefing ) ) -- Tasking.Task#TASK_A2A
|
||||
self:F()
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TaskType = TaskType
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "RouteToRendezVous", Rejected = "Reject" } )
|
||||
|
||||
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||
|
||||
Fsm:AddTransition( { "Arrived", "RoutingToRendezVous" }, "ArriveAtRendezVous", "ArrivedAtRendezVous" )
|
||||
|
||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "Engage", "Engaging" )
|
||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "HoldAtRendezVous", "HoldingAtRendezVous" )
|
||||
|
||||
Fsm:AddProcess ( "Engaging", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, self.TaskType ), {} )
|
||||
Fsm:AddTransition( "Engaging", "RouteToTarget", "Engaging" )
|
||||
Fsm:AddProcess( "Engaging", "RouteToTargetZone", ACT_ROUTE_ZONE:New(), {} )
|
||||
Fsm:AddProcess( "Engaging", "RouteToTargetPoint", ACT_ROUTE_POINT:New(), {} )
|
||||
Fsm:AddTransition( "Engaging", "RouteToTargets", "Engaging" )
|
||||
|
||||
-- Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
||||
-- Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_A2A#TASK_A2A Task
|
||||
function Fsm:onafterRouteToRendezVous( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
-- Determine the first Unit from the self.RendezVousSetUnit
|
||||
|
||||
if Task:GetRendezVousZone( TaskUnit ) then
|
||||
self:__RouteToRendezVousZone( 0.1 )
|
||||
else
|
||||
if Task:GetRendezVousCoordinate( TaskUnit ) then
|
||||
self:__RouteToRendezVousPoint( 0.1 )
|
||||
else
|
||||
self:__ArriveAtRendezVous( 0.1 )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task#TASK_A2A Task
|
||||
function Fsm:OnAfterArriveAtRendezVous( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
-- Determine the first Unit from the self.TargetSetUnit
|
||||
|
||||
self:__Engage( 0.1 )
|
||||
end
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task#TASK_A2A Task
|
||||
function Fsm:onafterEngage( TaskUnit, Task )
|
||||
self:E( { self } )
|
||||
self:__Account( 0.1 )
|
||||
self:__RouteToTarget(0.1 )
|
||||
self:__RouteToTargets( -10 )
|
||||
end
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_A2A#TASK_A2A Task
|
||||
function Fsm:onafterRouteToTarget( 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:__RouteToTargetZone( 0.1 )
|
||||
else
|
||||
local TargetUnit = Task.TargetSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
||||
if TargetUnit then
|
||||
local Coordinate = TargetUnit:GetCoordinate()
|
||||
self:T( { TargetCoordinate = Coordinate, Coordinate:GetX(), Coordinate:GetAlt(), Coordinate:GetZ() } )
|
||||
Task:SetTargetCoordinate( TargetUnit:GetCoordinate(), TaskUnit )
|
||||
end
|
||||
self:__RouteToTargetPoint( 0.1 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_A2A#TASK_A2A Task
|
||||
function Fsm:onafterRouteToTargets( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
local TargetUnit = Task.TargetSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
||||
if TargetUnit then
|
||||
Task:SetTargetCoordinate( TargetUnit:GetCoordinate(), TaskUnit )
|
||||
end
|
||||
self:__RouteToTargets( -10 )
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
function TASK_A2A:GetPlannedMenuText()
|
||||
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.TargetSetUnit:GetUnitTypesText() .. " )"
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
-- @param Core.Point#COORDINATE RendezVousCoordinate The Coordinate object referencing to the 2D point where the RendezVous point is located on the map.
|
||||
-- @param #number RendezVousRange The RendezVousRange that defines when the player is considered to have arrived at the RendezVous point.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
function TASK_A2A:SetRendezVousCoordinate( RendezVousCoordinate, RendezVousRange, TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
||||
ActRouteRendezVous:SetCoordinate( RendezVousCoordinate )
|
||||
ActRouteRendezVous:SetRange( RendezVousRange )
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return Core.Point#COORDINATE The Coordinate object referencing to the 2D point where the RendezVous point is located on the map.
|
||||
-- @return #number The RendezVousRange that defines when the player is considered to have arrived at the RendezVous point.
|
||||
function TASK_A2A:GetRendezVousCoordinate( TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
||||
return ActRouteRendezVous:GetCoordinate(), ActRouteRendezVous:GetRange()
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
-- @param Core.Zone#ZONE_BASE RendezVousZone The Zone object where the RendezVous is located on the map.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
function TASK_A2A:SetRendezVousZone( RendezVousZone, TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
||||
ActRouteRendezVous:SetZone( RendezVousZone )
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return Core.Zone#ZONE_BASE The Zone object where the RendezVous is located on the map.
|
||||
function TASK_A2A:GetRendezVousZone( TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteRendezVous = ProcessUnit:GetProcess( "RoutingToRendezVous", "RouteToRendezVousZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
||||
return ActRouteRendezVous:GetZone()
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
-- @param Core.Point#COORDINATE TargetCoordinate The Coordinate object where the Target is located on the map.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
function TASK_A2A:SetTargetCoordinate( TargetCoordinate, TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
||||
ActRouteTarget:SetCoordinate( TargetCoordinate )
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return Core.Point#COORDINATE The Coordinate object where the Target is located on the map.
|
||||
function TASK_A2A:GetTargetCoordinate( TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
||||
return ActRouteTarget:GetCoordinate()
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_A2A 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_A2A:SetTargetZone( TargetZone, Altitude, Heading, TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
||||
ActRouteTarget:SetZone( TargetZone, Altitude, Heading )
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_A2A self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
|
||||
function TASK_A2A:GetTargetZone( TaskUnit )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local ActRouteTarget = ProcessUnit:GetProcess( "Engaging", "RouteToTargetZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
||||
return ActRouteTarget:GetZone()
|
||||
end
|
||||
|
||||
function TASK_A2A:SetGoalTotal()
|
||||
|
||||
self.GoalTotal = self.TargetSetUnit:Count()
|
||||
end
|
||||
|
||||
function TASK_A2A:GetGoalTotal()
|
||||
|
||||
return self.GoalTotal
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
do -- TASK_A2A_INTERCEPT
|
||||
|
||||
--- The TASK_A2A_INTERCEPT class
|
||||
-- @type TASK_A2A_INTERCEPT
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
|
||||
--- # TASK_A2A_INTERCEPT class, extends @{Task_A2A#TASK_A2A}
|
||||
--
|
||||
-- The TASK_A2A_INTERCEPT class defines an intercept task for a human player to be executed.
|
||||
-- When enemy planes need to be intercepted by human players, use this task type to urgen the players to get out there!
|
||||
--
|
||||
-- The TASK_A2A_INTERCEPT is used by the @{Task_A2A_Dispatcher#TASK_A2A_DISPATCHER} to automatically create intercept tasks
|
||||
-- based on detected airborne enemy targets intruding friendly airspace.
|
||||
--
|
||||
-- The task is defined for a @{Mission#MISSION}, where a friendly @{Set#SET_GROUP} consisting of GROUPs with one human players each, is intercepting the targets.
|
||||
-- The task is given a name and a briefing, that is used in the menu structure and in the reporting.
|
||||
--
|
||||
-- @field #TASK_A2A_INTERCEPT
|
||||
TASK_A2A_INTERCEPT = {
|
||||
ClassName = "TASK_A2A_INTERCEPT",
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Instantiates a new TASK_A2A_INTERCEPT.
|
||||
-- @param #TASK_A2A_INTERCEPT 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.Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskBriefing The briefing of the task.
|
||||
-- @return #TASK_A2A_INTERCEPT
|
||||
function TASK_A2A_INTERCEPT:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2A:New( Mission, SetGroup, TaskName, TargetSetUnit, "INTERCEPT", TaskBriefing ) ) -- #TASK_A2A_INTERCEPT
|
||||
self:F()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
--TODO: Add BR, Altitude, type of planes...
|
||||
|
||||
self:SetBriefing(
|
||||
TaskBriefing or
|
||||
"Intercept incoming intruders.\n"
|
||||
)
|
||||
|
||||
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
|
||||
|
||||
self:SetInfo( "Threat", "[" .. string.rep( "■", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
|
||||
local DetectedItemsCount = TargetSetUnit:Count()
|
||||
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
|
||||
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A_INTERCEPT self
|
||||
-- @param Wrapper.Group#GROUP ReportGroup
|
||||
function TASK_A2A_INTERCEPT:ReportOrder( ReportGroup )
|
||||
self:F( { TaskInfo = self.TaskInfo } )
|
||||
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
|
||||
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
|
||||
|
||||
return Distance
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_A2A_INTERCEPT self
|
||||
function TASK_A2A_INTERCEPT:onafterGoal( TaskUnit, From, Event, To )
|
||||
local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
if TargetSetUnit:Count() == 0 then
|
||||
self:Success()
|
||||
end
|
||||
|
||||
self:__Goal( -10 )
|
||||
end
|
||||
|
||||
--- Set a score when a target in scope of the A2A attack, has been destroyed .
|
||||
-- @param #TASK_A2A_INTERCEPT self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_INTERCEPT
|
||||
function TASK_A2A_INTERCEPT:SetScoreOnProgress( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "AccountForPlayer", "Player " .. PlayerName .. " has intercepted a target.", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a score when all the targets in scope of the A2A attack, have been destroyed.
|
||||
-- @param #TASK_A2A_INTERCEPT self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_INTERCEPT
|
||||
function TASK_A2A_INTERCEPT:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Success", "All targets have been successfully intercepted!", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a penalty when the A2A attack has failed.
|
||||
-- @param #TASK_A2A_INTERCEPT self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Penalty The penalty in points, must be a negative value!
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_INTERCEPT
|
||||
function TASK_A2A_INTERCEPT:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
|
||||
self:F( { PlayerName, Penalty, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Failed", "The intercept has failed!", Penalty )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
do -- TASK_A2A_SWEEP
|
||||
|
||||
--- The TASK_A2A_SWEEP class
|
||||
-- @type TASK_A2A_SWEEP
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
|
||||
--- # TASK_A2A_SWEEP class, extends @{Task_A2A#TASK_A2A}
|
||||
--
|
||||
-- The TASK_A2A_SWEEP class defines a sweep task for a human player to be executed.
|
||||
-- A sweep task needs to be given when targets were detected but somehow the detection was lost.
|
||||
-- Most likely, these enemy planes are hidden in the mountains or are flying under radar.
|
||||
-- These enemy planes need to be sweeped by human players, and use this task type to urge the players to get out there and find those enemy fighters.
|
||||
--
|
||||
-- The TASK_A2A_SWEEP is used by the @{Task_A2A_Dispatcher#TASK_A2A_DISPATCHER} to automatically create sweep tasks
|
||||
-- based on detected airborne enemy targets intruding friendly airspace, for which the detection has been lost for more than 60 seconds.
|
||||
--
|
||||
-- The task is defined for a @{Mission#MISSION}, where a friendly @{Set#SET_GROUP} consisting of GROUPs with one human players each, is sweeping the targets.
|
||||
-- The task is given a name and a briefing, that is used in the menu structure and in the reporting.
|
||||
--
|
||||
-- @field #TASK_A2A_SWEEP
|
||||
TASK_A2A_SWEEP = {
|
||||
ClassName = "TASK_A2A_SWEEP",
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Instantiates a new TASK_A2A_SWEEP.
|
||||
-- @param #TASK_A2A_SWEEP 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.Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskBriefing The briefing of the task.
|
||||
-- @return #TASK_A2A_SWEEP self
|
||||
function TASK_A2A_SWEEP:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2A:New( Mission, SetGroup, TaskName, TargetSetUnit, "SWEEP", TaskBriefing ) ) -- #TASK_A2A_SWEEP
|
||||
self:F()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
--TODO: Add BR, Altitude, type of planes...
|
||||
|
||||
self:SetBriefing(
|
||||
TaskBriefing or
|
||||
"Perform a fighter sweep. Incoming intruders were detected and could be hiding at the location.\n"
|
||||
)
|
||||
|
||||
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
|
||||
|
||||
self:SetInfo( "Assumed Threat", "[" .. string.rep( "■", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
|
||||
local DetectedItemsCount = TargetSetUnit:Count()
|
||||
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
|
||||
self:SetInfo( "Lost Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TASK_A2A_SWEEP:ReportOrder( ReportGroup )
|
||||
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
|
||||
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
|
||||
|
||||
return Distance
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A_SWEEP self
|
||||
function TASK_A2A_SWEEP:onafterGoal( TaskUnit, From, Event, To )
|
||||
local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
if TargetSetUnit:Count() == 0 then
|
||||
self:Success()
|
||||
end
|
||||
|
||||
self:__Goal( -10 )
|
||||
end
|
||||
|
||||
--- Set a score when a target in scope of the A2A attack, has been destroyed .
|
||||
-- @param #TASK_A2A_SWEEP self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_SWEEP
|
||||
function TASK_A2A_SWEEP:SetScoreOnProgress( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "AccountForPlayer", "Player " .. PlayerName .. " has sweeped a target.", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a score when all the targets in scope of the A2A attack, have been destroyed.
|
||||
-- @param #TASK_A2A_SWEEP self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_SWEEP
|
||||
function TASK_A2A_SWEEP:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Success", "All targets have been successfully sweeped!", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a penalty when the A2A attack has failed.
|
||||
-- @param #TASK_A2A_SWEEP self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Penalty The penalty in points, must be a negative value!
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_SWEEP
|
||||
function TASK_A2A_SWEEP:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
|
||||
self:F( { PlayerName, Penalty, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Failed", "The sweep has failed!", Penalty )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
do -- TASK_A2A_ENGAGE
|
||||
|
||||
--- The TASK_A2A_ENGAGE class
|
||||
-- @type TASK_A2A_ENGAGE
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
|
||||
--- # TASK_A2A_ENGAGE class, extends @{Task_A2A#TASK_A2A}
|
||||
--
|
||||
-- The TASK_A2A_ENGAGE class defines an engage task for a human player to be executed.
|
||||
-- When enemy planes are close to human players, use this task type is used urge the players to get out there!
|
||||
--
|
||||
-- The TASK_A2A_ENGAGE is used by the @{Task_A2A_Dispatcher#TASK_A2A_DISPATCHER} to automatically create engage tasks
|
||||
-- based on detected airborne enemy targets intruding friendly airspace.
|
||||
--
|
||||
-- The task is defined for a @{Mission#MISSION}, where a friendly @{Set#SET_GROUP} consisting of GROUPs with one human players each, is engaging the targets.
|
||||
-- The task is given a name and a briefing, that is used in the menu structure and in the reporting.
|
||||
--
|
||||
-- @field #TASK_A2A_ENGAGE
|
||||
TASK_A2A_ENGAGE = {
|
||||
ClassName = "TASK_A2A_ENGAGE",
|
||||
}
|
||||
|
||||
|
||||
|
||||
--- Instantiates a new TASK_A2A_ENGAGE.
|
||||
-- @param #TASK_A2A_ENGAGE 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.Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskBriefing The briefing of the task.
|
||||
-- @return #TASK_A2A_ENGAGE self
|
||||
function TASK_A2A_ENGAGE:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2A:New( Mission, SetGroup, TaskName, TargetSetUnit, "ENGAGE", TaskBriefing ) ) -- #TASK_A2A_ENGAGE
|
||||
self:F()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
--TODO: Add BR, Altitude, type of planes...
|
||||
|
||||
self:SetBriefing(
|
||||
TaskBriefing or
|
||||
"Bogeys are nearby! Players close by are ordered to ENGAGE the intruders!\n"
|
||||
)
|
||||
|
||||
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
|
||||
|
||||
self:SetInfo( "Threat", "[" .. string.rep( "■", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
|
||||
local DetectedItemsCount = TargetSetUnit:Count()
|
||||
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
|
||||
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TASK_A2A_ENGAGE:ReportOrder( ReportGroup )
|
||||
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
|
||||
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
|
||||
|
||||
return Distance
|
||||
end
|
||||
|
||||
--- @param #TASK_A2A_ENGAGE self
|
||||
function TASK_A2A_ENGAGE:onafterGoal( TaskUnit, From, Event, To )
|
||||
local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
if TargetSetUnit:Count() == 0 then
|
||||
self:Success()
|
||||
end
|
||||
|
||||
self:__Goal( -10 )
|
||||
end
|
||||
|
||||
--- Set a score when a target in scope of the A2A attack, has been destroyed .
|
||||
-- @param #TASK_A2A_ENGAGE self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_ENGAGE
|
||||
function TASK_A2A_ENGAGE:SetScoreOnProgress( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "AccountForPlayer", "Player " .. PlayerName .. " has engaged and destroyed a target.", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a score when all the targets in scope of the A2A attack, have been destroyed.
|
||||
-- @param #TASK_A2A_ENGAGE self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_ENGAGE
|
||||
function TASK_A2A_ENGAGE:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Success", "All targets have been successfully engaged!", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a penalty when the A2A attack has failed.
|
||||
-- @param #TASK_A2A_ENGAGE self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Penalty The penalty in points, must be a negative value!
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2A_ENGAGE
|
||||
function TASK_A2A_ENGAGE:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
|
||||
self:F( { PlayerName, Penalty, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Failed", "The target engagement has failed!", Penalty )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
593
Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua
Normal file
593
Moose Development/Moose/Tasking/Task_A2A_Dispatcher.lua
Normal file
@@ -0,0 +1,593 @@
|
||||
--- **Tasking** - The TASK_A2A_DISPATCHER creates and manages player TASK_A2A tasks based on detected targets.
|
||||
--
|
||||
-- The @{#TASK_A2A_DISPATCHER} classes implement the dynamic dispatching of tasks upon groups of detected units determined a @{Set} of EWR installation groups.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Task_A2A_Dispatcher
|
||||
|
||||
do -- TASK_A2A_DISPATCHER
|
||||
|
||||
--- TASK_A2A_DISPATCHER class.
|
||||
-- @type TASK_A2A_DISPATCHER
|
||||
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
||||
|
||||
--- # TASK_A2A_DISPATCHER class, extends @{Tasking#DETECTION_MANAGER}
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The @{#TASK_A2A_DISPATCHER} class implements the dynamic dispatching of tasks upon groups of detected units determined a @{Set} of EWR installation groups.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The EWR will detect units, will group them, and will dispatch @{Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
||||
-- Find a summary below describing for which situation a task type is created:
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- * **INTERCEPT Task**: Is created when the target is known, is detected and within a danger zone, and there is no friendly airborne in range.
|
||||
-- * **SWEEP Task**: Is created when the target is unknown, was detected and the last position is only known, and within a danger zone, and there is no friendly airborne in range.
|
||||
-- * **ENGAGE Task**: Is created when the target is known, is detected and within a danger zone, and there is a friendly airborne in range, that will receive this task.
|
||||
--
|
||||
-- ## 1. TASK\_A2A\_DISPATCHER constructor:
|
||||
--
|
||||
-- The @{#TASK_A2A_DISPATCHER.New}() method creates a new TASK\_A2A\_DISPATCHER instance.
|
||||
--
|
||||
-- ### 1.1. Define or set the **Mission**:
|
||||
--
|
||||
-- Tasking is executed to accomplish missions. Therefore, a MISSION object needs to be given as the first parameter.
|
||||
--
|
||||
-- local HQ = GROUP:FindByName( "HQ", "Bravo" )
|
||||
-- local CommandCenter = COMMANDCENTER:New( HQ, "Lima" )
|
||||
-- local Mission = MISSION:New( CommandCenter, "A2A Mission", "High", "Watch the air enemy units being detected.", coalition.side.RED )
|
||||
--
|
||||
-- Missions are governed by COMMANDCENTERS, so, ensure you have a COMMANDCENTER object installed and setup within your mission.
|
||||
-- Create the MISSION object, and hook it under the command center.
|
||||
--
|
||||
-- ### 1.2. Build a set of the groups seated by human players:
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- A set or collection of the groups wherein human players can be seated, these can be clients or units that can be joined as a slot or jumping into.
|
||||
--
|
||||
-- local AttackGroups = SET_GROUP:New():FilterCoalitions( "red" ):FilterPrefixes( "Defender" ):FilterStart()
|
||||
--
|
||||
-- The set is built using the SET_GROUP class. Apply any filter criteria to identify the correct groups for your mission.
|
||||
-- Only these slots or units will be able to execute the mission and will receive tasks for this mission, once available.
|
||||
--
|
||||
-- ### 1.3. Define the **EWR network**:
|
||||
--
|
||||
-- As part of the TASK\_A2A\_DISPATCHER constructor, an EWR network must be given as the third parameter.
|
||||
-- An EWR network, or, Early Warning Radar network, is used to early detect potential airborne targets and to understand the position of patrolling targets of the enemy.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Typically EWR networks are setup using 55G6 EWR, 1L13 EWR, Hawk sr and Patriot str ground based radar units.
|
||||
-- These radars have different ranges and 55G6 EWR and 1L13 EWR radars are Eastern Bloc units (eg Russia, Ukraine, Georgia) while the Hawk and Patriot radars are Western (eg US).
|
||||
-- Additionally, ANY other radar capable unit can be part of the EWR network! Also AWACS airborne units, planes, helicopters can help to detect targets, as long as they have radar.
|
||||
-- The position of these units is very important as they need to provide enough coverage
|
||||
-- to pick up enemy aircraft as they approach so that CAP and GCI flights can be tasked to intercept them.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- Additionally in a hot war situation where the border is no longer respected the placement of radars has a big effect on how fast the war escalates.
|
||||
-- For example if they are a long way forward and can detect enemy planes on the ground and taking off
|
||||
-- they will start to vector CAP and GCI flights to attack them straight away which will immediately draw a response from the other coalition.
|
||||
-- Having the radars further back will mean a slower escalation because fewer targets will be detected and
|
||||
-- therefore less CAP and GCI flights will spawn and this will tend to make just the border area active rather than a melee over the whole map.
|
||||
-- It all depends on what the desired effect is.
|
||||
--
|
||||
-- EWR networks are **dynamically constructed**, that is, they form part of the @{Functional#DETECTION_BASE} object that is given as the input parameter of the TASK\_A2A\_DISPATCHER class.
|
||||
-- By defining in a **smart way the names or name prefixes of the groups** with EWR capable units, these groups will be **automatically added or deleted** from the EWR network,
|
||||
-- increasing or decreasing the radar coverage of the Early Warning System.
|
||||
--
|
||||
-- See the following example to setup an EWR network containing EWR stations and AWACS.
|
||||
--
|
||||
-- local EWRSet = SET_GROUP:New():FilterPrefixes( "EWR" ):FilterCoalitions("red"):FilterStart()
|
||||
--
|
||||
-- local EWRDetection = DETECTION_AREAS:New( EWRSet, 6000 )
|
||||
-- EWRDetection:SetFriendliesRange( 10000 )
|
||||
-- EWRDetection:SetDetectionInterval(30)
|
||||
--
|
||||
-- -- Setup the A2A dispatcher, and initialize it.
|
||||
-- A2ADispatcher = TASK_A2A_DISPATCHER:New( Mission, AttackGroups, EWRDetection )
|
||||
--
|
||||
-- The above example creates a SET_GROUP instance, and stores this in the variable (object) **EWRSet**.
|
||||
-- **EWRSet** is then being configured to filter all active groups with a group name starting with **EWR** to be included in the Set.
|
||||
-- **EWRSet** is then being ordered to start the dynamic filtering. Note that any destroy or new spawn of a group with the above names will be removed or added to the Set.
|
||||
-- Then a new **EWRDetection** object is created from the class DETECTION_AREAS. A grouping radius of 6000 is choosen, which is 6km.
|
||||
-- The **EWRDetection** object is then passed to the @{#TASK_A2A_DISPATCHER.New}() method to indicate the EWR network configuration and setup the A2A tasking and detection mechanism.
|
||||
--
|
||||
-- ### 2. Define the detected **target grouping radius**:
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- The target grouping radius is a property of the Detection object, that was passed to the AI\_A2A\_DISPATCHER object, but can be changed.
|
||||
-- The grouping radius should not be too small, but also depends on the types of planes and the era of the simulation.
|
||||
-- Fast planes like in the 80s, need a larger radius than WWII planes.
|
||||
-- Typically I suggest to use 30000 for new generation planes and 10000 for older era aircraft.
|
||||
--
|
||||
-- Note that detected targets are constantly re-grouped, that is, when certain detected aircraft are moving further than the group radius, then these aircraft will become a separate
|
||||
-- group being detected. This may result in additional GCI being started by the dispatcher! So don't make this value too small!
|
||||
--
|
||||
-- ## 3. Set the **Engage radius**:
|
||||
--
|
||||
-- Define the radius to engage any target by airborne friendlies, which are executing cap or returning from an intercept mission.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- So, if there is a target area detected and reported,
|
||||
-- then any friendlies that are airborne near this target area,
|
||||
-- will be commanded to (re-)engage that target when available (if no other tasks were commanded).
|
||||
-- For example, if 100000 is given as a value, then any friendly that is airborne within 100km from the detected target,
|
||||
-- will be considered to receive the command to engage that target area.
|
||||
-- You need to evaluate the value of this parameter carefully.
|
||||
-- If too small, more intercept missions may be triggered upon detected target areas.
|
||||
-- If too large, any airborne cap may not be able to reach the detected target area in time, because it is too far.
|
||||
--
|
||||
-- ## 4. Set **Scoring** and **Messages**:
|
||||
--
|
||||
-- The TASK\_A2A\_DISPATCHER is a state machine. It triggers the event Assign when a new player joins a @{Task} dispatched by the TASK\_A2A\_DISPATCHER.
|
||||
-- An _event handler_ can be defined to catch the **Assign** event, and add **additional processing** to set _scoring_ and to _define messages_,
|
||||
-- when the player reaches certain achievements in the task.
|
||||
--
|
||||
-- The prototype to handle the **Assign** event needs to be developed as follows:
|
||||
--
|
||||
-- TaskDispatcher = TASK_A2A_DISPATCHER:New( ... )
|
||||
--
|
||||
-- --- @param #TaskDispatcher self
|
||||
-- -- @param #string From Contains the name of the state from where the Event was triggered.
|
||||
-- -- @param #string Event Contains the name of the event that was triggered. In this case Assign.
|
||||
-- -- @param #string To Contains the name of the state that will be transitioned to.
|
||||
-- -- @param Tasking.Task_A2A#TASK_A2A Task The Task object, which is any derived object from TASK_A2A.
|
||||
-- -- @param Wrapper.Unit#UNIT TaskUnit The Unit or Client that contains the Player.
|
||||
-- -- @param #string PlayerName The name of the Player that joined the TaskUnit.
|
||||
-- function TaskDispatcher:OnAfterAssign( From, Event, To, Task, TaskUnit, PlayerName )
|
||||
-- Task:SetScoreOnProgress( PlayerName, 20, TaskUnit )
|
||||
-- Task:SetScoreOnSuccess( PlayerName, 200, TaskUnit )
|
||||
-- Task:SetScoreOnFail( PlayerName, -100, TaskUnit )
|
||||
-- end
|
||||
--
|
||||
-- The **OnAfterAssign** method (function) is added to the TaskDispatcher object.
|
||||
-- This method will be called when a new player joins a unit in the set of groups in scope of the dispatcher.
|
||||
-- So, this method will be called only **ONCE** when a player joins a unit in scope of the task.
|
||||
--
|
||||
-- The TASK class implements various methods to additional **set scoring** for player achievements:
|
||||
--
|
||||
-- * @{Tasking.Task#TASK.SetScoreOnProgress}() will add additional scores when a player achieves **Progress** while executing the task.
|
||||
-- Examples of **task progress** can be destroying units, arriving at zones etc.
|
||||
--
|
||||
-- * @{Tasking.Task#TASK.SetScoreOnSuccess}() will add additional scores when the task goes into **Success** state.
|
||||
-- This means the **task has been successfully completed**.
|
||||
--
|
||||
-- * @{Tasking.Task#TASK.SetScoreOnSuccess}() will add additional (negative) scores when the task goes into **Failed** state.
|
||||
-- This means the **task has not been successfully completed**, and the scores must be given with a negative value!
|
||||
--
|
||||
-- @field #TASK_A2A_DISPATCHER
|
||||
TASK_A2A_DISPATCHER = {
|
||||
ClassName = "TASK_A2A_DISPATCHER",
|
||||
Mission = nil,
|
||||
Detection = nil,
|
||||
Tasks = {},
|
||||
SweepZones = {},
|
||||
}
|
||||
|
||||
|
||||
--- TASK_A2A_DISPATCHER constructor.
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param Tasking.Mission#MISSION Mission The mission for which the task dispatching is done.
|
||||
-- @param Set#SET_GROUP SetGroup The set of groups that can join the tasks within the mission.
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection The detection results that are used to dynamically assign new tasks to human players.
|
||||
-- @return #TASK_A2A_DISPATCHER self
|
||||
function TASK_A2A_DISPATCHER:New( Mission, SetGroup, Detection )
|
||||
|
||||
-- Inherits from DETECTION_MANAGER
|
||||
local self = BASE:Inherit( self, DETECTION_MANAGER:New( SetGroup, Detection ) ) -- #TASK_A2A_DISPATCHER
|
||||
|
||||
self.Detection = Detection
|
||||
self.Mission = Mission
|
||||
|
||||
|
||||
-- TODO: Check detection through radar.
|
||||
self.Detection:FilterCategories( Unit.Category.AIRPLANE, Unit.Category.HELICOPTER )
|
||||
self.Detection:InitDetectRadar( true )
|
||||
self.Detection:SetDetectionInterval( 30 )
|
||||
|
||||
self:AddTransition( "Started", "Assign", "Started" )
|
||||
|
||||
--- OnAfter Transition Handler for Event Assign.
|
||||
-- @function [parent=#TASK_A2A_DISPATCHER] OnAfterAssign
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param #string From The From State string.
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
-- @param Tasking.Task_A2A#TASK_A2A Task
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param #string PlayerName
|
||||
|
||||
self:__Start( 5 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Define the radius to when an ENGAGE task will be generated for any nearby by airborne friendlies, which are executing cap or returning from an intercept mission.
|
||||
-- So, if there is a target area detected and reported,
|
||||
-- then any friendlies that are airborne near this target area,
|
||||
-- will be commanded to (re-)engage that target when available (if no other tasks were commanded).
|
||||
-- An ENGAGE task will be created for those pilots.
|
||||
-- For example, if 100000 is given as a value, then any friendly that is airborne within 100km from the detected target,
|
||||
-- will be considered to receive the command to engage that target area.
|
||||
-- You need to evaluate the value of this parameter carefully.
|
||||
-- If too small, more intercept missions may be triggered upon detected target areas.
|
||||
-- If too large, any airborne cap may not be able to reach the detected target area in time, because it is too far.
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param #number EngageRadius (Optional, Default = 100000) The radius to report friendlies near the target.
|
||||
-- @return #TASK_A2A_DISPATCHER
|
||||
-- @usage
|
||||
--
|
||||
-- -- Set 50km as the radius to engage any target by airborne friendlies.
|
||||
-- TaskA2ADispatcher:SetEngageRadius( 50000 )
|
||||
--
|
||||
-- -- Set 100km as the radius to engage any target by airborne friendlies.
|
||||
-- TaskA2ADispatcher:SetEngageRadius() -- 100000 is the default value.
|
||||
--
|
||||
function TASK_A2A_DISPATCHER:SetEngageRadius( EngageRadius )
|
||||
|
||||
self.Detection:SetFriendliesRange( EngageRadius or 100000 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Creates an INTERCEPT task when there are targets for it.
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
||||
-- @return Set#SET_UNIT TargetSetUnit: The target set of units.
|
||||
-- @return #nil If there are no targets to be set.
|
||||
function TASK_A2A_DISPATCHER:EvaluateINTERCEPT( DetectedItem )
|
||||
self:F( { DetectedItem.ItemID } )
|
||||
|
||||
local DetectedSet = DetectedItem.Set
|
||||
local DetectedZone = DetectedItem.Zone
|
||||
|
||||
-- Check if there is at least one UNIT in the DetectedSet is visible.
|
||||
|
||||
if DetectedItem.IsDetected == true then
|
||||
|
||||
-- Here we're doing something advanced... We're copying the DetectedSet.
|
||||
local TargetSetUnit = SET_UNIT:New()
|
||||
TargetSetUnit:SetDatabase( DetectedSet )
|
||||
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
||||
|
||||
return TargetSetUnit
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Creates an SWEEP task when there are targets for it.
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
||||
-- @return Set#SET_UNIT TargetSetUnit: The target set of units.
|
||||
-- @return #nil If there are no targets to be set.
|
||||
function TASK_A2A_DISPATCHER:EvaluateSWEEP( DetectedItem )
|
||||
self:F( { DetectedItem.ItemID } )
|
||||
|
||||
local DetectedSet = DetectedItem.Set
|
||||
local DetectedZone = DetectedItem.Zone
|
||||
|
||||
|
||||
if DetectedItem.IsDetected == false then
|
||||
|
||||
-- Here we're doing something advanced... We're copying the DetectedSet.
|
||||
local TargetSetUnit = SET_UNIT:New()
|
||||
TargetSetUnit:SetDatabase( DetectedSet )
|
||||
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
||||
|
||||
return TargetSetUnit
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Creates an ENGAGE task when there are human friendlies airborne near the targets.
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
|
||||
-- @return Set#SET_UNIT TargetSetUnit: The target set of units.
|
||||
-- @return #nil If there are no targets to be set.
|
||||
function TASK_A2A_DISPATCHER:EvaluateENGAGE( DetectedItem )
|
||||
self:F( { DetectedItem.ItemID } )
|
||||
|
||||
local DetectedSet = DetectedItem.Set
|
||||
local DetectedZone = DetectedItem.Zone
|
||||
|
||||
local PlayersCount, PlayersReport = self:GetPlayerFriendliesNearBy( DetectedItem )
|
||||
|
||||
|
||||
-- Only allow ENGAGE when there are Players near the zone, and when the Area has detected items since the last run in a 60 seconds time zone.
|
||||
if PlayersCount > 0 and DetectedItem.IsDetected == true then
|
||||
|
||||
-- Here we're doing something advanced... We're copying the DetectedSet.
|
||||
local TargetSetUnit = SET_UNIT:New()
|
||||
TargetSetUnit:SetDatabase( DetectedSet )
|
||||
TargetSetUnit:FilterOnce() -- Filter but don't do any events!!! Elements are added manually upon each detection.
|
||||
|
||||
return TargetSetUnit
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
--- Evaluates the removal of the Task from the Mission.
|
||||
-- Can only occur when the DetectedItem is Changed AND the state of the Task is "Planned".
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Detection#DETECTION_BASE} derived object.
|
||||
-- @param #boolean DetectedItemID
|
||||
-- @param #boolean DetectedItemChange
|
||||
-- @return Tasking.Task#TASK
|
||||
function TASK_A2A_DISPATCHER:EvaluateRemoveTask( Mission, Task, Detection, DetectedItem, DetectedItemIndex, DetectedItemChanged )
|
||||
|
||||
if Task then
|
||||
|
||||
if Task:IsStatePlanned() then
|
||||
local TaskName = Task:GetName()
|
||||
local TaskType = TaskName:match( "(%u+)%.%d+" )
|
||||
|
||||
self:T2( { TaskType = TaskType } )
|
||||
|
||||
local Remove = false
|
||||
|
||||
local IsPlayers = Detection:IsPlayersNearBy( DetectedItem )
|
||||
if TaskType == "ENGAGE" then
|
||||
if IsPlayers == false then
|
||||
Remove = true
|
||||
end
|
||||
end
|
||||
|
||||
if TaskType == "INTERCEPT" then
|
||||
if IsPlayers == true then
|
||||
Remove = true
|
||||
end
|
||||
if DetectedItem.IsDetected == false then
|
||||
Remove = true
|
||||
end
|
||||
end
|
||||
|
||||
if TaskType == "SWEEP" then
|
||||
if DetectedItem.IsDetected == true then
|
||||
Remove = true
|
||||
end
|
||||
end
|
||||
|
||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||
--DetectedSet:Flush()
|
||||
--self:E( { DetectedSetCount = DetectedSet:Count() } )
|
||||
if DetectedSet:Count() == 0 then
|
||||
Remove = true
|
||||
end
|
||||
|
||||
if DetectedItemChanged == true or Remove then
|
||||
--self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
||||
Mission:RemoveTask( Task )
|
||||
self.Tasks[DetectedItemIndex] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Task
|
||||
end
|
||||
|
||||
--- Calculates which friendlies are nearby the area
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param DetectedItem
|
||||
-- @return #number, Core.CommandCenter#REPORT
|
||||
function TASK_A2A_DISPATCHER:GetFriendliesNearBy( DetectedItem )
|
||||
|
||||
local DetectedSet = DetectedItem.Set
|
||||
local FriendlyUnitsNearBy = self.Detection:GetFriendliesNearBy( DetectedItem )
|
||||
|
||||
local FriendlyTypes = {}
|
||||
local FriendliesCount = 0
|
||||
|
||||
if FriendlyUnitsNearBy then
|
||||
local DetectedTreatLevel = DetectedSet:CalculateThreatLevelA2G()
|
||||
for FriendlyUnitName, FriendlyUnitData in pairs( FriendlyUnitsNearBy ) do
|
||||
local FriendlyUnit = FriendlyUnitData -- Wrapper.Unit#UNIT
|
||||
if FriendlyUnit:IsAirPlane() then
|
||||
local FriendlyUnitThreatLevel = FriendlyUnit:GetThreatLevel()
|
||||
FriendliesCount = FriendliesCount + 1
|
||||
local FriendlyType = FriendlyUnit:GetTypeName()
|
||||
FriendlyTypes[FriendlyType] = FriendlyTypes[FriendlyType] and ( FriendlyTypes[FriendlyType] + 1 ) or 1
|
||||
if DetectedTreatLevel < FriendlyUnitThreatLevel + 2 then
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--self:E( { FriendliesCount = FriendliesCount } )
|
||||
|
||||
local FriendlyTypesReport = REPORT:New()
|
||||
|
||||
if FriendliesCount > 0 then
|
||||
for FriendlyType, FriendlyTypeCount in pairs( FriendlyTypes ) do
|
||||
FriendlyTypesReport:Add( string.format("%d of %s", FriendlyTypeCount, FriendlyType ) )
|
||||
end
|
||||
else
|
||||
FriendlyTypesReport:Add( "-" )
|
||||
end
|
||||
|
||||
|
||||
return FriendliesCount, FriendlyTypesReport
|
||||
end
|
||||
|
||||
--- Calculates which HUMAN friendlies are nearby the area
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param DetectedItem
|
||||
-- @return #number, Core.CommandCenter#REPORT
|
||||
function TASK_A2A_DISPATCHER:GetPlayerFriendliesNearBy( DetectedItem )
|
||||
|
||||
local DetectedSet = DetectedItem.Set
|
||||
local PlayersNearBy = self.Detection:GetPlayersNearBy( DetectedItem )
|
||||
|
||||
local PlayerTypes = {}
|
||||
local PlayersCount = 0
|
||||
|
||||
if PlayersNearBy then
|
||||
local DetectedTreatLevel = DetectedSet:CalculateThreatLevelA2G()
|
||||
for PlayerUnitName, PlayerUnitData in pairs( PlayersNearBy ) do
|
||||
local PlayerUnit = PlayerUnitData -- Wrapper.Unit#UNIT
|
||||
local PlayerName = PlayerUnit:GetPlayerName()
|
||||
--self:E( { PlayerName = PlayerName, PlayerUnit = PlayerUnit } )
|
||||
if PlayerUnit:IsAirPlane() and PlayerName ~= nil then
|
||||
local FriendlyUnitThreatLevel = PlayerUnit:GetThreatLevel()
|
||||
PlayersCount = PlayersCount + 1
|
||||
local PlayerType = PlayerUnit:GetTypeName()
|
||||
PlayerTypes[PlayerName] = PlayerType
|
||||
if DetectedTreatLevel < FriendlyUnitThreatLevel + 2 then
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--self:E( { PlayersCount = PlayersCount } )
|
||||
|
||||
local PlayerTypesReport = REPORT:New()
|
||||
|
||||
if PlayersCount > 0 then
|
||||
for PlayerName, PlayerType in pairs( PlayerTypes ) do
|
||||
PlayerTypesReport:Add( string.format('"%s" in %s', PlayerName, PlayerType ) )
|
||||
end
|
||||
else
|
||||
PlayerTypesReport:Add( "-" )
|
||||
end
|
||||
|
||||
|
||||
return PlayersCount, PlayerTypesReport
|
||||
end
|
||||
|
||||
|
||||
--- Assigns tasks in relation to the detected items to the @{Set#SET_GROUP}.
|
||||
-- @param #TASK_A2A_DISPATCHER self
|
||||
-- @param Functional.Detection#DETECTION_BASE Detection The detection created by the @{Detection#DETECTION_BASE} derived object.
|
||||
-- @return #boolean Return true if you want the task assigning to continue... false will cancel the loop.
|
||||
function TASK_A2A_DISPATCHER:ProcessDetected( Detection )
|
||||
self:E()
|
||||
|
||||
local AreaMsg = {}
|
||||
local TaskMsg = {}
|
||||
local ChangeMsg = {}
|
||||
|
||||
local Mission = self.Mission
|
||||
|
||||
if Mission:IsIDLE() or Mission:IsENGAGED() then
|
||||
|
||||
local TaskReport = REPORT:New()
|
||||
|
||||
-- Checking the task queue for the dispatcher, and removing any obsolete task!
|
||||
for TaskIndex, TaskData in pairs( self.Tasks ) do
|
||||
local Task = TaskData -- Tasking.Task#TASK
|
||||
if Task:IsStatePlanned() then
|
||||
local DetectedItem = Detection:GetDetectedItem( TaskIndex )
|
||||
if not DetectedItem then
|
||||
local TaskText = Task:GetName()
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
Mission:GetCommandCenter():MessageToGroup( string.format( "Obsolete A2A task %s for %s removed.", TaskText, Mission:GetName() ), TaskGroup )
|
||||
end
|
||||
Mission:RemoveTask( Task )
|
||||
self.Tasks[TaskIndex] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Now that all obsolete tasks are removed, loop through the detected targets.
|
||||
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
|
||||
|
||||
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||
local DetectedCount = DetectedSet:Count()
|
||||
local DetectedZone = DetectedItem.Zone
|
||||
--self:E( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
|
||||
--DetectedSet:Flush()
|
||||
|
||||
local DetectedID = DetectedItem.ID
|
||||
local TaskIndex = DetectedItem.Index
|
||||
local DetectedItemChanged = DetectedItem.Changed
|
||||
|
||||
local Task = self.Tasks[TaskIndex]
|
||||
Task = self:EvaluateRemoveTask( Mission, Task, Detection, DetectedItem, TaskIndex, DetectedItemChanged ) -- Task will be removed if it is planned and changed.
|
||||
|
||||
-- Evaluate INTERCEPT
|
||||
if not Task and DetectedCount > 0 then
|
||||
local TargetSetUnit = self:EvaluateENGAGE( DetectedItem ) -- Returns a SetUnit if there are targets to be INTERCEPTed...
|
||||
if TargetSetUnit then
|
||||
Task = TASK_A2A_ENGAGE:New( Mission, self.SetGroup, string.format( "ENGAGE.%03d", DetectedID ), TargetSetUnit )
|
||||
else
|
||||
local TargetSetUnit = self:EvaluateINTERCEPT( DetectedItem ) -- Returns a SetUnit if there are targets to be INTERCEPTed...
|
||||
if TargetSetUnit then
|
||||
Task = TASK_A2A_INTERCEPT:New( Mission, self.SetGroup, string.format( "INTERCEPT.%03d", DetectedID ), TargetSetUnit )
|
||||
else
|
||||
local TargetSetUnit = self:EvaluateSWEEP( DetectedItem ) -- Returns a SetUnit
|
||||
if TargetSetUnit then
|
||||
Task = TASK_A2A_SWEEP:New( Mission, self.SetGroup, string.format( "SWEEP.%03d", DetectedID ), TargetSetUnit )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Task then
|
||||
self.Tasks[TaskIndex] = Task
|
||||
Task:SetTargetZone( DetectedZone, DetectedSet:GetFirst():GetAltitude(), DetectedSet:GetFirst():GetHeading() )
|
||||
Task:SetDispatcher( self )
|
||||
Mission:AddTask( Task )
|
||||
|
||||
TaskReport:Add( Task:GetName() )
|
||||
else
|
||||
self:E("This should not happen")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if Task then
|
||||
local FriendliesCount, FriendliesReport = self:GetFriendliesNearBy( DetectedItem )
|
||||
Task:SetInfo( "Friendlies", string.format( "%d ( %s )", FriendliesCount, FriendliesReport:Text( "," ) ), 30 )
|
||||
local PlayersCount, PlayersReport = self:GetPlayerFriendliesNearBy( DetectedItem )
|
||||
Task:SetInfo( "Players", string.format( "%d ( %s )", PlayersCount, PlayersReport:Text( "," ) ), 31 )
|
||||
end
|
||||
|
||||
-- OK, so the tasking has been done, now delete the changes reported for the area.
|
||||
Detection:AcceptChanges( DetectedItem )
|
||||
end
|
||||
|
||||
-- TODO set menus using the HQ coordinator
|
||||
Mission:GetCommandCenter():SetMenu()
|
||||
|
||||
local TaskText = TaskReport:Text(", ")
|
||||
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
if ( not Mission:IsGroupAssigned(TaskGroup) ) and TaskText ~= "" then
|
||||
Mission:GetCommandCenter():MessageToGroup( string.format( "%s has tasks %s. Subscribe to a task using the radio menu.", Mission:GetName(), TaskText ), TaskGroup )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
end
|
||||
@@ -2,67 +2,13 @@
|
||||
--
|
||||
-- 
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # 1) @{Task_A2G#TASK_A2G} class, extends @{Task#TASK}
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- The @{#TASK_A2G} class defines Air To Ground tasks for a @{Set} of Target Units,
|
||||
-- based on the tasking capabilities defined in @{Task#TASK}.
|
||||
-- The TASK_A2G is implemented using a @{Statemachine#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.
|
||||
--
|
||||
-- # 1.1) Set the scoring of achievements in an A2G attack.
|
||||
--
|
||||
-- Scoring or penalties can be given in the following circumstances:
|
||||
--
|
||||
-- * @{#TASK_A2G.SetScoreOnDestroy}(): Set a score when a target in scope of the A2G attack, has been destroyed.
|
||||
-- * @{#TASK_A2G.SetScoreOnSuccess}(): Set a score when all the targets in scope of the A2G attack, have been destroyed.
|
||||
-- * @{#TASK_A2G.SetPenaltyOnFailed}(): Set a penalty when the A2G attack has failed.
|
||||
--
|
||||
-- # 2) @{Task_A2G#TASK_SEAD} class, extends @{Task_A2G#TASK_A2G}
|
||||
--
|
||||
-- The @{#TASK_SEAD} class defines a SEAD task for a @{Set} of Target Units.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 3) @{Task_A2G#TASK_CAS} class, extends @{Task_A2G#TASK_A2G}
|
||||
--
|
||||
-- The @{#TASK_CAS} class defines a CAS task for a @{Set} of Target Units.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # 4) @{Task_A2G#TASK_BAI} class, extends @{Task_A2G#TASK_A2G}
|
||||
--
|
||||
-- The @{#TASK_BAI} class defines a BAI task for a @{Set} of Target Units.
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-03-09: Revised version.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **[WingThor]**: Concept, Advice & Testing.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
--
|
||||
-- @module Task_A2G
|
||||
|
||||
@@ -72,6 +18,28 @@ do -- TASK_A2G
|
||||
-- @type TASK_A2G
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
|
||||
--- # TASK_A2G class, extends @{Task#TASK}
|
||||
--
|
||||
-- The TASK_A2G class defines Air To Ground tasks for a @{Set} of Target Units,
|
||||
-- based on the tasking capabilities defined in @{Task#TASK}.
|
||||
-- The TASK_A2G 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_A2G.SetScoreOnDestroy}(): Set a score when a target in scope of the A2G attack, has been destroyed.
|
||||
-- * @{#TASK_A2G.SetScoreOnSuccess}(): Set a score when all the targets in scope of the A2G attack, have been destroyed.
|
||||
-- * @{#TASK_A2G.SetPenaltyOnFailed}(): Set a penalty when the A2G attack has failed.
|
||||
--
|
||||
-- @field #TASK_A2G
|
||||
TASK_A2G = {
|
||||
ClassName = "TASK_A2G",
|
||||
}
|
||||
@@ -92,7 +60,7 @@ do -- TASK_A2G
|
||||
|
||||
self.TargetSetUnit = TargetSetUnit
|
||||
self.TaskType = TaskType
|
||||
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
|
||||
@@ -107,14 +75,14 @@ do -- TASK_A2G
|
||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "Engage", "Engaging" )
|
||||
Fsm:AddTransition( { "ArrivedAtRendezVous", "HoldingAtRendezVous" }, "HoldAtRendezVous", "HoldingAtRendezVous" )
|
||||
|
||||
Fsm:AddProcess ( "Engaging", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, self.TaskType ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess ( "Engaging", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, self.TaskType ), {} )
|
||||
Fsm:AddTransition( "Engaging", "RouteToTarget", "Engaging" )
|
||||
Fsm:AddProcess( "Engaging", "RouteToTargetZone", ACT_ROUTE_ZONE:New(), {} )
|
||||
Fsm:AddProcess( "Engaging", "RouteToTargetPoint", ACT_ROUTE_POINT:New(), {} )
|
||||
Fsm:AddTransition( "Engaging", "RouteToTargets", "Engaging" )
|
||||
|
||||
Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
||||
Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
--Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
|
||||
--Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
@@ -174,7 +142,7 @@ do -- TASK_A2G
|
||||
local TargetUnit = Task.TargetSetUnit:GetFirst() -- Wrapper.Unit#UNIT
|
||||
if TargetUnit then
|
||||
local Coordinate = TargetUnit:GetCoordinate()
|
||||
self:T( { TargetCoordinate = Coordinate, Coordinate:GetX(), Coordinate:GetAlt(), Coordinate:GetZ() } )
|
||||
self:T( { TargetCoordinate = Coordinate, Coordinate:GetX(), Coordinate:GetY(), Coordinate:GetZ() } )
|
||||
Task:SetTargetCoordinate( TargetUnit:GetCoordinate(), TaskUnit )
|
||||
end
|
||||
self:__RouteToTargetPoint( 0.1 )
|
||||
@@ -299,175 +267,378 @@ do -- TASK_A2G
|
||||
return ActRouteTarget:GetZone()
|
||||
end
|
||||
|
||||
function TASK_A2G:SetGoalTotal()
|
||||
|
||||
self.GoalTotal = self.TargetSetUnit:Count()
|
||||
end
|
||||
|
||||
function TASK_A2G:GetGoalTotal()
|
||||
|
||||
return self.GoalTotal
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
do -- TASK_A2G_SEAD
|
||||
|
||||
--- The TASK_A2G_SEAD class
|
||||
-- @type TASK_A2G_SEAD
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
|
||||
--- # TASK_A2G_SEAD class, extends @{Task_A2G#TASK_A2G}
|
||||
--
|
||||
-- The TASK_A2G_SEAD 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_A2G_SEAD is used by the @{Task_A2G_Dispatcher#TASK_A2G_DISPATCHER} to automatically create SEAD tasks
|
||||
-- based on detected enemy ground targets.
|
||||
--
|
||||
-- @field #TASK_A2G_SEAD
|
||||
TASK_A2G_SEAD = {
|
||||
ClassName = "TASK_A2G_SEAD",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_A2G_SEAD.
|
||||
-- @param #TASK_A2G_SEAD 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.Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskBriefing The briefing of the task.
|
||||
-- @return #TASK_A2G_SEAD self
|
||||
function TASK_A2G_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD", TaskBriefing ) ) -- #TASK_A2G_SEAD
|
||||
self:F()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
self:SetBriefing(
|
||||
TaskBriefing or
|
||||
"Execute a Suppression of Enemy Air Defenses.\n"
|
||||
)
|
||||
|
||||
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
|
||||
|
||||
self:SetInfo( "Threat", "[" .. string.rep( "■", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
|
||||
local DetectedItemsCount = TargetSetUnit:Count()
|
||||
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
|
||||
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TASK_A2G_SEAD:ReportOrder( ReportGroup )
|
||||
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
|
||||
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
|
||||
|
||||
return Distance
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_A2G_SEAD self
|
||||
function TASK_A2G_SEAD:onafterGoal( TaskUnit, From, Event, To )
|
||||
local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
if TargetSetUnit:Count() == 0 then
|
||||
self:Success()
|
||||
end
|
||||
|
||||
self:__Goal( -10 )
|
||||
end
|
||||
|
||||
--- Set a score when a target in scope of the A2G attack, has been destroyed .
|
||||
-- @param #TASK_A2G self
|
||||
-- @param #string Text The text to display to the player, when the target has been destroyed.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param #TASK_A2G_SEAD self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G
|
||||
function TASK_A2G:SetScoreOnDestroy( Text, Score, TaskUnit )
|
||||
self:F( { Text, Score, TaskUnit } )
|
||||
-- @return #TASK_A2G_SEAD
|
||||
function TASK_A2G_SEAD:SetScoreOnProgress( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "Account", Text, Score )
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "AccountForPlayer", "Player " .. PlayerName .. " has SEADed a target.", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a score when all the targets in scope of the A2G attack, have been destroyed.
|
||||
-- @param #TASK_A2G self
|
||||
-- @param #string Text The text to display to the player, when all targets hav been destroyed.
|
||||
-- @param #TASK_A2G_SEAD self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G
|
||||
function TASK_A2G:SetScoreOnSuccess( Text, Score, TaskUnit )
|
||||
self:F( { Text, Score, TaskUnit } )
|
||||
-- @return #TASK_A2G_SEAD
|
||||
function TASK_A2G_SEAD:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Success", Text, Score )
|
||||
ProcessUnit:AddScore( "Success", "All radar emitting targets have been successfully SEADed!", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a penalty when the A2G attack has failed.
|
||||
-- @param #TASK_A2G self
|
||||
-- @param #string Text The text to display to the player, when the A2G attack has failed.
|
||||
-- @param #number Penalty The penalty in points.
|
||||
-- @param #TASK_A2G_SEAD self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Penalty The penalty in points, must be a negative value!
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G
|
||||
function TASK_A2G:SetPenaltyOnFailed( Text, Penalty, TaskUnit )
|
||||
self:F( { Text, Score, TaskUnit } )
|
||||
-- @return #TASK_A2G_SEAD
|
||||
function TASK_A2G_SEAD:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
|
||||
self:F( { PlayerName, Penalty, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Failed", Text, Penalty )
|
||||
ProcessUnit:AddScore( "Failed", "The SEADing has failed!", Penalty )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- TASK_SEAD
|
||||
do -- TASK_A2G_BAI
|
||||
|
||||
--- The TASK_SEAD class
|
||||
-- @type TASK_SEAD
|
||||
--- The TASK_A2G_BAI class
|
||||
-- @type TASK_A2G_BAI
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
TASK_SEAD = {
|
||||
ClassName = "TASK_SEAD",
|
||||
|
||||
--- # TASK_A2G_BAI class, extends @{Task_A2G#TASK_A2G}
|
||||
--
|
||||
-- The TASK_A2G_BAI class defines an Battlefield Air Interdiction task for a human player to be executed.
|
||||
-- These tasks are more strategic in nature and are most of the time further away from friendly forces.
|
||||
-- BAI tasks can also be used to express the abscence of friendly forces near the vicinity.
|
||||
--
|
||||
-- The TASK_A2G_BAI is used by the @{Task_A2G_Dispatcher#TASK_A2G_DISPATCHER} to automatically create BAI tasks
|
||||
-- based on detected enemy ground targets.
|
||||
--
|
||||
-- @field #TASK_A2G_BAI
|
||||
TASK_A2G_BAI = {
|
||||
ClassName = "TASK_A2G_BAI",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_SEAD.
|
||||
-- @param #TASK_SEAD self
|
||||
--- Instantiates a new TASK_A2G_BAI.
|
||||
-- @param #TASK_A2G_BAI 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.Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskBriefing The briefing of the task.
|
||||
-- @return #TASK_SEAD self
|
||||
function TASK_SEAD:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "SEAD", TaskBriefing ) ) -- #TASK_SEAD
|
||||
-- @return #TASK_A2G_BAI self
|
||||
function TASK_A2G_BAI:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "BAI", TaskBriefing ) ) -- #TASK_A2G_BAI
|
||||
self:F()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
local TargetPositionText = TargetCoord:ToString()
|
||||
local TargetThreatLevel = TargetSetUnit:CalculateThreatLevelA2G()
|
||||
|
||||
self:SetBriefing(
|
||||
TaskBriefing or
|
||||
"Execute a Suppression of Enemy Air Defenses.\n" ..
|
||||
"Initial Coordinates: " .. TargetPositionText .. "\n" ..
|
||||
"Threat Level: [" .. string.rep( "■", TargetThreatLevel ) .. "]"
|
||||
"Execute a Battlefield Air Interdiction of a group of enemy targets.\n"
|
||||
)
|
||||
|
||||
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
|
||||
|
||||
self:SetInfo( "Threat", "[" .. string.rep( "■", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
|
||||
local DetectedItemsCount = TargetSetUnit:Count()
|
||||
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
|
||||
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- TASK_BAI
|
||||
function TASK_A2G_BAI:ReportOrder( ReportGroup )
|
||||
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
|
||||
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
|
||||
|
||||
return Distance
|
||||
end
|
||||
|
||||
--- The TASK_BAI class
|
||||
-- @type TASK_BAI
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
TASK_BAI = {
|
||||
ClassName = "TASK_BAI",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_BAI.
|
||||
-- @param #TASK_BAI 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.Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskBriefing The briefing of the task.
|
||||
-- @return #TASK_BAI self
|
||||
function TASK_BAI:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "BAI", TaskBriefing ) ) -- #TASK_BAI
|
||||
self:F()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
local TargetPositionText = TargetCoord:ToString()
|
||||
local TargetThreatLevel = TargetSetUnit:CalculateThreatLevelA2G()
|
||||
|
||||
self:SetBriefing(
|
||||
TaskBriefing or
|
||||
"Execute a Battlefield Air Interdiction of a group of enemy targets.\n" ..
|
||||
"Initial Coordinates: " .. TargetPositionText .. "\n" ..
|
||||
"Threat Level: [" .. string.rep( "■", TargetThreatLevel ) .. "]"
|
||||
)
|
||||
|
||||
--- @param #TASK_A2G_BAI self
|
||||
function TASK_A2G_BAI:onafterGoal( TaskUnit, From, Event, To )
|
||||
local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
if TargetSetUnit:Count() == 0 then
|
||||
self:Success()
|
||||
end
|
||||
|
||||
self:__Goal( -10 )
|
||||
end
|
||||
|
||||
--- Set a score when a target in scope of the A2G attack, has been destroyed .
|
||||
-- @param #TASK_A2G_BAI self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G_BAI
|
||||
function TASK_A2G_BAI:SetScoreOnProgress( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "AccountForPlayer", "Player " .. PlayerName .. " has destroyed a target in Battlefield Air Interdiction (BAI).", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
end
|
||||
|
||||
--- Set a score when all the targets in scope of the A2G attack, have been destroyed.
|
||||
-- @param #TASK_A2G_BAI self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G_BAI
|
||||
function TASK_A2G_BAI:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Success", "All targets have been successfully destroyed! The Battlefield Air Interdiction (BAI) is a success!", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a penalty when the A2G attack has failed.
|
||||
-- @param #TASK_A2G_BAI self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Penalty The penalty in points, must be a negative value!
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G_BAI
|
||||
function TASK_A2G_BAI:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
|
||||
self:F( { PlayerName, Penalty, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Failed", "The Battlefield Air Interdiction (BAI) has failed!", Penalty )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
do -- TASK_CAS
|
||||
do -- TASK_A2G_CAS
|
||||
|
||||
--- The TASK_CAS class
|
||||
-- @type TASK_CAS
|
||||
--- The TASK_A2G_CAS class
|
||||
-- @type TASK_A2G_CAS
|
||||
-- @field Set#SET_UNIT TargetSetUnit
|
||||
-- @extends Tasking.Task#TASK
|
||||
TASK_CAS = {
|
||||
ClassName = "TASK_CAS",
|
||||
|
||||
--- # TASK_A2G_CAS class, extends @{Task_A2G#TASK_A2G}
|
||||
--
|
||||
-- The TASK_A2G_CAS class defines an Close Air Support task for a human player to be executed.
|
||||
-- Friendly forces will be in the vicinity within 6km from the enemy.
|
||||
--
|
||||
-- The TASK_A2G_CAS is used by the @{Task_A2G_Dispatcher#TASK_A2G_DISPATCHER} to automatically create CAS tasks
|
||||
-- based on detected enemy ground targets.
|
||||
--
|
||||
-- @field #TASK_A2G_CAS
|
||||
TASK_A2G_CAS = {
|
||||
ClassName = "TASK_A2G_CAS",
|
||||
}
|
||||
|
||||
--- Instantiates a new TASK_CAS.
|
||||
-- @param #TASK_CAS self
|
||||
--- Instantiates a new TASK_A2G_CAS.
|
||||
-- @param #TASK_A2G_CAS 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.Set#SET_UNIT TargetSetUnit
|
||||
-- @param #string TaskBriefing The briefing of the task.
|
||||
-- @return #TASK_CAS self
|
||||
function TASK_CAS:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "CAS", TaskBriefing ) ) -- #TASK_CAS
|
||||
-- @return #TASK_A2G_CAS self
|
||||
function TASK_A2G_CAS:New( Mission, SetGroup, TaskName, TargetSetUnit, TaskBriefing )
|
||||
local self = BASE:Inherit( self, TASK_A2G:New( Mission, SetGroup, TaskName, TargetSetUnit, "CAS", TaskBriefing ) ) -- #TASK_A2G_CAS
|
||||
self:F()
|
||||
|
||||
Mission:AddTask( self )
|
||||
|
||||
local TargetCoord = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
local TargetPositionText = TargetCoord:ToString()
|
||||
local TargetThreatLevel = TargetSetUnit:CalculateThreatLevelA2G()
|
||||
|
||||
self:SetBriefing(
|
||||
TaskBriefing or
|
||||
"Execute a Close Air Support for a group of enemy targets.\n" ..
|
||||
"Beware of friendlies at the vicinity!\n" ..
|
||||
"Initial Coordinates: " .. TargetPositionText .. "\n" ..
|
||||
"Threat Level: [" .. string.rep( "■", TargetThreatLevel ) .. "]"
|
||||
"Beware of friendlies at the vicinity!\n"
|
||||
)
|
||||
|
||||
|
||||
local TargetCoordinate = TargetSetUnit:GetFirst():GetCoordinate()
|
||||
self:SetInfo( "Coordinates", TargetCoordinate, 10 )
|
||||
|
||||
self:SetInfo( "Threat", "[" .. string.rep( "■", TargetSetUnit:CalculateThreatLevelA2G() ) .. "]", 11 )
|
||||
local DetectedItemsCount = TargetSetUnit:Count()
|
||||
local DetectedItemsTypes = TargetSetUnit:GetTypeNames()
|
||||
self:SetInfo( "Targets", string.format( "%d of %s", DetectedItemsCount, DetectedItemsTypes ), 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TASK_A2G_CAS:ReportOrder( ReportGroup )
|
||||
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
|
||||
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
|
||||
|
||||
return Distance
|
||||
end
|
||||
|
||||
|
||||
--- @param #TASK_A2G_CAS self
|
||||
function TASK_A2G_CAS:onafterGoal( TaskUnit, From, Event, To )
|
||||
local TargetSetUnit = self.TargetSetUnit -- Core.Set#SET_UNIT
|
||||
|
||||
if TargetSetUnit:Count() == 0 then
|
||||
self:Success()
|
||||
end
|
||||
|
||||
self:__Goal( -10 )
|
||||
end
|
||||
|
||||
--- Set a score when a target in scope of the A2G attack, has been destroyed .
|
||||
-- @param #TASK_A2G_CAS self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points to be granted when task process has been achieved.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G_CAS
|
||||
function TASK_A2G_CAS:SetScoreOnProgress( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScoreProcess( "Engaging", "Account", "AccountForPlayer", "Player " .. PlayerName .. " has destroyed a target in Close Air Support (CAS).", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a score when all the targets in scope of the A2G attack, have been destroyed.
|
||||
-- @param #TASK_A2G_CAS self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G_CAS
|
||||
function TASK_A2G_CAS:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
|
||||
self:F( { PlayerName, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Success", "All targets have been successfully destroyed! The Close Air Support (CAS) was a success!", Score )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set a penalty when the A2G attack has failed.
|
||||
-- @param #TASK_A2G_CAS self
|
||||
-- @param #string PlayerName The name of the player.
|
||||
-- @param #number Penalty The penalty in points, must be a negative value!
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_A2G_CAS
|
||||
function TASK_A2G_CAS:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
|
||||
self:F( { PlayerName, Penalty, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
ProcessUnit:AddScore( "Failed", "The Close Air Support (CAS) has failed!", Penalty )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -1,45 +1,12 @@
|
||||
--- **Tasking** - The TASK_A2G_DISPATCHER creates and manages player TASK_A2G tasks based on detected targets.
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- # 1) @{#TASK_A2G_DISPATCHER} class, extends @{#DETECTION_MANAGER}
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- The @{#TASK_A2G_DISPATCHER} class implements the dynamic dispatching of tasks upon groups of detected units determined a @{Set} of FAC (groups).
|
||||
-- The FAC will detect units, will group them, and will dispatch @{Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
||||
-- Find a summary below describing for which situation a task type is created:
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **CAS Task**: Is created when there are enemy ground units within range of the FAC, while there are friendly units in the FAC perimeter.
|
||||
-- * **BAI Task**: Is created when there are enemy ground units within range of the FAC, while there are NO other friendly units within the FAC perimeter.
|
||||
-- * **SEAD Task**: Is created when there are enemy ground units wihtin range of the FAC, with air search radars.
|
||||
--
|
||||
-- Other task types will follow...
|
||||
--
|
||||
-- 3.1) TASK_A2G_DISPATCHER constructor:
|
||||
-- --------------------------------------
|
||||
-- The @{#TASK_A2G_DISPATCHER.New}() method creates a new TASK_A2G_DISPATCHER instance.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-03-09: Initial class and API.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
-- ====
|
||||
--
|
||||
-- @module Task_A2G_Dispatcher
|
||||
|
||||
@@ -51,6 +18,24 @@ do -- TASK_A2G_DISPATCHER
|
||||
-- @field Functional.Detection#DETECTION_BASE Detection The DETECTION_BASE object that is used to report the detected objects.
|
||||
-- @field Tasking.Mission#MISSION Mission
|
||||
-- @extends Tasking.DetectionManager#DETECTION_MANAGER
|
||||
|
||||
--- # TASK_A2G_DISPATCHE} class, extends @{#DETECTION_MANAGER}
|
||||
--
|
||||
-- The TASK_A2G_DISPATCHER class implements the dynamic dispatching of tasks upon groups of detected units determined a @{Set} of FAC (groups).
|
||||
-- The FAC will detect units, will group them, and will dispatch @{Task}s to groups. Depending on the type of target detected, different tasks will be dispatched.
|
||||
-- Find a summary below describing for which situation a task type is created:
|
||||
--
|
||||
-- * **CAS Task**: Is created when there are enemy ground units within range of the FAC, while there are friendly units in the FAC perimeter.
|
||||
-- * **BAI Task**: Is created when there are enemy ground units within range of the FAC, while there are NO other friendly units within the FAC perimeter.
|
||||
-- * **SEAD Task**: Is created when there are enemy ground units wihtin range of the FAC, with air search radars.
|
||||
--
|
||||
-- Other task types will follow...
|
||||
--
|
||||
-- ## TASK_A2G_DISPATCHER constructor
|
||||
--
|
||||
-- The @{#TASK_A2G_DISPATCHER.New}() method creates a new TASK_A2G_DISPATCHER instance.
|
||||
--
|
||||
-- @field #TASK_A2G_DISPATCHER
|
||||
TASK_A2G_DISPATCHER = {
|
||||
ClassName = "TASK_A2G_DISPATCHER",
|
||||
Mission = nil,
|
||||
@@ -185,13 +170,13 @@ do -- TASK_A2G_DISPATCHER
|
||||
-- @param #boolean DetectedItemID
|
||||
-- @param #boolean DetectedItemChange
|
||||
-- @return Tasking.Task#TASK
|
||||
function TASK_A2G_DISPATCHER:EvaluateRemoveTask( Mission, Task, DetectedItemID, DetectedItemChanged )
|
||||
function TASK_A2G_DISPATCHER:EvaluateRemoveTask( Mission, Task, TaskIndex, DetectedItemChanged )
|
||||
|
||||
if Task then
|
||||
if Task:IsStatePlanned() and DetectedItemChanged == true then
|
||||
self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
||||
--self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
||||
Mission:RemoveTask( Task )
|
||||
self.Tasks[DetectedItemID] = nil
|
||||
self.Tasks[TaskIndex] = nil
|
||||
end
|
||||
end
|
||||
|
||||
@@ -216,60 +201,74 @@ do -- TASK_A2G_DISPATCHER
|
||||
|
||||
local TaskReport = REPORT:New()
|
||||
|
||||
-- Checking the task queue for the dispatcher, and removing any obsolete task!
|
||||
for TaskIndex, TaskData in pairs( self.Tasks ) do
|
||||
local Task = TaskData -- Tasking.Task#TASK
|
||||
if Task:IsStatePlanned() then
|
||||
local DetectedItem = Detection:GetDetectedItem( TaskIndex )
|
||||
if not DetectedItem then
|
||||
local TaskText = Task:GetName()
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
Mission:GetCommandCenter():MessageToGroup( string.format( "Obsolete A2G task %s for %s removed.", TaskText, Mission:GetName() ), TaskGroup )
|
||||
end
|
||||
Mission:RemoveTask( Task )
|
||||
self.Tasks[TaskIndex] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- First we need to the detected targets.
|
||||
for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do
|
||||
|
||||
local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||
local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT
|
||||
local DetectedZone = DetectedItem.Zone
|
||||
self:E( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
|
||||
--self:E( { "Targets in DetectedItem", DetectedItem.ItemID, DetectedSet:Count(), tostring( DetectedItem ) } )
|
||||
DetectedSet:Flush()
|
||||
|
||||
local DetectedItemID = DetectedItem.ID
|
||||
local DetectedItemIndex = DetectedItem.Index
|
||||
local TaskIndex = DetectedItem.Index
|
||||
local DetectedItemChanged = DetectedItem.Changed
|
||||
|
||||
local Task = self.Tasks[DetectedItemID]
|
||||
Task = self:EvaluateRemoveTask( Mission, Task, DetectedItemID, DetectedItemChanged ) -- Task will be removed if it is planned and changed.
|
||||
local Task = self.Tasks[TaskIndex]
|
||||
Task = self:EvaluateRemoveTask( Mission, Task, TaskIndex, DetectedItemChanged ) -- Task will be removed if it is planned and changed.
|
||||
|
||||
-- Evaluate SEAD
|
||||
if not Task then
|
||||
local TargetSetUnit = self:EvaluateSEAD( DetectedItem ) -- Returns a SetUnit if there are targets to be SEADed...
|
||||
if TargetSetUnit then
|
||||
Task = TASK_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", DetectedItemID ), TargetSetUnit )
|
||||
Task = TASK_A2G_SEAD:New( Mission, self.SetGroup, string.format( "SEAD.%03d", DetectedItemID ), TargetSetUnit )
|
||||
end
|
||||
|
||||
-- Evaluate CAS
|
||||
if not Task then
|
||||
local TargetSetUnit = self:EvaluateCAS( DetectedItem ) -- Returns a SetUnit if there are targets to be CASed...
|
||||
if TargetSetUnit then
|
||||
Task = TASK_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", DetectedItemID ), TargetSetUnit )
|
||||
Task = TASK_A2G_CAS:New( Mission, self.SetGroup, string.format( "CAS.%03d", DetectedItemID ), TargetSetUnit )
|
||||
end
|
||||
|
||||
-- Evaluate BAI
|
||||
if not Task then
|
||||
local TargetSetUnit = self:EvaluateBAI( DetectedItem, self.Mission:GetCommandCenter():GetPositionable():GetCoalition() ) -- Returns a SetUnit if there are targets to be BAIed...
|
||||
if TargetSetUnit then
|
||||
Task = TASK_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", DetectedItemID ), TargetSetUnit )
|
||||
Task = TASK_A2G_BAI:New( Mission, self.SetGroup, string.format( "BAI.%03d", DetectedItemID ), TargetSetUnit )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Task then
|
||||
self.Tasks[DetectedItemID] = Task
|
||||
self.Tasks[TaskIndex] = Task
|
||||
Task:SetTargetZone( DetectedZone )
|
||||
Task:SetDispatcher( self )
|
||||
Task:SetInfo( "ThreatLevel", DetectedSet:CalculateThreatLevelA2G() )
|
||||
Task:SetInfo( "Detection", Detection:DetectedItemReportSummary( DetectedItemIndex ) )
|
||||
Task:SetInfo( "Changes", Detection:GetChangeText( DetectedItem ) )
|
||||
Mission:AddTask( Task )
|
||||
|
||||
TaskReport:Add( Task:GetName() )
|
||||
else
|
||||
self:E("This should not happen")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
TaskReport:Add( Task:GetName() )
|
||||
|
||||
-- OK, so the tasking has been done, now delete the changes reported for the area.
|
||||
Detection:AcceptChanges( DetectedItem )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Tasking (Release 2.1)** -- The TASK_CARGO models tasks for players to transport @{Cargo}.
|
||||
--- **Tasking** -- The TASK_CARGO models tasks for players to transport @{Cargo}.
|
||||
--
|
||||
-- 
|
||||
--
|
||||
@@ -14,28 +14,13 @@
|
||||
--
|
||||
-- * @{#TASK_CARGO_TRANSPORT}: Defines a task for a human player to transport a set of cargo between various zones.
|
||||
--
|
||||
-- ==
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-03-09: Revised version.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Concept, Design & Programming.
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Task_Cargo
|
||||
|
||||
@@ -174,11 +159,17 @@ do -- TASK_CARGO
|
||||
|
||||
self.SetCargo = SetCargo
|
||||
self.TaskType = TaskType
|
||||
self.SmokeColor = SMOKECOLOR.Red
|
||||
|
||||
self.CargoItemCount = {} -- Map of Carriers having a cargo item count to check the cargo loading limits.
|
||||
self.CargoLimit = 2
|
||||
|
||||
self.DeployZones = {} -- setmetatable( {}, { __mode = "v" } ) -- weak table on value
|
||||
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
Fsm:SetStartState( "Planned" )
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "SelectAction", Rejected = "Reject" } )
|
||||
|
||||
@@ -216,12 +207,19 @@ do -- TASK_CARGO
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_CARGO#TASK_CARGO Task
|
||||
function Fsm:onafterSelectAction( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
local TaskUnitName = TaskUnit:GetName()
|
||||
|
||||
self:E( { TaskUnit = TaskUnitName, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
local MenuTime = timer.getTime()
|
||||
|
||||
TaskUnit.Menu = MENU_GROUP:New( TaskUnit:GetGroup(), Task:GetName() .. " @ " .. TaskUnit:GetName() ):SetTime( MenuTime )
|
||||
|
||||
local CargoItemCount = TaskUnit:CargoItemCount()
|
||||
|
||||
--Task:GetMission():GetCommandCenter():MessageToGroup( "Cargo in carrier: " .. CargoItemCount, TaskUnit:GetGroup() )
|
||||
|
||||
|
||||
Task.SetCargo:ForEachCargo(
|
||||
|
||||
@@ -240,51 +238,37 @@ do -- TASK_CARGO
|
||||
-- Cargo
|
||||
-- ):SetTime(MenuTime)
|
||||
-- end
|
||||
|
||||
|
||||
|
||||
if Cargo:IsUnLoaded() then
|
||||
if Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
|
||||
MENU_GROUP_COMMAND:New(
|
||||
TaskUnit:GetGroup(),
|
||||
"Board cargo " .. Cargo.Name,
|
||||
TaskUnit.Menu,
|
||||
self.MenuBoardCargo,
|
||||
self,
|
||||
Cargo
|
||||
):SetTime(MenuTime)
|
||||
else
|
||||
MENU_GROUP_COMMAND:New(
|
||||
TaskUnit:GetGroup(),
|
||||
"Route to Pickup cargo " .. Cargo.Name,
|
||||
TaskUnit.Menu,
|
||||
self.MenuRouteToPickup,
|
||||
self,
|
||||
Cargo
|
||||
):SetTime(MenuTime)
|
||||
if CargoItemCount < Task.CargoLimit then
|
||||
if Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
|
||||
local NotInDeployZones = true
|
||||
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
|
||||
if Cargo:IsInZone( DeployZone ) then
|
||||
NotInDeployZones = false
|
||||
end
|
||||
end
|
||||
if NotInDeployZones then
|
||||
if not TaskUnit:InAir() then
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Board cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuBoardCargo, self, Cargo ):SetTime(MenuTime)
|
||||
end
|
||||
end
|
||||
else
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Pickup cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuRouteToPickup, self, Cargo ):SetTime(MenuTime)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Cargo:IsLoaded() then
|
||||
|
||||
MENU_GROUP_COMMAND:New(
|
||||
TaskUnit:GetGroup(),
|
||||
"Unboard cargo " .. Cargo.Name,
|
||||
TaskUnit.Menu,
|
||||
self.MenuUnBoardCargo,
|
||||
self,
|
||||
Cargo
|
||||
):SetTime(MenuTime)
|
||||
|
||||
if not TaskUnit:InAir() then
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Unboard cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuUnBoardCargo, self, Cargo ):SetTime(MenuTime)
|
||||
end
|
||||
-- Deployzones are optional zones that can be selected to request routing information.
|
||||
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
|
||||
if not Cargo:IsInZone( DeployZone ) then
|
||||
MENU_GROUP_COMMAND:New(
|
||||
TaskUnit:GetGroup(),
|
||||
"Route to Deploy cargo at " .. DeployZoneName,
|
||||
TaskUnit.Menu,
|
||||
self.MenuRouteToDeploy,
|
||||
self,
|
||||
DeployZone
|
||||
):SetTime(MenuTime)
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Deploy cargo at " .. DeployZoneName, TaskUnit.Menu, self.MenuRouteToDeploy, self, DeployZone ):SetTime(MenuTime)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -298,9 +282,9 @@ do -- TASK_CARGO
|
||||
|
||||
self:__SelectAction( -15 )
|
||||
|
||||
--Task:GetMission():GetCommandCenter():MessageToGroup("Cargo menu is ready ...", TaskUnit:GetGroup() )
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
@@ -327,8 +311,14 @@ do -- TASK_CARGO
|
||||
self:__RouteToDeploy( 1.0, DeployZone )
|
||||
end
|
||||
|
||||
--- Route to Cargo
|
||||
-- @param #FSM_PROCESS self
|
||||
|
||||
|
||||
---
|
||||
--#TASK_CAROG_TRANSPORT self
|
||||
--#Wrapper.Unit#UNIT
|
||||
|
||||
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
-- @param From
|
||||
@@ -347,16 +337,16 @@ do -- TASK_CARGO
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterArriveAtPickup( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
if self.Cargo:IsAlive() then
|
||||
self.Cargo:Smoke( Task:GetSmokeColor(), 15 )
|
||||
if TaskUnit:IsAir() then
|
||||
self.Cargo.CargoObject:GetUnit(1):SmokeRed()
|
||||
Task:GetMission():GetCommandCenter():MessageToGroup( "Land", TaskUnit:GetGroup() )
|
||||
self:__Land( -0.1, "Pickup" )
|
||||
else
|
||||
self:__SelectAction( -0.1 )
|
||||
@@ -365,8 +355,7 @@ do -- TASK_CARGO
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterCancelRouteToPickup( TaskUnit, Task )
|
||||
@@ -376,8 +365,7 @@ do -- TASK_CARGO
|
||||
end
|
||||
|
||||
|
||||
--- Route to DeployZone
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
function Fsm:onafterRouteToDeploy( TaskUnit, Task, From, Event, To, DeployZone )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
@@ -389,14 +377,14 @@ do -- TASK_CARGO
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterArriveAtDeploy( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
if TaskUnit:IsAir() then
|
||||
Task:GetMission():GetCommandCenter():MessageToGroup( "Land", TaskUnit:GetGroup() )
|
||||
self:__Land( -0.1, "Deploy" )
|
||||
else
|
||||
self:__SelectAction( -0.1 )
|
||||
@@ -404,8 +392,7 @@ do -- TASK_CARGO
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterCancelRouteToDeploy( TaskUnit, Task )
|
||||
@@ -416,7 +403,7 @@ do -- TASK_CARGO
|
||||
|
||||
|
||||
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterLand( TaskUnit, Task, From, Event, To, Action )
|
||||
@@ -425,7 +412,6 @@ do -- TASK_CARGO
|
||||
if self.Cargo:IsAlive() then
|
||||
if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then
|
||||
if TaskUnit:InAir() then
|
||||
Task:GetMission():GetCommandCenter():MessageToGroup( "Land", TaskUnit:GetGroup() )
|
||||
self:__Land( -10, Action )
|
||||
else
|
||||
Task:GetMission():GetCommandCenter():MessageToGroup( "Landed ...", TaskUnit:GetGroup() )
|
||||
@@ -441,8 +427,7 @@ do -- TASK_CARGO
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterLanded( TaskUnit, Task, From, Event, To, Action )
|
||||
@@ -465,8 +450,7 @@ do -- TASK_CARGO
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterPrepareBoarding( TaskUnit, Task, From, Event, To, Cargo )
|
||||
@@ -478,8 +462,7 @@ do -- TASK_CARGO
|
||||
end
|
||||
end
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterBoard( TaskUnit, Task )
|
||||
@@ -505,14 +488,18 @@ do -- TASK_CARGO
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
--- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterBoarded( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
local TaskUnitName = TaskUnit:GetName()
|
||||
self:E( { TaskUnit = TaskUnitName, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
self.Cargo:MessageToGroup( "Boarded ...", TaskUnit:GetGroup() )
|
||||
|
||||
TaskUnit:AddCargo( self.Cargo )
|
||||
|
||||
self:__SelectAction( 1 )
|
||||
|
||||
-- TODO:I need to find a more decent solution for this.
|
||||
@@ -586,12 +573,28 @@ do -- TASK_CARGO
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
function Fsm:onafterUnBoarded( TaskUnit, Task )
|
||||
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
local TaskUnitName = TaskUnit:GetName()
|
||||
self:E( { TaskUnit = TaskUnitName, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
self.Cargo:MessageToGroup( "UnBoarded ...", TaskUnit:GetGroup() )
|
||||
|
||||
TaskUnit:RemoveCargo( self.Cargo )
|
||||
|
||||
local NotInDeployZones = true
|
||||
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
|
||||
if self.Cargo:IsInZone( DeployZone ) then
|
||||
NotInDeployZones = false
|
||||
end
|
||||
end
|
||||
|
||||
if NotInDeployZones == false then
|
||||
self.Cargo:SetDeployed( true )
|
||||
end
|
||||
|
||||
-- TODO:I need to find a more decent solution for this.
|
||||
Task:E( { CargoDeployed = Task.CargoDeployed } )
|
||||
Task:E( { CargoDeployed = Task.CargoDeployed and "true" or "false" } )
|
||||
Task:E( { CargoIsAlive = self.Cargo:IsAlive() and "true" or "false" } )
|
||||
if self.Cargo:IsAlive() then
|
||||
if Task.CargoDeployed then
|
||||
Task:CargoDeployed( TaskUnit, self.Cargo, self.DeployZone )
|
||||
@@ -605,6 +608,36 @@ do -- TASK_CARGO
|
||||
return self
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Set a limit on the amount of cargo items that can be loaded into the Carriers.
|
||||
-- @param #TASK_CARGO self
|
||||
-- @param CargoLimit Specifies a number of cargo items that can be loaded in the helicopter.
|
||||
-- @return #TASK_CARGO
|
||||
function TASK_CARGO:SetCargoLimit( CargoLimit )
|
||||
self.CargoLimit = CargoLimit
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
---@param Color Might be SMOKECOLOR.Blue, SMOKECOLOR.Red SMOKECOLOR.Orange, SMOKECOLOR.White or SMOKECOLOR.Green
|
||||
function TASK_CARGO:SetSmokeColor(SmokeColor)
|
||||
-- Makes sure Coloe is set
|
||||
if SmokeColor == nil then
|
||||
self.SmokeColor = SMOKECOLOR.Red -- Make sure a default color is exist
|
||||
|
||||
elseif type(SmokeColor) == "number" then
|
||||
self:F2(SmokeColor)
|
||||
if SmokeColor > 0 and SmokeColor <=5 then -- Make sure number is within ragne, assuming first enum is one
|
||||
self.SmokeColor = SMOKECOLOR.SmokeColor
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--@return SmokeColor
|
||||
function TASK_CARGO:GetSmokeColor()
|
||||
return self.SmokeColor
|
||||
end
|
||||
|
||||
--- @param #TASK_CARGO self
|
||||
function TASK_CARGO:GetPlannedMenuText()
|
||||
@@ -715,7 +748,7 @@ do -- TASK_CARGO
|
||||
-- @param #number Score The score in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_CARGO
|
||||
function TASK_CARGO:SetScoreOnDestroy( Text, Score, TaskUnit )
|
||||
function TASK_CARGO:SetScoreOnProgress( Text, Score, TaskUnit )
|
||||
self:F( { Text, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
@@ -747,7 +780,7 @@ do -- TASK_CARGO
|
||||
-- @param #number Penalty The penalty in points.
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @return #TASK_CARGO
|
||||
function TASK_CARGO:SetPenaltyOnFailed( Text, Penalty, TaskUnit )
|
||||
function TASK_CARGO:SetScoreOnFail( Text, Penalty, TaskUnit )
|
||||
self:F( { Text, Score, TaskUnit } )
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
@@ -757,6 +790,17 @@ do -- TASK_CARGO
|
||||
return self
|
||||
end
|
||||
|
||||
function TASK_CARGO:SetGoalTotal()
|
||||
|
||||
self.GoalTotal = self.SetCargo:Count()
|
||||
end
|
||||
|
||||
function TASK_CARGO:GetGoalTotal()
|
||||
|
||||
return self.GoalTotal
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -789,6 +833,8 @@ do -- TASK_CARGO_TRANSPORT
|
||||
self:AddTransition( "*", "CargoPickedUp", "*" )
|
||||
self:AddTransition( "*", "CargoDeployed", "*" )
|
||||
|
||||
self:E( { CargoDeployed = self.CargoDeployed ~= nil and "true" or "false" } )
|
||||
|
||||
--- OnBefore Transition Handler for Event CargoPickedUp.
|
||||
-- @function [parent=#TASK_CARGO_TRANSPORT] OnBeforeCargoPickedUp
|
||||
-- @param #TASK_CARGO_TRANSPORT self
|
||||
@@ -867,7 +913,7 @@ do -- TASK_CARGO_TRANSPORT
|
||||
local CargoType = Cargo:GetType()
|
||||
local CargoName = Cargo:GetName()
|
||||
local CargoCoordinate = Cargo:GetCoordinate()
|
||||
CargoReport:Add( string.format( '- "%s" (%s) at %s', CargoName, CargoType, CargoCoordinate:ToString() ) )
|
||||
CargoReport:Add( string.format( '- "%s" (%s) at %s', CargoName, CargoType, CargoCoordinate:ToStringMGRS() ) )
|
||||
end
|
||||
)
|
||||
|
||||
@@ -879,6 +925,12 @@ do -- TASK_CARGO_TRANSPORT
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function TASK_CARGO_TRANSPORT:ReportOrder( ReportGroup )
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- @param #TASK_CARGO_TRANSPORT self
|
||||
@@ -895,22 +947,36 @@ do -- TASK_CARGO_TRANSPORT
|
||||
-- Loop the CargoSet (so evaluate each Cargo in the SET_CARGO ).
|
||||
for CargoID, CargoData in pairs( Set ) do
|
||||
local Cargo = CargoData -- Core.Cargo#CARGO
|
||||
|
||||
if Cargo:IsDeployed() then
|
||||
|
||||
-- Loop the DeployZones set for the TASK_CARGO_TRANSPORT.
|
||||
for DeployZoneID, DeployZone in pairs( DeployZones ) do
|
||||
|
||||
-- If there is a Cargo not in one of DeployZones, then not all Cargo is deployed.
|
||||
self:T( { Cargo.CargoObject } )
|
||||
if Cargo:IsInZone( DeployZone ) then
|
||||
else
|
||||
CargoDeployed = false
|
||||
-- Loop the DeployZones set for the TASK_CARGO_TRANSPORT.
|
||||
for DeployZoneID, DeployZone in pairs( DeployZones ) do
|
||||
|
||||
-- If there is a Cargo not in one of DeployZones, then not all Cargo is deployed.
|
||||
self:T( { Cargo.CargoObject } )
|
||||
if Cargo:IsInZone( DeployZone ) == false then
|
||||
CargoDeployed = false
|
||||
end
|
||||
end
|
||||
else
|
||||
CargoDeployed = false
|
||||
end
|
||||
end
|
||||
|
||||
return CargoDeployed
|
||||
end
|
||||
|
||||
--- @param #TASK_CARGO_TRANSPORT self
|
||||
function TASK_CARGO_TRANSPORT:onafterGoal( TaskUnit, From, Event, To )
|
||||
local CargoSet = self.CargoSet
|
||||
|
||||
if self:IsAllCargoTransported() then
|
||||
self:Success()
|
||||
end
|
||||
|
||||
self:__Goal( -10 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -183,6 +183,10 @@ UTILS.KnotsToMps = function(knots)
|
||||
return knots*1852/3600
|
||||
end
|
||||
|
||||
UTILS.KnotsToKmph = function(knots)
|
||||
return knots* 1.852
|
||||
end
|
||||
|
||||
UTILS.KmphToMps = function(kmph)
|
||||
return kmph/3.6
|
||||
end
|
||||
@@ -303,3 +307,27 @@ function UTILS.DoString( s )
|
||||
return false, err
|
||||
end
|
||||
end
|
||||
|
||||
-- Here is a customized version of pairs, which I called spairs because it iterates over the table in a sorted order.
|
||||
function UTILS.spairs( t, order )
|
||||
-- collect the keys
|
||||
local keys = {}
|
||||
for k in pairs(t) do keys[#keys+1] = k end
|
||||
|
||||
-- if order function given, sort by it by passing the table and keys a, b,
|
||||
-- otherwise just sort the keys
|
||||
if order then
|
||||
table.sort(keys, function(a,b) return order(t, a, b) end)
|
||||
else
|
||||
table.sort(keys)
|
||||
end
|
||||
|
||||
-- return the iterator function
|
||||
local i = 0
|
||||
return function()
|
||||
i = i + 1
|
||||
if keys[i] then
|
||||
return keys[i], t[keys[i]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
--- This module contains the AIRBASE classes.
|
||||
--- **Wrapper** -- AIRBASE is a wrapper class to handle the DCS Airbase objects.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 1) @{Airbase#AIRBASE} class, extends @{Positionable#POSITIONABLE}
|
||||
-- =================================================================
|
||||
-- The @{AIRBASE} class is a wrapper class to handle the DCS Airbase objects:
|
||||
-- @module Airbase
|
||||
|
||||
|
||||
--- @type AIRBASE
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
|
||||
--- # AIRBASE class, extends @{Positionable#POSITIONABLE}
|
||||
--
|
||||
-- AIRBASE is a wrapper class to handle the DCS Airbase objects:
|
||||
--
|
||||
-- * Support all DCS Airbase APIs.
|
||||
-- * Enhance with Airbase specific APIs not in the DCS Airbase API set.
|
||||
--
|
||||
--
|
||||
-- 1.1) AIRBASE reference methods
|
||||
-- ------------------------------
|
||||
-- ## AIRBASE reference methods
|
||||
--
|
||||
-- For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _@{DATABASE} object.
|
||||
-- This is done at the beginning of the mission (when the mission starts).
|
||||
--
|
||||
@@ -29,27 +40,14 @@
|
||||
--
|
||||
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil).
|
||||
--
|
||||
-- 1.2) DCS AIRBASE APIs
|
||||
-- ---------------------
|
||||
-- ## DCS Airbase APIs
|
||||
--
|
||||
-- The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method.
|
||||
-- To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call,
|
||||
-- the first letter of the method is also capitalized. So, by example, the DCS Airbase method @{DCSWrapper.Airbase#Airbase.getName}()
|
||||
-- is implemented in the AIRBASE class as @{#AIRBASE.GetName}().
|
||||
--
|
||||
-- More functions will be added
|
||||
-- ----------------------------
|
||||
-- During the MOOSE development, more functions will be added.
|
||||
--
|
||||
-- @module Airbase
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- The AIRBASE class
|
||||
-- @type AIRBASE
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
-- @field #AIRBASE AIRBASE
|
||||
AIRBASE = {
|
||||
ClassName="AIRBASE",
|
||||
CategoryName = {
|
||||
@@ -59,6 +57,88 @@ AIRBASE = {
|
||||
},
|
||||
}
|
||||
|
||||
--- @field Caucasus
|
||||
AIRBASE.Caucasus = {
|
||||
["Gelendzhik"] = "Gelendzhik",
|
||||
["Krasnodar_Pashkovsky"] = "Krasnodar-Pashkovsky",
|
||||
["Sukhumi_Babushara"] = "Sukhumi-Babushara",
|
||||
["Gudauta"] = "Gudauta",
|
||||
["Batumi"] = "Batumi",
|
||||
["Senaki_Kolkhi"] = "Senaki-Kolkhi",
|
||||
["Kobuleti"] = "Kobuleti",
|
||||
["Kutaisi"] = "Kutaisi",
|
||||
["Tbilisi_Lochini"] = "Tbilisi-Lochini",
|
||||
["Soganlug"] = "Soganlug",
|
||||
["Vaziani"] = "Vaziani",
|
||||
["Anapa_Vityazevo"] = "Anapa-Vityazevo",
|
||||
["Krasnodar_Center"] = "Krasnodar-Center",
|
||||
["Novorossiysk"] = "Novorossiysk",
|
||||
["Krymsk"] = "Krymsk",
|
||||
["Maykop_Khanskaya"] = "Maykop-Khanskaya",
|
||||
["Sochi_Adler"] = "Sochi-Adler",
|
||||
["Mineralnye_Vody"] = "Mineralnye Vody",
|
||||
["Nalchik"] = "Nalchik",
|
||||
["Mozdok"] = "Mozdok",
|
||||
["Beslan"] = "Beslan",
|
||||
}
|
||||
|
||||
--- @field Nevada
|
||||
AIRBASE.Nevada = {
|
||||
["Creech_AFB"] = "Creech AFB",
|
||||
["Groom_Lake_AFB"] = "Groom Lake AFB",
|
||||
["McCarran_International_Airport"] = "McCarran International Airport",
|
||||
["Nellis_AFB"] = "Nellis AFB",
|
||||
["Beatty_Airport"] = "Beatty Airport",
|
||||
["Boulder_City_Airport"] = "Boulder City Airport",
|
||||
["Echo_Bay"] = "Echo Bay",
|
||||
["Henderson_Executive_Airport"] = "Henderson Executive Airport",
|
||||
["Jean_Airport"] = "Jean Airport",
|
||||
["Laughlin_Airport"] = "Laughlin Airport",
|
||||
["Lincoln_County"] = "Lincoln County",
|
||||
["Mellan_Airstrip"] = "Mellan Airstrip",
|
||||
["Mesquite"] = "Mesquite",
|
||||
["Mina_Airport_3Q0"] = "Mina Airport 3Q0",
|
||||
["North_Las_Vegas"] = "North Las Vegas",
|
||||
["Pahute_Mesa_Airstrip"] = "Pahute Mesa Airstrip",
|
||||
["Tonopah_Airport"] = "Tonopah Airport",
|
||||
["Tonopah_Test_Range_Airfield"] = "Tonopah Test Range Airfield",
|
||||
}
|
||||
|
||||
--- @field Normandy
|
||||
AIRBASE.Normandy = {
|
||||
["Saint_Pierre_du_Mont"] = "Saint Pierre du Mont",
|
||||
["Lignerolles"] = "Lignerolles",
|
||||
["Cretteville"] = "Cretteville",
|
||||
["Maupertus"] = "Maupertus",
|
||||
["Brucheville"] = "Brucheville",
|
||||
["Meautis"] = "Meautis",
|
||||
["Cricqueville_en_Bessin"] = "Cricqueville-en-Bessin",
|
||||
["Lessay"] = "Lessay",
|
||||
["Sainte_Laurent_sur_Mer"] = "Sainte-Laurent-sur-Mer",
|
||||
["Biniville"] = "Biniville",
|
||||
["Cardonville"] = "Cardonville",
|
||||
["Deux_Jumeaux"] = "Deux Jumeaux",
|
||||
["Chippelle"] = "Chippelle",
|
||||
["Beuzeville"] = "Beuzeville",
|
||||
["Azeville"] = "Azeville",
|
||||
["Picauville"] = "Picauville",
|
||||
["Le_Molay"] = "Le Molay",
|
||||
["Longues_sur_Mer"] = "Longues-sur-Mer",
|
||||
["Carpiquet"] = "Carpiquet",
|
||||
["Bazenville"] = "Bazenville",
|
||||
["Sainte_Croix_sur_Mer"] = "Sainte-Croix-sur-Mer",
|
||||
["Beny_sur_Mer"] = "Beny-sur-Mer",
|
||||
["Rucqueville"] = "Rucqueville",
|
||||
["Sommervieu"] = "Sommervieu",
|
||||
["Lantheuil"] = "Lantheuil",
|
||||
["Evreux"] = "Evreux",
|
||||
["Chailey"] = "Chailey",
|
||||
["Needs_Oar_Point"] = "Needs Oar Point",
|
||||
["Funtington"] = "Funtington",
|
||||
["Tangmere"] = "Tangmere",
|
||||
["Ford"] = "Ford",
|
||||
}
|
||||
|
||||
-- Registration.
|
||||
|
||||
--- Create a new AIRBASE from DCSAirbase.
|
||||
@@ -69,6 +149,7 @@ function AIRBASE:Register( AirbaseName )
|
||||
|
||||
local self = BASE:Inherit( self, POSITIONABLE:New( AirbaseName ) )
|
||||
self.AirbaseName = AirbaseName
|
||||
self.AirbaseZone = ZONE_RADIUS:New( AirbaseName, self:GetVec2(), 8000 )
|
||||
return self
|
||||
end
|
||||
|
||||
@@ -105,5 +186,12 @@ function AIRBASE:GetDCSObject()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Get the airbase zone.
|
||||
-- @param #AIRBASE self
|
||||
-- @return Core.Zone#ZONE_RADIUS The zone radius of the airbase.
|
||||
function AIRBASE:GetZone()
|
||||
return self.AirbaseZone
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,26 @@
|
||||
--- This module contains the CLIENT class.
|
||||
--- **Wrapper** -- CLIENT wraps DCS Unit objects acting as a __Client__ or __Player__ within a mission.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Client
|
||||
|
||||
|
||||
--- The CLIENT class
|
||||
-- @type CLIENT
|
||||
-- @extends Wrapper.Unit#UNIT
|
||||
|
||||
|
||||
--- # CLIENT class, extends @{Unit#UNIT}
|
||||
--
|
||||
-- 1) @{Client#CLIENT} class, extends @{Unit#UNIT}
|
||||
-- ===============================================
|
||||
-- Clients are those **Units** defined within the Mission Editor that have the skillset defined as __Client__ or __Player__.
|
||||
-- Note that clients are NOT the same as Units, they are NOT necessarily alive.
|
||||
-- The @{Client#CLIENT} class is a wrapper class to handle the DCS Unit objects that have the skillset defined as __Client__ or __Player__:
|
||||
-- The CLIENT class is a wrapper class to handle the DCS Unit objects that have the skillset defined as __Client__ or __Player__:
|
||||
--
|
||||
-- * Wraps the DCS Unit objects with skill level set to Player or Client.
|
||||
-- * Support all DCS Unit APIs.
|
||||
@@ -15,8 +31,8 @@
|
||||
--
|
||||
-- Clients are being used by the @{MISSION} class to follow players and register their successes.
|
||||
--
|
||||
-- 1.1) CLIENT reference methods
|
||||
-- -----------------------------
|
||||
-- ## CLIENT reference methods
|
||||
--
|
||||
-- For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _@{DATABASE} object.
|
||||
-- This is done at the beginning of the mission (when the mission starts).
|
||||
--
|
||||
@@ -32,13 +48,9 @@
|
||||
-- * @{#CLIENT.Find}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object.
|
||||
-- * @{#CLIENT.FindByName}(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name.
|
||||
--
|
||||
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).
|
||||
-- **IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).**
|
||||
--
|
||||
-- @module Client
|
||||
|
||||
--- The CLIENT class
|
||||
-- @type CLIENT
|
||||
-- @extends Wrapper.Unit#UNIT
|
||||
-- @field #CLIENT
|
||||
CLIENT = {
|
||||
ONBOARDSIDE = {
|
||||
NONE = 0,
|
||||
|
||||
@@ -1,29 +1,48 @@
|
||||
--- This module contains the CONTROLLABLE class.
|
||||
--- **Wrapper** -- CONTROLLABLE is an intermediate class wrapping Group and Unit classes "controllers".
|
||||
--
|
||||
-- 1) @{Controllable#CONTROLLABLE} class, extends @{Positionable#POSITIONABLE}
|
||||
-- ===========================================================
|
||||
-- The @{Controllable#CONTROLLABLE} class is a wrapper class to handle the DCS Controllable objects:
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Controllable
|
||||
|
||||
|
||||
|
||||
--- @type CONTROLLABLE
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
-- @field Dcs.DCSWrapper.Controllable#Controllable DCSControllable The DCS controllable class.
|
||||
-- @field #string ControllableName The name of the controllable.
|
||||
|
||||
|
||||
|
||||
--- # CONTROLLABLE class, extends @{Positionable#POSITIONABLE}
|
||||
--
|
||||
-- CONTROLLABLE is a wrapper class to handle the "DCS Controllable objects", which are Groups and Units:
|
||||
--
|
||||
-- * Support all DCS Controllable APIs.
|
||||
-- * Enhance with Controllable specific APIs not in the DCS Controllable API set.
|
||||
-- * Handle local Controllable Controller.
|
||||
-- * Manage the "state" of the DCS Controllable.
|
||||
--
|
||||
-- 1.1) CONTROLLABLE constructor
|
||||
-- -----------------------------
|
||||
-- ## CONTROLLABLE constructor
|
||||
--
|
||||
-- The CONTROLLABLE class provides the following functions to construct a CONTROLLABLE instance:
|
||||
--
|
||||
-- * @{#CONTROLLABLE.New}(): Create a CONTROLLABLE instance.
|
||||
--
|
||||
-- 1.2) CONTROLLABLE task methods
|
||||
-- ------------------------------
|
||||
-- ## CONTROLLABLE Task methods
|
||||
--
|
||||
-- Several controllable task methods are available that help you to prepare tasks.
|
||||
-- These methods return a string consisting of the task description, which can then be given to either a @{Controllable#CONTROLLABLE.PushTask} or @{Controllable#SetTask} method to assign the task to the CONTROLLABLE.
|
||||
-- Tasks are specific for the category of the CONTROLLABLE, more specific, for AIR, GROUND or AIR and GROUND.
|
||||
-- Each task description where applicable indicates for which controllable category the task is valid.
|
||||
-- There are 2 main subdivisions of tasks: Assigned tasks and EnRoute tasks.
|
||||
--
|
||||
-- ### 1.2.1) Assigned task methods
|
||||
-- ### Task assignment
|
||||
--
|
||||
-- Assigned task methods make the controllable execute the task where the location of the (possible) targets of the task are known before being detected.
|
||||
-- This is different from the EnRoute tasks, where the targets of the task need to be detected before the task can be executed.
|
||||
@@ -54,19 +73,20 @@
|
||||
-- * @{#CONTROLLABLE.TaskRouteToZone}: (AIR + GROUND) Route the controllable to a given zone.
|
||||
-- * @{#CONTROLLABLE.TaskReturnToBase}: (AIR) Route the controllable to an airbase.
|
||||
--
|
||||
-- ### 1.2.2) EnRoute task methods
|
||||
-- ### EnRoute assignment
|
||||
--
|
||||
-- EnRoute tasks require the targets of the task need to be detected by the controllable (using its sensors) before the task can be executed:
|
||||
--
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskAWACS}: (AIR) Aircraft will act as an AWACS for friendly units (will provide them with information about contacts). No parameters.
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskEngageControllable}: (AIR) Engaging a controllable. The task does not assign the target controllable to the unit/controllable to attack now; it just allows the unit/controllable to engage the target controllable as well as other assigned targets.
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskEngageTargets}: (AIR) Engaging targets of defined types.
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskEngageTargetsInZone}: (AIR) Engaging a targets of defined types at circle-shaped zone.
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskEWR}: (AIR) Attack the Unit.
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskFAC}: (AIR + GROUND) The task makes the controllable/unit a FAC and lets the FAC to choose a targets (enemy ground controllable) around as well as other assigned targets.
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskFAC_EngageControllable}: (AIR + GROUND) The task makes the controllable/unit a FAC and lets the FAC to choose the target (enemy ground controllable) as well as other assigned targets.
|
||||
-- * @{#CONTROLLABLE.EnRouteTaskTanker}: (AIR) Aircraft will act as a tanker for friendly units. No parameters.
|
||||
--
|
||||
-- ### 1.2.3) Preparation task methods
|
||||
-- ### Task preparation
|
||||
--
|
||||
-- There are certain task methods that allow to tailor the task behaviour:
|
||||
--
|
||||
@@ -75,24 +95,24 @@
|
||||
-- * @{#CONTROLLABLE.TaskCondition}: Return a condition section for a controlled task.
|
||||
-- * @{#CONTROLLABLE.TaskControlled}: Return a Controlled Task taking a Task and a TaskCondition.
|
||||
--
|
||||
-- ### 1.2.4) Obtain the mission from controllable templates
|
||||
-- ### Obtain the mission from controllable templates
|
||||
--
|
||||
-- Controllable templates contain complete mission descriptions. Sometimes you want to copy a complete mission from a controllable and assign it to another:
|
||||
--
|
||||
-- * @{#CONTROLLABLE.TaskMission}: (AIR + GROUND) Return a mission task from a mission template.
|
||||
--
|
||||
-- 1.3) CONTROLLABLE Command methods
|
||||
-- --------------------------
|
||||
-- ## CONTROLLABLE Command methods
|
||||
--
|
||||
-- Controllable **command methods** prepare the execution of commands using the @{#CONTROLLABLE.SetCommand} method:
|
||||
--
|
||||
-- * @{#CONTROLLABLE.CommandDoScript}: Do Script command.
|
||||
-- * @{#CONTROLLABLE.CommandSwitchWayPoint}: Perform a switch waypoint command.
|
||||
--
|
||||
-- 1.4) CONTROLLABLE Option methods
|
||||
-- -------------------------
|
||||
-- ## CONTROLLABLE Option methods
|
||||
--
|
||||
-- Controllable **Option methods** change the behaviour of the Controllable while being alive.
|
||||
--
|
||||
-- ### 1.4.1) Rule of Engagement:
|
||||
-- ### Rule of Engagement:
|
||||
--
|
||||
-- * @{#CONTROLLABLE.OptionROEWeaponFree}
|
||||
-- * @{#CONTROLLABLE.OptionROEOpenFire}
|
||||
@@ -106,7 +126,7 @@
|
||||
-- * @{#CONTROLLABLE.OptionROEReturnFirePossible}
|
||||
-- * @{#CONTROLLABLE.OptionROEEvadeFirePossible}
|
||||
--
|
||||
-- ### 1.4.2) Rule on thread:
|
||||
-- ### Rule on thread:
|
||||
--
|
||||
-- * @{#CONTROLLABLE.OptionROTNoReaction}
|
||||
-- * @{#CONTROLLABLE.OptionROTPassiveDefense}
|
||||
@@ -120,15 +140,7 @@
|
||||
-- * @{#CONTROLLABLE.OptionROTEvadeFirePossible}
|
||||
-- * @{#CONTROLLABLE.OptionROTVerticalPossible}
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Controllable
|
||||
|
||||
--- The CONTROLLABLE class
|
||||
-- @type CONTROLLABLE
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
-- @field Dcs.DCSWrapper.Controllable#Controllable DCSControllable The DCS controllable class.
|
||||
-- @field #string ControllableName The name of the controllable.
|
||||
-- @field #CONTROLLABLE
|
||||
CONTROLLABLE = {
|
||||
ClassName = "CONTROLLABLE",
|
||||
ControllableName = "",
|
||||
@@ -140,7 +152,7 @@ CONTROLLABLE = {
|
||||
-- @param Dcs.DCSWrapper.Controllable#Controllable ControllableName The DCS Controllable name
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:New( ControllableName )
|
||||
local self = BASE:Inherit( self, POSITIONABLE:New( ControllableName ) )
|
||||
local self = BASE:Inherit( self, POSITIONABLE:New( ControllableName ) ) -- #CONTROLLABLE
|
||||
self:F2( ControllableName )
|
||||
self.ControllableName = ControllableName
|
||||
|
||||
@@ -154,12 +166,10 @@ end
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @return Dcs.DCSController#Controller
|
||||
function CONTROLLABLE:_GetController()
|
||||
self:F2( { self.ControllableName } )
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
|
||||
if DCSControllable then
|
||||
local ControllableController = DCSControllable:getController()
|
||||
self:T3( ControllableController )
|
||||
return ControllableController
|
||||
end
|
||||
|
||||
@@ -218,6 +228,36 @@ function CONTROLLABLE:GetLife()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the initial health.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @return #number The controllable health value (unit or group average).
|
||||
-- @return #nil The controllable is not existing or alive.
|
||||
function CONTROLLABLE:GetLife0()
|
||||
self:F2( self.ControllableName )
|
||||
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
|
||||
if DCSControllable then
|
||||
local UnitLife = 0
|
||||
local Units = self:GetUnits()
|
||||
if #Units == 1 then
|
||||
local Unit = Units[1] -- Wrapper.Unit#UNIT
|
||||
UnitLife = Unit:GetLife0()
|
||||
else
|
||||
local UnitLifeTotal = 0
|
||||
for UnitID, Unit in pairs( Units ) do
|
||||
local Unit = Unit -- Wrapper.Unit#UNIT
|
||||
UnitLifeTotal = UnitLifeTotal + Unit:GetLife0()
|
||||
end
|
||||
UnitLife = UnitLifeTotal / #Units
|
||||
end
|
||||
return UnitLife
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
-- Tasks
|
||||
@@ -288,14 +328,13 @@ end
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @return Wrapper.Controllable#CONTROLLABLE self
|
||||
function CONTROLLABLE:SetTask( DCSTask, WaitTime )
|
||||
self:F2( { DCSTask } )
|
||||
self:F2( { DCSTask = DCSTask } )
|
||||
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
|
||||
if DCSControllable then
|
||||
|
||||
local Controller = self:_GetController()
|
||||
self:T3( Controller )
|
||||
|
||||
-- When a controllable SPAWNs, it takes about a second to get the controllable in the simulator. Setting tasks to unspawned controllables provides unexpected results.
|
||||
-- Therefore we schedule the functions to set the mission and options for the Controllable.
|
||||
@@ -313,6 +352,24 @@ function CONTROLLABLE:SetTask( DCSTask, WaitTime )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Checking the Task Queue of the controllable. Returns false if no task is on the queue. true if there is a task.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @return Wrapper.Controllable#CONTROLLABLE self
|
||||
function CONTROLLABLE:HasTask() --R2.2
|
||||
|
||||
local HasTaskResult = false
|
||||
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
|
||||
if DCSControllable then
|
||||
|
||||
local Controller = self:_GetController()
|
||||
HasTaskResult = Controller:hasTask()
|
||||
end
|
||||
|
||||
return HasTaskResult
|
||||
end
|
||||
|
||||
|
||||
--- Return a condition section for a controlled task.
|
||||
-- @param #CONTROLLABLE self
|
||||
@@ -377,7 +434,7 @@ function CONTROLLABLE:TaskCombo( DCSTasks )
|
||||
}
|
||||
|
||||
for TaskID, Task in ipairs( DCSTasks ) do
|
||||
self:E( Task )
|
||||
self:T( Task )
|
||||
end
|
||||
|
||||
self:T3( { DCSTaskCombo } )
|
||||
@@ -576,7 +633,7 @@ function CONTROLLABLE:TaskAttackUnit( AttackUnit, GroupAttack, WeaponExpend, Att
|
||||
}
|
||||
}
|
||||
|
||||
self:E( DCSTask )
|
||||
self:T3( DCSTask )
|
||||
|
||||
return DCSTask
|
||||
end
|
||||
@@ -1088,7 +1145,7 @@ end
|
||||
-- @param Dcs.DCSTypes#AttributeNameArray TargetTypes Array of target categories allowed to engage.
|
||||
-- @param #number Priority All en-route tasks have the priority parameter. This is a number (less value - higher priority) that determines actions related to what task will be performed first.
|
||||
-- @return Dcs.DCSTasking.Task#Task The DCS task structure.
|
||||
function CONTROLLABLE:EnRouteTaskEngageTargets( Vec2, Radius, TargetTypes, Priority )
|
||||
function CONTROLLABLE:EnRouteTaskEngageTargetsInZone( Vec2, Radius, TargetTypes, Priority )
|
||||
self:F2( { self.ControllableName, Vec2, Radius, TargetTypes, Priority } )
|
||||
|
||||
-- EngageTargetsInZone = {
|
||||
@@ -1647,6 +1704,59 @@ function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- (GROUND) Route the controllable to a given Vec2.
|
||||
-- A speed can be given in km/h.
|
||||
-- A given formation can be given.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #Vec2 Vec2 The Vec2 where to route to.
|
||||
-- @param #number Speed The speed.
|
||||
-- @param Base#FORMATION Formation The formation string.
|
||||
function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation )
|
||||
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
|
||||
if DCSControllable then
|
||||
|
||||
local ControllablePoint = self:GetVec2()
|
||||
|
||||
local PointFrom = {}
|
||||
PointFrom.x = ControllablePoint.x
|
||||
PointFrom.y = ControllablePoint.y
|
||||
PointFrom.type = "Turning Point"
|
||||
PointFrom.action = Formation or "Cone"
|
||||
PointFrom.speed = 20 / 1.6
|
||||
|
||||
|
||||
local PointTo = {}
|
||||
|
||||
PointTo.x = Vec2.x
|
||||
PointTo.y = Vec2.y
|
||||
PointTo.type = "Turning Point"
|
||||
|
||||
if Formation then
|
||||
PointTo.action = Formation
|
||||
else
|
||||
PointTo.action = "Cone"
|
||||
end
|
||||
|
||||
if Speed then
|
||||
PointTo.speed = Speed
|
||||
else
|
||||
PointTo.speed = 60 / 3.6
|
||||
end
|
||||
|
||||
local Points = { PointFrom, PointTo }
|
||||
|
||||
self:T3( Points )
|
||||
|
||||
self:Route( Points )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
-- Commands
|
||||
|
||||
@@ -2118,6 +2228,57 @@ function CONTROLLABLE:OptionROTVertical()
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Set RTB on bingo fuel.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #boolean RTB true if RTB on bingo fuel (default), false if no RTB on bingo fuel.
|
||||
-- Warning! When you switch this option off, the airborne group will continue to fly until all fuel has been consumed, and will crash.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:OptionRTBBingoFuel( RTB ) --R2.2
|
||||
self:F2( { self.ControllableName } )
|
||||
|
||||
RTB = RTB or true
|
||||
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
if DCSControllable then
|
||||
local Controller = self:_GetController()
|
||||
|
||||
if self:IsAir() then
|
||||
Controller:setOption( AI.Option.Air.id.RTB_ON_BINGO, RTB )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Set RTB on ammo.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param #boolean WeaponsFlag Weapons.flag enumerator.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:OptionRTBAmmo( WeaponsFlag )
|
||||
self:F2( { self.ControllableName } )
|
||||
|
||||
local DCSControllable = self:GetDCSObject()
|
||||
if DCSControllable then
|
||||
local Controller = self:_GetController()
|
||||
|
||||
if self:IsAir() then
|
||||
Controller:setOption( AI.Option.GROUND.id.RTB_ON_OUT_OF_AMMO, WeaponsFlag )
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- Retrieve the controllable mission and allow to place function hooks within the mission waypoint plan.
|
||||
-- Use the method @{Controllable#CONTROLLABLE:WayPointFunction} to define the hook functions for specific waypoints.
|
||||
-- Use the method @{Controllable@CONTROLLABLE:WayPointExecute) to start the execution of the new mission plan.
|
||||
@@ -2185,7 +2346,7 @@ function CONTROLLABLE:TaskFunction( WayPoint, WayPointIndex, FunctionString, Fun
|
||||
), WayPointIndex
|
||||
)
|
||||
|
||||
self:T3( DCSTask )
|
||||
self:T( DCSTask )
|
||||
|
||||
return DCSTask
|
||||
|
||||
@@ -2217,4 +2378,32 @@ function CONTROLLABLE:WayPointExecute( WayPoint, WaitTime )
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns if the Controllable contains AirPlanes.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @return #boolean true if Controllable contains AirPlanes.
|
||||
function CONTROLLABLE:IsAirPlane()
|
||||
self:F2()
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
if DCSObject then
|
||||
local Category = DCSObject:getDesc().category
|
||||
return Category == Unit.Category.AIRPLANE
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function CONTROLLABLE:GetSize()
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
if DCSObject then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Message APIs
|
||||
@@ -1,4 +1,4 @@
|
||||
--- **Wrapper** -- GROUP is a wrapper class for the DCS Class Group.
|
||||
--- **Wrapper** -- GROUP wraps the DCS Class Group objects.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@@ -15,45 +15,22 @@
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- # **API CHANGE HISTORY**
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2017-03-26: GROUP:**RouteRTB( RTBAirbase, Speed )** added.
|
||||
--
|
||||
-- 2017-03-07: GROUP:**HandleEvent( Event, EventFunction )** added.
|
||||
-- 2017-03-07: GROUP:**UnHandleEvent( Event )** added.
|
||||
--
|
||||
-- 2017-01-24: GROUP:**SetAIOnOff( AIOnOff )** added.
|
||||
--
|
||||
-- 2017-01-24: GROUP:**SetAIOn()** added.
|
||||
--
|
||||
-- 2017-01-24: GROUP:**SetAIOff()** added.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- # **AUTHORS and CONTRIBUTIONS**
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * [**Entropy**](https://forums.eagle.ru/member.php?u=111471), **Afinegan**: Came up with the requirement for AIOnOff().
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * **FlightControl**: Design & Programming
|
||||
-- ====
|
||||
--
|
||||
-- @module Group
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
--- @type GROUP
|
||||
-- @extends Wrapper.Controllable#CONTROLLABLE
|
||||
-- @field #string GroupName The name of the group.
|
||||
|
||||
|
||||
---
|
||||
-- # GROUP class, extends @{Controllable#CONTROLLABLE}
|
||||
--
|
||||
@@ -114,6 +91,25 @@ GROUP = {
|
||||
ClassName = "GROUP",
|
||||
}
|
||||
|
||||
|
||||
--- Enumerator for location at airbases
|
||||
-- @type GROUP.Takeoff
|
||||
GROUP.Takeoff = {
|
||||
Air = 1,
|
||||
Runway = 2,
|
||||
Hot = 3,
|
||||
Cold = 4,
|
||||
}
|
||||
|
||||
GROUPTEMPLATE = {}
|
||||
|
||||
GROUPTEMPLATE.Takeoff = {
|
||||
[GROUP.Takeoff.Air] = "Turning Point",
|
||||
[GROUP.Takeoff.Runway] = "TakeOff",
|
||||
[GROUP.Takeoff.Hot] = "TakeOffParkingHot",
|
||||
[GROUP.Takeoff.Cold] = "TakeOffParking",
|
||||
}
|
||||
|
||||
--- Create a new GROUP from a DCSGroup
|
||||
-- @param #GROUP self
|
||||
-- @param Dcs.DCSWrapper.Group#Group GroupName The DCS Group name
|
||||
@@ -357,8 +353,13 @@ function GROUP:GetSize()
|
||||
|
||||
if DCSGroup then
|
||||
local GroupSize = DCSGroup:getSize()
|
||||
self:T3( GroupSize )
|
||||
return GroupSize
|
||||
|
||||
if GroupSize then
|
||||
self:T3( GroupSize )
|
||||
return GroupSize
|
||||
else
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
@@ -426,6 +427,24 @@ function GROUP:GetTypeName()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Gets the player name of the group.
|
||||
-- @param #GROUP self
|
||||
-- @return #string The player name of the group.
|
||||
function GROUP:GetPlayerName()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local PlayerName = DCSGroup:getUnit(1):getPlayerName()
|
||||
self:T3( PlayerName )
|
||||
return( PlayerName )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Gets the CallSign of the first DCS Unit of the DCS Group.
|
||||
-- @param #GROUP self
|
||||
-- @return #string The CallSign of the first DCS Unit of the DCS Group.
|
||||
@@ -485,6 +504,25 @@ function GROUP:GetPointVec2()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns a COORDINATE object indicating the point of the first UNIT of the GROUP within the mission.
|
||||
-- @param Wrapper.Group#GROUP self
|
||||
-- @return Core.Point#COORDINATE The COORDINATE of the GROUP.
|
||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
||||
function GROUP:GetCoordinate()
|
||||
self:F2( self.PositionableName )
|
||||
|
||||
local FirstUnit = self:GetUnit(1)
|
||||
|
||||
if FirstUnit then
|
||||
local FirstUnitCoordinate = FirstUnit:GetCoordinate()
|
||||
self:T3(FirstUnitCoordinate)
|
||||
return FirstUnitCoordinate
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns a random @{DCSTypes#Vec3} vector (point in 3D of the UNIT within the mission) within a range around the first UNIT of the GROUP.
|
||||
-- @param #GROUP self
|
||||
-- @param #number Radius
|
||||
@@ -831,25 +869,28 @@ end
|
||||
-- @param #table Template The template of the Group retrieved with GROUP:GetTemplate()
|
||||
function GROUP:Respawn( Template )
|
||||
|
||||
local Vec3 = self:GetVec3()
|
||||
Template.x = Vec3.x
|
||||
Template.y = Vec3.z
|
||||
--Template.x = nil
|
||||
--Template.y = nil
|
||||
|
||||
self:E( #Template.units )
|
||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||
local GroupUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
self:E( GroupUnit:GetName() )
|
||||
if GroupUnit:IsAlive() then
|
||||
local GroupUnitVec3 = GroupUnit:GetVec3()
|
||||
local GroupUnitHeading = GroupUnit:GetHeading()
|
||||
Template.units[UnitID].alt = GroupUnitVec3.y
|
||||
Template.units[UnitID].x = GroupUnitVec3.x
|
||||
Template.units[UnitID].y = GroupUnitVec3.z
|
||||
Template.units[UnitID].heading = GroupUnitHeading
|
||||
self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
|
||||
if self:IsAlive() then
|
||||
local Vec3 = self:GetVec3()
|
||||
Template.x = Vec3.x
|
||||
Template.y = Vec3.z
|
||||
--Template.x = nil
|
||||
--Template.y = nil
|
||||
|
||||
self:E( #Template.units )
|
||||
for UnitID, UnitData in pairs( self:GetUnits() ) do
|
||||
local GroupUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
self:E( GroupUnit:GetName() )
|
||||
if GroupUnit:IsAlive() then
|
||||
local GroupUnitVec3 = GroupUnit:GetVec3()
|
||||
local GroupUnitHeading = GroupUnit:GetHeading()
|
||||
Template.units[UnitID].alt = GroupUnitVec3.y
|
||||
Template.units[UnitID].x = GroupUnitVec3.x
|
||||
Template.units[UnitID].y = GroupUnitVec3.z
|
||||
Template.units[UnitID].heading = GroupUnitHeading
|
||||
self:E( { UnitID, Template.units[UnitID], Template.units[UnitID] } )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self:Destroy()
|
||||
@@ -1100,7 +1141,7 @@ do -- Event Handling
|
||||
-- @return #GROUP
|
||||
function GROUP:UnHandleEvent( Event )
|
||||
|
||||
self:EventDispatcher():Remove( self, Event )
|
||||
self:EventDispatcher():RemoveEvent( self, Event )
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -1129,7 +1170,7 @@ do -- Players
|
||||
-- @return #nil The group has no players
|
||||
function GROUP:GetPlayerNames()
|
||||
|
||||
local PlayerNames = nil
|
||||
local PlayerNames = {}
|
||||
|
||||
local Units = self:GetUnits()
|
||||
for UnitID, UnitData in pairs( Units ) do
|
||||
@@ -1145,4 +1186,96 @@ do -- Players
|
||||
return PlayerNames
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
--do -- Smoke
|
||||
--
|
||||
----- Signal a flare at the position of the GROUP.
|
||||
---- @param #GROUP self
|
||||
---- @param Utilities.Utils#FLARECOLOR FlareColor
|
||||
--function GROUP:Flare( FlareColor )
|
||||
-- self:F2()
|
||||
-- trigger.action.signalFlare( self:GetVec3(), FlareColor , 0 )
|
||||
--end
|
||||
--
|
||||
----- Signal a white flare at the position of the GROUP.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:FlareWhite()
|
||||
-- self:F2()
|
||||
-- trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.White , 0 )
|
||||
--end
|
||||
--
|
||||
----- Signal a yellow flare at the position of the GROUP.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:FlareYellow()
|
||||
-- self:F2()
|
||||
-- trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Yellow , 0 )
|
||||
--end
|
||||
--
|
||||
----- Signal a green flare at the position of the GROUP.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:FlareGreen()
|
||||
-- self:F2()
|
||||
-- trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Green , 0 )
|
||||
--end
|
||||
--
|
||||
----- Signal a red flare at the position of the GROUP.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:FlareRed()
|
||||
-- self:F2()
|
||||
-- local Vec3 = self:GetVec3()
|
||||
-- if Vec3 then
|
||||
-- trigger.action.signalFlare( Vec3, trigger.flareColor.Red, 0 )
|
||||
-- end
|
||||
--end
|
||||
--
|
||||
----- Smoke the GROUP.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:Smoke( SmokeColor, Range )
|
||||
-- self:F2()
|
||||
-- if Range then
|
||||
-- trigger.action.smoke( self:GetRandomVec3( Range ), SmokeColor )
|
||||
-- else
|
||||
-- trigger.action.smoke( self:GetVec3(), SmokeColor )
|
||||
-- end
|
||||
--
|
||||
--end
|
||||
--
|
||||
----- Smoke the GROUP Green.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:SmokeGreen()
|
||||
-- self:F2()
|
||||
-- trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Green )
|
||||
--end
|
||||
--
|
||||
----- Smoke the GROUP Red.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:SmokeRed()
|
||||
-- self:F2()
|
||||
-- trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Red )
|
||||
--end
|
||||
--
|
||||
----- Smoke the GROUP White.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:SmokeWhite()
|
||||
-- self:F2()
|
||||
-- trigger.action.smoke( self:GetVec3(), trigger.smokeColor.White )
|
||||
--end
|
||||
--
|
||||
----- Smoke the GROUP Orange.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:SmokeOrange()
|
||||
-- self:F2()
|
||||
-- trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Orange )
|
||||
--end
|
||||
--
|
||||
----- Smoke the GROUP Blue.
|
||||
---- @param #GROUP self
|
||||
--function GROUP:SmokeBlue()
|
||||
-- self:F2()
|
||||
-- trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Blue )
|
||||
--end
|
||||
--
|
||||
--
|
||||
--
|
||||
--end
|
||||
@@ -1,39 +1,34 @@
|
||||
--- This module contains the IDENTIFIABLE class.
|
||||
--- **Wrapper** -- IDENTIFIABLE is an intermediate class wrapping DCS Object class derived Objects.
|
||||
--
|
||||
-- 1) @{#IDENTIFIABLE} class, extends @{Object#OBJECT}
|
||||
-- ===============================================================
|
||||
-- The @{#IDENTIFIABLE} class is a wrapper class to handle the DCS Identifiable objects:
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Identifiable
|
||||
|
||||
--- @type IDENTIFIABLE
|
||||
-- @extends Wrapper.Object#OBJECT
|
||||
-- @field #string IdentifiableName The name of the identifiable.
|
||||
|
||||
--- # IDENTIFIABLE class, extends @{Object#OBJECT}
|
||||
--
|
||||
-- The IDENTIFIABLE class is a wrapper class to handle the DCS Identifiable objects:
|
||||
--
|
||||
-- * Support all DCS Identifiable APIs.
|
||||
-- * Enhance with Identifiable specific APIs not in the DCS Identifiable API set.
|
||||
-- * Manage the "state" of the DCS Identifiable.
|
||||
--
|
||||
-- 1.1) IDENTIFIABLE constructor:
|
||||
-- ------------------------------
|
||||
-- ## IDENTIFIABLE constructor
|
||||
--
|
||||
-- The IDENTIFIABLE class provides the following functions to construct a IDENTIFIABLE instance:
|
||||
--
|
||||
-- * @{#IDENTIFIABLE.New}(): Create a IDENTIFIABLE instance.
|
||||
--
|
||||
-- 1.2) IDENTIFIABLE methods:
|
||||
-- --------------------------
|
||||
-- The following methods can be used to identify an identifiable object:
|
||||
--
|
||||
-- * @{#IDENTIFIABLE.GetName}(): Returns the name of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.IsAlive}(): Returns if the Identifiable is alive.
|
||||
-- * @{#IDENTIFIABLE.GetTypeName}(): Returns the type name of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.GetCoalition}(): Returns the coalition of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.GetCountry}(): Returns the country of the Identifiable.
|
||||
-- * @{#IDENTIFIABLE.GetDesc}(): Returns the descriptor structure of the Identifiable.
|
||||
--
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Identifiable
|
||||
|
||||
--- The IDENTIFIABLE class
|
||||
-- @type IDENTIFIABLE
|
||||
-- @extends Wrapper.Object#OBJECT
|
||||
-- @field #string IdentifiableName The name of the identifiable.
|
||||
-- @field #IDENTIFIABLE
|
||||
IDENTIFIABLE = {
|
||||
ClassName = "IDENTIFIABLE",
|
||||
IdentifiableName = "",
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
--- This module contains the OBJECT class.
|
||||
--- **Wrapper** -- OBJECT wraps the DCS Object derived objects.
|
||||
--
|
||||
-- 1) @{Object#OBJECT} class, extends @{Base#BASE}
|
||||
-- ===========================================================
|
||||
-- The @{Object#OBJECT} class is a wrapper class to handle the DCS Object objects:
|
||||
--
|
||||
-- * Support all DCS Object APIs.
|
||||
-- * Enhance with Object specific APIs not in the DCS Object API set.
|
||||
-- * Manage the "state" of the DCS Object.
|
||||
--
|
||||
-- 1.1) OBJECT constructor:
|
||||
-- ------------------------------
|
||||
-- The OBJECT class provides the following functions to construct a OBJECT instance:
|
||||
--
|
||||
-- * @{Object#OBJECT.New}(): Create a OBJECT instance.
|
||||
--
|
||||
-- 1.2) OBJECT methods:
|
||||
-- --------------------------
|
||||
-- The following methods can be used to identify an Object object:
|
||||
-- ====
|
||||
--
|
||||
-- * @{Object#OBJECT.GetID}(): Returns the ID of the Object object.
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module Object
|
||||
|
||||
--- The OBJECT class
|
||||
-- @type OBJECT
|
||||
|
||||
--- @type OBJECT
|
||||
-- @extends Core.Base#BASE
|
||||
-- @field #string ObjectName The name of the Object.
|
||||
|
||||
|
||||
--- # OBJECT class, extends @{Base#BASE}
|
||||
--
|
||||
-- OBJECT handles the DCS Object objects:
|
||||
--
|
||||
-- * Support all DCS Object APIs.
|
||||
-- * Enhance with Object specific APIs not in the DCS Object API set.
|
||||
-- * Manage the "state" of the DCS Object.
|
||||
--
|
||||
-- ## OBJECT constructor:
|
||||
--
|
||||
-- The OBJECT class provides the following functions to construct a OBJECT instance:
|
||||
--
|
||||
-- * @{Object#OBJECT.New}(): Create a OBJECT instance.
|
||||
--
|
||||
-- @field #OBJECT
|
||||
OBJECT = {
|
||||
ClassName = "OBJECT",
|
||||
ObjectName = "",
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
--- **Wrapper** -- This module contains the POSITIONABLE class.
|
||||
--- **Wrapper** -- POSITIONABLE wraps DCS classes that are "positionable".
|
||||
--
|
||||
-- ===
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Positionable
|
||||
|
||||
--- The POSITIONABLE class
|
||||
-- @type POSITIONABLE
|
||||
--- @type POSITIONABLE.__ Methods which are not intended for mission designers, but which are used interally by the moose designer :-)
|
||||
-- @extends Wrapper.Identifiable#IDENTIFIABLE
|
||||
-- @field #string PositionableName The name of the measurable.
|
||||
-- @field Core.Spot#SPOT Spot The laser Spot.
|
||||
-- @field #number LaserCode The last assigned laser code.
|
||||
|
||||
--- @type POSITIONABLE
|
||||
-- @extends POSITIONABLE.__
|
||||
|
||||
|
||||
--- # POSITIONABLE class, extends @{Identifiable#IDENTIFIABLE}
|
||||
--
|
||||
@@ -23,14 +29,17 @@
|
||||
--
|
||||
-- The POSITIONABLE class provides the following functions to construct a POSITIONABLE instance:
|
||||
--
|
||||
-- * @{Positionable#POSITIONABLE.New}(): Create a POSITIONABLE instance.
|
||||
--
|
||||
-- ## POSITIONABLE methods
|
||||
-- * @{#POSITIONABLE.New}(): Create a POSITIONABLE instance.
|
||||
--
|
||||
-- The following methods can be used to identify an measurable object:
|
||||
-- ## Get the current speed
|
||||
--
|
||||
-- * @{Positionable#POSITIONABLE.GetID}(): Returns the ID of the measurable object.
|
||||
-- * @{Positionable#POSITIONABLE.GetName}(): Returns the name of the measurable object.
|
||||
-- There are 3 methods that can be used to determine the speed.
|
||||
-- Use @{#POSITIONABLE.GetVelocityKMH}() to retrieve the current speed in km/h. Use @{#POSITIONABLE.GetVelocityMPS}() to retrieve the speed in meters per second.
|
||||
-- The method @{#POSITIONABLE.GetVelocity}() returns the speed vector (a Vec3).
|
||||
--
|
||||
-- ## Get the current altitude
|
||||
--
|
||||
-- Altitude can be retrieved using the method @{#POSITIONABLE.GetHeight}() and returns the current altitude in meters from the orthonormal plane.
|
||||
--
|
||||
--
|
||||
-- @field #POSITIONABLE
|
||||
@@ -38,6 +47,14 @@ POSITIONABLE = {
|
||||
ClassName = "POSITIONABLE",
|
||||
PositionableName = "",
|
||||
}
|
||||
|
||||
--- @field #POSITIONABLE.__
|
||||
POSITIONABLE.__ = {}
|
||||
|
||||
--- @field #POSITIONABLE.__.Cargo
|
||||
POSITIONABLE.__.Cargo = {}
|
||||
|
||||
|
||||
--- A DCSPositionable
|
||||
-- @type DCSPositionable
|
||||
-- @field id_ The ID of the controllable in DCS
|
||||
@@ -148,7 +165,8 @@ function POSITIONABLE:GetCoordinate()
|
||||
if DCSPositionable then
|
||||
local PositionableVec3 = self:GetPositionVec3()
|
||||
|
||||
local PositionableCoordinate = COORDINATE:NewFromVec3( PositionableVec3 )
|
||||
local PositionableCoordinate = POINT_VEC3:NewFromVec3( PositionableVec3 )
|
||||
PositionableCoordinate:SetHeading( self:GetHeading() )
|
||||
|
||||
self:T2( PositionableCoordinate )
|
||||
return PositionableCoordinate
|
||||
@@ -353,7 +371,6 @@ end
|
||||
--- Returns the POSITIONABLE velocity in km/h.
|
||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||
-- @return #number The velocity in km/h
|
||||
-- @return #nil The POSITIONABLE is not existing or alive.
|
||||
function POSITIONABLE:GetVelocityKMH()
|
||||
self:F2( self.PositionableName )
|
||||
|
||||
@@ -367,7 +384,25 @@ function POSITIONABLE:GetVelocityKMH()
|
||||
return Velocity
|
||||
end
|
||||
|
||||
return nil
|
||||
return 0
|
||||
end
|
||||
|
||||
--- Returns the POSITIONABLE velocity in meters per second.
|
||||
-- @param Wrapper.Positionable#POSITIONABLE self
|
||||
-- @return #number The velocity in meters per second.
|
||||
function POSITIONABLE:GetVelocityMPS()
|
||||
self:F2( self.PositionableName )
|
||||
|
||||
local DCSPositionable = self:GetDCSObject()
|
||||
|
||||
if DCSPositionable then
|
||||
local VelocityVec3 = self:GetVelocity()
|
||||
local Velocity = ( VelocityVec3.x ^ 2 + VelocityVec3.y ^ 2 + VelocityVec3.z ^ 2 ) ^ 0.5 -- in meters / sec
|
||||
self:T3( Velocity )
|
||||
return Velocity
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
@@ -648,5 +683,132 @@ function POSITIONABLE:GetLaserCode() --R2.1
|
||||
return self.LaserCode
|
||||
end
|
||||
|
||||
--- Add cargo.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param Core.Cargo#CARGO Cargo
|
||||
-- @return #POSITIONABLE
|
||||
function POSITIONABLE:AddCargo( Cargo )
|
||||
self.__.Cargo[Cargo] = Cargo
|
||||
return self
|
||||
end
|
||||
|
||||
--- Remove cargo.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param Core.Cargo#CARGO Cargo
|
||||
-- @return #POSITIONABLE
|
||||
function POSITIONABLE:RemoveCargo( Cargo )
|
||||
self.__.Cargo[Cargo] = nil
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns if carrier has given cargo.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @return Core.Cargo#CARGO Cargo
|
||||
function POSITIONABLE:HasCargo( Cargo )
|
||||
return self.__.Cargo[Cargo]
|
||||
end
|
||||
|
||||
--- Clear all cargo.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:ClearCargo()
|
||||
self.__.Cargo = {}
|
||||
end
|
||||
|
||||
--- Get cargo item count.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @return Core.Cargo#CARGO Cargo
|
||||
function POSITIONABLE:CargoItemCount()
|
||||
local ItemCount = 0
|
||||
for CargoName, Cargo in pairs( self.__.Cargo ) do
|
||||
ItemCount = ItemCount + Cargo:GetCount()
|
||||
end
|
||||
return ItemCount
|
||||
end
|
||||
|
||||
--- Signal a flare at the position of the POSITIONABLE.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param Utilities.Utils#FLARECOLOR FlareColor
|
||||
function POSITIONABLE:Flare( FlareColor )
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), FlareColor , 0 )
|
||||
end
|
||||
|
||||
--- Signal a white flare at the position of the POSITIONABLE.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:FlareWhite()
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.White , 0 )
|
||||
end
|
||||
|
||||
--- Signal a yellow flare at the position of the POSITIONABLE.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:FlareYellow()
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Yellow , 0 )
|
||||
end
|
||||
|
||||
--- Signal a green flare at the position of the POSITIONABLE.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:FlareGreen()
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Green , 0 )
|
||||
end
|
||||
|
||||
--- Signal a red flare at the position of the POSITIONABLE.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:FlareRed()
|
||||
self:F2()
|
||||
local Vec3 = self:GetVec3()
|
||||
if Vec3 then
|
||||
trigger.action.signalFlare( Vec3, trigger.flareColor.Red, 0 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Smoke the POSITIONABLE.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:Smoke( SmokeColor, Range )
|
||||
self:F2()
|
||||
if Range then
|
||||
trigger.action.smoke( self:GetRandomVec3( Range ), SmokeColor )
|
||||
else
|
||||
trigger.action.smoke( self:GetVec3(), SmokeColor )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Smoke the POSITIONABLE Green.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:SmokeGreen()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Green )
|
||||
end
|
||||
|
||||
--- Smoke the POSITIONABLE Red.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:SmokeRed()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Red )
|
||||
end
|
||||
|
||||
--- Smoke the POSITIONABLE White.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:SmokeWhite()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.White )
|
||||
end
|
||||
|
||||
--- Smoke the POSITIONABLE Orange.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:SmokeOrange()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Orange )
|
||||
end
|
||||
|
||||
--- Smoke the POSITIONABLE Blue.
|
||||
-- @param #POSITIONABLE self
|
||||
function POSITIONABLE:SmokeBlue()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Blue )
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,31 @@
|
||||
--- This module contains the SCENERY class.
|
||||
--- **Wrapper** -- SCENERY models scenery within the DCS simulator.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Scenery
|
||||
|
||||
|
||||
|
||||
--- @type SCENERY
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
|
||||
|
||||
--- # SCENERY class, extends @{Positionable#POSITIONABLE}
|
||||
--
|
||||
-- 1) @{Scenery#SCENERY} class, extends @{Positionable#POSITIONABLE}
|
||||
-- ===============================================================
|
||||
-- Scenery objects are defined on the map.
|
||||
-- The @{Scenery#SCENERY} class is a wrapper class to handle the DCS Scenery objects:
|
||||
--
|
||||
-- * Wraps the DCS Scenery objects.
|
||||
-- * Support all DCS Scenery APIs.
|
||||
-- * Enhance with Scenery specific APIs not in the DCS API set.
|
||||
--
|
||||
-- @module Scenery
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
|
||||
--- The SCENERY class
|
||||
-- @type SCENERY
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
--
|
||||
-- @field #SCENERY
|
||||
SCENERY = {
|
||||
ClassName = "SCENERY",
|
||||
}
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
--- This module contains the STATIC class.
|
||||
--- **Wrapper** -- STATIC wraps the DCS StaticObject class.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Static
|
||||
|
||||
|
||||
--- @type STATIC
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
|
||||
--- # STATIC class, extends @{Positionable#POSITIONABLE}
|
||||
--
|
||||
-- 1) @{Static#STATIC} class, extends @{Positionable#POSITIONABLE}
|
||||
-- ===============================================================
|
||||
-- Statics are **Static Units** defined within the Mission Editor.
|
||||
-- Note that Statics are almost the same as Units, but they don't have a controller.
|
||||
-- The @{Static#STATIC} class is a wrapper class to handle the DCS Static objects:
|
||||
@@ -10,8 +24,8 @@
|
||||
-- * Support all DCS Static APIs.
|
||||
-- * Enhance with Static specific APIs not in the DCS API set.
|
||||
--
|
||||
-- 1.1) STATIC reference methods
|
||||
-- -----------------------------
|
||||
-- ## STATIC reference methods
|
||||
--
|
||||
-- For each DCS Static will have a STATIC wrapper object (instance) within the _@{DATABASE} object.
|
||||
-- This is done at the beginning of the mission (when the mission starts).
|
||||
--
|
||||
@@ -28,17 +42,7 @@
|
||||
--
|
||||
-- IMPORTANT: ONE SHOULD NEVER SANATIZE these STATIC OBJECT REFERENCES! (make the STATIC object references nil).
|
||||
--
|
||||
-- @module Static
|
||||
-- @author FlightControl
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- The STATIC class
|
||||
-- @type STATIC
|
||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||
-- @field #STATIC
|
||||
STATIC = {
|
||||
ClassName = "STATIC",
|
||||
}
|
||||
|
||||
@@ -9,8 +9,17 @@
|
||||
-- * Handle local Unit Controller.
|
||||
-- * Manage the "state" of the DCS Unit.
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- ### Author: **Sven Van de Velde (FlightControl)**
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- ====
|
||||
--
|
||||
-- @module Unit
|
||||
|
||||
|
||||
--- @type UNIT
|
||||
-- @extends Wrapper.Controllable#CONTROLLABLE
|
||||
|
||||
@@ -315,7 +324,8 @@ function UNIT:GetPlayerName()
|
||||
return PlayerName
|
||||
end
|
||||
|
||||
return nil
|
||||
return nil
|
||||
|
||||
end
|
||||
|
||||
--- Returns the unit's number in the group.
|
||||
@@ -526,7 +536,7 @@ function UNIT:GetLife()
|
||||
return UnitLife
|
||||
end
|
||||
|
||||
return nil
|
||||
return -1
|
||||
end
|
||||
|
||||
--- Returns the Unit's initial health.
|
||||
@@ -543,7 +553,7 @@ function UNIT:GetLife0()
|
||||
return UnitLife0
|
||||
end
|
||||
|
||||
return nil
|
||||
return 0
|
||||
end
|
||||
|
||||
--- Returns the category name of the #UNIT.
|
||||
@@ -588,122 +598,128 @@ end
|
||||
-- @param #UNIT self
|
||||
function UNIT:GetThreatLevel()
|
||||
|
||||
local Attributes = self:GetDesc().attributes
|
||||
self:T( Attributes )
|
||||
|
||||
local ThreatLevel = 0
|
||||
local ThreatText = ""
|
||||
|
||||
if self:IsGround() then
|
||||
local Descriptor = self:GetDesc()
|
||||
|
||||
self:T( "Ground" )
|
||||
if Descriptor then
|
||||
|
||||
local ThreatLevels = {
|
||||
"Unarmed",
|
||||
"Infantry",
|
||||
"Old Tanks & APCs",
|
||||
"Tanks & IFVs without ATGM",
|
||||
"Tanks & IFV with ATGM",
|
||||
"Modern Tanks",
|
||||
"AAA",
|
||||
"IR Guided SAMs",
|
||||
"SR SAMs",
|
||||
"MR SAMs",
|
||||
"LR SAMs"
|
||||
}
|
||||
local Attributes = Descriptor.attributes
|
||||
self:T( Attributes )
|
||||
|
||||
if self:IsGround() then
|
||||
|
||||
self:T( "Ground" )
|
||||
|
||||
if Attributes["LR SAM"] then ThreatLevel = 10
|
||||
elseif Attributes["MR SAM"] then ThreatLevel = 9
|
||||
elseif Attributes["SR SAM"] and
|
||||
not Attributes["IR Guided SAM"] then ThreatLevel = 8
|
||||
elseif ( Attributes["SR SAM"] or Attributes["MANPADS"] ) and
|
||||
Attributes["IR Guided SAM"] then ThreatLevel = 7
|
||||
elseif Attributes["AAA"] then ThreatLevel = 6
|
||||
elseif Attributes["Modern Tanks"] then ThreatLevel = 5
|
||||
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
|
||||
Attributes["ATGM"] then ThreatLevel = 4
|
||||
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
|
||||
not Attributes["ATGM"] then ThreatLevel = 3
|
||||
elseif Attributes["Old Tanks"] or Attributes["APC"] or Attributes["Artillery"] then ThreatLevel = 2
|
||||
elseif Attributes["Infantry"] then ThreatLevel = 1
|
||||
local ThreatLevels = {
|
||||
"Unarmed",
|
||||
"Infantry",
|
||||
"Old Tanks & APCs",
|
||||
"Tanks & IFVs without ATGM",
|
||||
"Tanks & IFV with ATGM",
|
||||
"Modern Tanks",
|
||||
"AAA",
|
||||
"IR Guided SAMs",
|
||||
"SR SAMs",
|
||||
"MR SAMs",
|
||||
"LR SAMs"
|
||||
}
|
||||
|
||||
|
||||
if Attributes["LR SAM"] then ThreatLevel = 10
|
||||
elseif Attributes["MR SAM"] then ThreatLevel = 9
|
||||
elseif Attributes["SR SAM"] and
|
||||
not Attributes["IR Guided SAM"] then ThreatLevel = 8
|
||||
elseif ( Attributes["SR SAM"] or Attributes["MANPADS"] ) and
|
||||
Attributes["IR Guided SAM"] then ThreatLevel = 7
|
||||
elseif Attributes["AAA"] then ThreatLevel = 6
|
||||
elseif Attributes["Modern Tanks"] then ThreatLevel = 5
|
||||
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
|
||||
Attributes["ATGM"] then ThreatLevel = 4
|
||||
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
|
||||
not Attributes["ATGM"] then ThreatLevel = 3
|
||||
elseif Attributes["Old Tanks"] or Attributes["APC"] or Attributes["Artillery"] then ThreatLevel = 2
|
||||
elseif Attributes["Infantry"] then ThreatLevel = 1
|
||||
end
|
||||
|
||||
ThreatText = ThreatLevels[ThreatLevel+1]
|
||||
end
|
||||
|
||||
ThreatText = ThreatLevels[ThreatLevel+1]
|
||||
end
|
||||
|
||||
if self:IsAir() then
|
||||
|
||||
self:T( "Air" )
|
||||
|
||||
local ThreatLevels = {
|
||||
"Unarmed",
|
||||
"Tanker",
|
||||
"AWACS",
|
||||
"Transport Helicpter",
|
||||
"UAV",
|
||||
"Bomber",
|
||||
"Strategic Bomber",
|
||||
"Attack Helicopter",
|
||||
"Battleplane",
|
||||
"Multirole Fighter",
|
||||
"Fighter"
|
||||
}
|
||||
if self:IsAir() then
|
||||
|
||||
|
||||
if Attributes["Fighters"] then ThreatLevel = 10
|
||||
elseif Attributes["Multirole fighters"] then ThreatLevel = 9
|
||||
elseif Attributes["Battleplanes"] then ThreatLevel = 8
|
||||
elseif Attributes["Attack helicopters"] then ThreatLevel = 7
|
||||
elseif Attributes["Strategic bombers"] then ThreatLevel = 6
|
||||
elseif Attributes["Bombers"] then ThreatLevel = 5
|
||||
elseif Attributes["UAVs"] then ThreatLevel = 4
|
||||
elseif Attributes["Transport helicopters"] then ThreatLevel = 3
|
||||
elseif Attributes["AWACS"] then ThreatLevel = 2
|
||||
elseif Attributes["Tankers"] then ThreatLevel = 1
|
||||
self:T( "Air" )
|
||||
|
||||
local ThreatLevels = {
|
||||
"Unarmed",
|
||||
"Tanker",
|
||||
"AWACS",
|
||||
"Transport Helicopter",
|
||||
"UAV",
|
||||
"Bomber",
|
||||
"Strategic Bomber",
|
||||
"Attack Helicopter",
|
||||
"Battleplane",
|
||||
"Multirole Fighter",
|
||||
"Fighter"
|
||||
}
|
||||
|
||||
|
||||
if Attributes["Fighters"] then ThreatLevel = 10
|
||||
elseif Attributes["Multirole fighters"] then ThreatLevel = 9
|
||||
elseif Attributes["Battleplanes"] then ThreatLevel = 8
|
||||
elseif Attributes["Attack helicopters"] then ThreatLevel = 7
|
||||
elseif Attributes["Strategic bombers"] then ThreatLevel = 6
|
||||
elseif Attributes["Bombers"] then ThreatLevel = 5
|
||||
elseif Attributes["UAVs"] then ThreatLevel = 4
|
||||
elseif Attributes["Transport helicopters"] then ThreatLevel = 3
|
||||
elseif Attributes["AWACS"] then ThreatLevel = 2
|
||||
elseif Attributes["Tankers"] then ThreatLevel = 1
|
||||
end
|
||||
|
||||
ThreatText = ThreatLevels[ThreatLevel+1]
|
||||
end
|
||||
|
||||
ThreatText = ThreatLevels[ThreatLevel+1]
|
||||
end
|
||||
|
||||
if self:IsShip() then
|
||||
|
||||
self:T( "Ship" )
|
||||
|
||||
--["Aircraft Carriers"] = {"Heavy armed ships",},
|
||||
--["Cruisers"] = {"Heavy armed ships",},
|
||||
--["Destroyers"] = {"Heavy armed ships",},
|
||||
--["Frigates"] = {"Heavy armed ships",},
|
||||
--["Corvettes"] = {"Heavy armed ships",},
|
||||
--["Heavy armed ships"] = {"Armed ships", "Armed Air Defence", "HeavyArmoredUnits",},
|
||||
--["Light armed ships"] = {"Armed ships","NonArmoredUnits"},
|
||||
--["Armed ships"] = {"Ships"},
|
||||
--["Unarmed ships"] = {"Ships","HeavyArmoredUnits",},
|
||||
|
||||
local ThreatLevels = {
|
||||
"Unarmed ship",
|
||||
"Light armed ships",
|
||||
"Corvettes",
|
||||
"",
|
||||
"Frigates",
|
||||
"",
|
||||
"Cruiser",
|
||||
"",
|
||||
"Destroyer",
|
||||
"",
|
||||
"Aircraft Carrier"
|
||||
}
|
||||
|
||||
if self:IsShip() then
|
||||
|
||||
self:T( "Ship" )
|
||||
|
||||
--["Aircraft Carriers"] = {"Heavy armed ships",},
|
||||
--["Cruisers"] = {"Heavy armed ships",},
|
||||
--["Destroyers"] = {"Heavy armed ships",},
|
||||
--["Frigates"] = {"Heavy armed ships",},
|
||||
--["Corvettes"] = {"Heavy armed ships",},
|
||||
--["Heavy armed ships"] = {"Armed ships", "Armed Air Defence", "HeavyArmoredUnits",},
|
||||
--["Light armed ships"] = {"Armed ships","NonArmoredUnits"},
|
||||
--["Armed ships"] = {"Ships"},
|
||||
--["Unarmed ships"] = {"Ships","HeavyArmoredUnits",},
|
||||
|
||||
if Attributes["Aircraft Carriers"] then ThreatLevel = 10
|
||||
elseif Attributes["Destroyers"] then ThreatLevel = 8
|
||||
elseif Attributes["Cruisers"] then ThreatLevel = 6
|
||||
elseif Attributes["Frigates"] then ThreatLevel = 4
|
||||
elseif Attributes["Corvettes"] then ThreatLevel = 2
|
||||
elseif Attributes["Light armed ships"] then ThreatLevel = 1
|
||||
local ThreatLevels = {
|
||||
"Unarmed ship",
|
||||
"Light armed ships",
|
||||
"Corvettes",
|
||||
"",
|
||||
"Frigates",
|
||||
"",
|
||||
"Cruiser",
|
||||
"",
|
||||
"Destroyer",
|
||||
"",
|
||||
"Aircraft Carrier"
|
||||
}
|
||||
|
||||
|
||||
if Attributes["Aircraft Carriers"] then ThreatLevel = 10
|
||||
elseif Attributes["Destroyers"] then ThreatLevel = 8
|
||||
elseif Attributes["Cruisers"] then ThreatLevel = 6
|
||||
elseif Attributes["Frigates"] then ThreatLevel = 4
|
||||
elseif Attributes["Corvettes"] then ThreatLevel = 2
|
||||
elseif Attributes["Light armed ships"] then ThreatLevel = 1
|
||||
end
|
||||
|
||||
ThreatText = ThreatLevels[ThreatLevel+1]
|
||||
end
|
||||
|
||||
ThreatText = ThreatLevels[ThreatLevel+1]
|
||||
end
|
||||
|
||||
self:T2( ThreatLevel )
|
||||
@@ -778,92 +794,6 @@ end
|
||||
|
||||
|
||||
|
||||
--- Signal a flare at the position of the UNIT.
|
||||
-- @param #UNIT self
|
||||
-- @param Utilities.Utils#FLARECOLOR FlareColor
|
||||
function UNIT:Flare( FlareColor )
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), FlareColor , 0 )
|
||||
end
|
||||
|
||||
--- Signal a white flare at the position of the UNIT.
|
||||
-- @param #UNIT self
|
||||
function UNIT:FlareWhite()
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.White , 0 )
|
||||
end
|
||||
|
||||
--- Signal a yellow flare at the position of the UNIT.
|
||||
-- @param #UNIT self
|
||||
function UNIT:FlareYellow()
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Yellow , 0 )
|
||||
end
|
||||
|
||||
--- Signal a green flare at the position of the UNIT.
|
||||
-- @param #UNIT self
|
||||
function UNIT:FlareGreen()
|
||||
self:F2()
|
||||
trigger.action.signalFlare( self:GetVec3(), trigger.flareColor.Green , 0 )
|
||||
end
|
||||
|
||||
--- Signal a red flare at the position of the UNIT.
|
||||
-- @param #UNIT self
|
||||
function UNIT:FlareRed()
|
||||
self:F2()
|
||||
local Vec3 = self:GetVec3()
|
||||
if Vec3 then
|
||||
trigger.action.signalFlare( Vec3, trigger.flareColor.Red, 0 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Smoke the UNIT.
|
||||
-- @param #UNIT self
|
||||
function UNIT:Smoke( SmokeColor, Range )
|
||||
self:F2()
|
||||
if Range then
|
||||
trigger.action.smoke( self:GetRandomVec3( Range ), SmokeColor )
|
||||
else
|
||||
trigger.action.smoke( self:GetVec3(), SmokeColor )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Smoke the UNIT Green.
|
||||
-- @param #UNIT self
|
||||
function UNIT:SmokeGreen()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Green )
|
||||
end
|
||||
|
||||
--- Smoke the UNIT Red.
|
||||
-- @param #UNIT self
|
||||
function UNIT:SmokeRed()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Red )
|
||||
end
|
||||
|
||||
--- Smoke the UNIT White.
|
||||
-- @param #UNIT self
|
||||
function UNIT:SmokeWhite()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.White )
|
||||
end
|
||||
|
||||
--- Smoke the UNIT Orange.
|
||||
-- @param #UNIT self
|
||||
function UNIT:SmokeOrange()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Orange )
|
||||
end
|
||||
|
||||
--- Smoke the UNIT Blue.
|
||||
-- @param #UNIT self
|
||||
function UNIT:SmokeBlue()
|
||||
self:F2()
|
||||
trigger.action.smoke( self:GetVec3(), trigger.smokeColor.Blue )
|
||||
end
|
||||
|
||||
|
||||
|
||||
-- Is methods
|
||||
|
||||
@@ -5,6 +5,7 @@ Core/Base.lua
|
||||
Core/Scheduler.lua
|
||||
Core/ScheduleDispatcher.lua
|
||||
Core/Event.lua
|
||||
Core/Settings.lua
|
||||
Core/Menu.lua
|
||||
Core/Zone.lua
|
||||
Core/Database.lua
|
||||
@@ -40,6 +41,11 @@ Functional/Detection.lua
|
||||
Functional/Designate.lua
|
||||
|
||||
AI/AI_Balancer.lua
|
||||
AI/AI_A2A.lua
|
||||
AI/AI_A2A_Patrol.lua
|
||||
AI/AI_A2A_Cap.lua
|
||||
AI/AI_A2A_Gci.lua
|
||||
AI/AI_A2A_Dispatcher.lua
|
||||
AI/AI_Patrol.lua
|
||||
AI/AI_Cap.lua
|
||||
AI/AI_Cas.lua
|
||||
@@ -57,6 +63,8 @@ Tasking/Task.lua
|
||||
Tasking/DetectionManager.lua
|
||||
Tasking/Task_A2G_Dispatcher.lua
|
||||
Tasking/Task_A2G.lua
|
||||
Tasking/Task_A2A_Dispatcher.lua
|
||||
Tasking/Task_A2A.lua
|
||||
Tasking/Task_Cargo.lua
|
||||
|
||||
Moose.lua
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
362
Release 2.1.bb
Normal file
362
Release 2.1.bb
Normal file
@@ -0,0 +1,362 @@
|
||||
[SIZE=7]MOOSE Release 2.1.0[/SIZE]
|
||||
|
||||
Finally it is here, release 2.1.0 of MOOSE!
|
||||
It took some time to prepare this release, as it was a lot of work to get the building blocks of the framework developed and tested. You'll find in this release a lot of new features as well as a couple of important bug fixes.
|
||||
|
||||
Release 2.1.0 is now published into the [B]master-release-2.1[/B] branch of this repository on github.
|
||||
You can download the file moose.lua below to use MOOSE in your missions.
|
||||
The moose.lua file is also located [URL="https://github.com/FlightControl-Master/MOOSE/blob/master-release-2.1/Moose%20Mission%20Setup/Moose.lua"]here[/URL] in the [B]master-release-2.1[/B] branch.
|
||||
|
||||
Those who are using the [B]master[/B] branch can continue to beta test, as new bleeding edge features will be added soon in preparation for release 2.2.0! There are many topics on the agenda to be added.
|
||||
|
||||
[B]This release would not have been possible without the help and contribution of many members of this community. THANK YOU![/B]
|
||||
|
||||
|
||||
|
||||
[SIZE=6]In summary:[/SIZE]
|
||||
|
||||
This release brings you [B]an improved tasking mechanism[/B].
|
||||
Tasking is the system in MOOSE that allows to:
|
||||
|
||||
* Execute [B]co-op[/B] missions and tasks
|
||||
* [B]Detect[/B] targets dynamically
|
||||
* Define new tasks [B]dynamically[/B]
|
||||
* Execute the tasks
|
||||
* Complete the mission [B]goals[/B]
|
||||
* Extensive menu system and briefings/reports for [B]player interaction[/B]
|
||||
* Improved Scoring of mission goal achievements, and task achievements.
|
||||
|
||||
On top, release brings you new functionality by the introduction of new classes to:
|
||||
|
||||
* [B]Designate targets[/B] (lase, smoke or illuminate targets) by AI, assisting your attack. Allows to drop laser guides bombs.
|
||||
* A new [B]tasking[/B] system to [B]transport cargo[/B] of various types
|
||||
* Dynamically [B]spawn static objects[/B]
|
||||
* Improved [B]coordinate system[/B]
|
||||
* Build [B]large formations[/B], like bombers flying to a target area
|
||||
|
||||
|
||||
|
||||
|
||||
[SIZE=6]1. TASKING SYSTEM![/SIZE]
|
||||
|
||||
A lot of work has been done in improving the tasking framework within MOOSE.
|
||||
|
||||
**The tasking system comes with TASK DISPATCHING mechanisms, that DYNAMICALLY
|
||||
allocate new tasks based on the tactical or strategical situation in the mission!!!
|
||||
These tasks can then be engaged upon by the players!!!**
|
||||
|
||||
The [URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Task_A2G_Dispatcher.html"]TASK_A2G_DISPATCHER[/URL] class implements the dynamic dispatching of tasks upon groups of detected units determined a Set of FAC (groups). The FAC will detect units, will group them, and will dispatch Tasks to groups of players. Depending on the type of target detected, different tasks will be dispatched. Find a summary below describing for which situation a task type is created:
|
||||
|
||||
* [B]CAS Task[/B]: Is created when there are enemy ground units within range of the FAC, while there are friendly units in the FAC perimeter.
|
||||
* [B]BAI Task[/B]: Is created when there are enemy ground units within range of the FAC, while there are NO other friendly units within the FAC perimeter.
|
||||
* [B]SEAD Task[/B]: Is created when there are enemy ground units wihtin range of the FAC, with air search radars.
|
||||
|
||||
More TASK_... dispatcher classes are to come in the future, like A2A, G2G, etc...
|
||||
|
||||
Improvements on the TASKING are in summary:
|
||||
|
||||
* A COMMANDCENTER has a dedicated menu.
|
||||
* A MISSION has a dedicated menu system.
|
||||
* A MISSION has a briefing report.
|
||||
* A MISSION has dedicated status reports.
|
||||
* A MISSION has for each TASK TYPE a menu.
|
||||
* A MISSION has for each TASK TYPE a dedicated menu system for each TASK defined.
|
||||
* A MISSION has an "assigned" task menu that contains menu actions relevant to the assigned task.
|
||||
* A TASK (of various types) has a dedicated menu system.
|
||||
* A TASK has a briefing report.
|
||||
* A TASK has dedicated status reports.
|
||||
* Player reports can be retrieved that explain which player is at which task.
|
||||
* ...
|
||||
|
||||
TASKING is vast, and at the moment there is too much to explain.
|
||||
[B]The best way to explore the TASKING is to TRY it...[/B]
|
||||
I suggest you have a look at the [URL="https://www.youtube.com/watch?v=v2Us8SS1-44&t=1070s"]GORI Valley Mission - Iteration 3[/URL].
|
||||
|
||||
Many people have contributed in the testing of the mechanism, especially:
|
||||
@baluballa, @doom, @whiplash
|
||||
|
||||
|
||||
|
||||
[SIZE=6]2. New MOOSE classes have been added.[/SIZE]
|
||||
|
||||
MOOSE 2.1.0 comes with new classes that extends the functionality of the MOOSE framework and allow you to do new things in your missions:
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.1. Target designation by laser, smoke or illumination.[/SIZE]
|
||||
|
||||
[URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Designate.html"]DESIGNATE[/URL] is orchestrating the designation of potential targets executed by a Recce group,
|
||||
and communicates these to a dedicated attacking group of players,
|
||||
so that following a dynamically generated menu system,
|
||||
each detected set of potential targets can be lased or smoked...
|
||||
|
||||
Targets can be:
|
||||
|
||||
* [B]Lased[/B] for a period of time.
|
||||
* [B]Smoked[/B]. Artillery or airplanes with Illuminatino ordonance need to be present. (WIP, but early demo ready.)
|
||||
* [B]Illuminated[/B] through an illumination bomb. Artillery or airplanes with Illuminatino ordonance need to be present. (WIP, but early demo ready.
|
||||
|
||||
This class was made with the help of @EasyEB and many others.
|
||||
|
||||
[URL="https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0dQ9UKQMb7YL8z2sKSqemH"]DESIGNATE is demonstrated on youtube[/URL]
|
||||
|
||||
DESIGNATE demonstration missions:
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/DES%20-%20Designation"]DES - Designation[/URL]
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.2. Transport cargo of different types to various locations as a human task within a mission.[/SIZE]
|
||||
|
||||
The Moose framework provides various CARGO classes that allow DCS physical or logical objects to be transported or sling loaded by Carriers.
|
||||
The CARGO_ classes, as part of the moose core, are able to Board, Load, UnBoard and UnLoad cargo between Carrier units.
|
||||
This collection of classes in this module define tasks for human players to handle these cargo objects.
|
||||
Cargo can be transported, picked-up, deployed and sling-loaded from and to other places.
|
||||
|
||||
[URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Task_Cargo.html#TASK_CARGO_TRANSPORT"]TASK_CARGO_TRANSPORT[/URL] defines a task for a human player to transport a set of cargo between various zones.
|
||||
It is the first class that forms part of the TASK_CARGO classes suite.
|
||||
|
||||
The TASK_CARGO classes provide you with a flexible tasking sytem,
|
||||
that allows you to transport cargo of various types between various locations
|
||||
and various dedicated deployment zones.
|
||||
|
||||
A human player can join the battle field in a client airborne slot or a ground vehicle within the CA module (ALT-J).
|
||||
The player needs to accept the task from the task overview list within the mission, using the radio menus.
|
||||
Once the TASK_CARGO_TRANSPORT is assigned to the player and accepted by the player, the player will obtain
|
||||
an extra [B]Cargo Handling Radio Menu[/B] that contains the CARGO objects that need to be transported.
|
||||
Cargo can be transported towards different [B]Deployment Zones[/B], but can also be deployed anywhere within the battle field.
|
||||
|
||||
The Cargo Handling Radio Menu system allows to execute [B]various actions[/B] to handle the cargo.
|
||||
In the menu, you'll find for each CARGO, that is part of the scope of the task, various actions that can be completed.
|
||||
Depending on the location of your Carrier unit, the menu options will vary.
|
||||
|
||||
The [URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Cargo.html#CARGO_GROUP"]CARGO_GROUP[/URL] class defines a
|
||||
cargo that is represented by a GROUP object within the simulator, and can be transported by a carrier.
|
||||
|
||||
The [URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Cargo.html#CARGO_UNIT"]CARGO_UNIT[/URL] class defines a
|
||||
cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
||||
|
||||
Mission designers can use the [URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Set.html#SET_CARGO"]SET_CARGO[/URL]
|
||||
class to build sets of cargos.
|
||||
|
||||
Note 1: [B]Various other CARGO classes are defined and are WIP[/B].
|
||||
Now that the foundation for Cargo handling is getting form, future releases will bring other types of CARGO handling
|
||||
classes to the MOOSE framework quickly. Sling-loading, package, beacon and other types of CARGO will be released soon.
|
||||
|
||||
Note 2: [B]AI_CARGO has been renamed to CARGO and now forms part of the Core or MOOSE[/B].
|
||||
If you were using AI_CARGO in your missions, please rename AI_CARGO with CARGO...
|
||||
|
||||
TASK_TRANSPORT_CARGO is demonstrated at the [URL="https://www.youtube.com/watch?v=v2Us8SS1-44&t=1070s"]GORI Valley Mission - Iteration 4[/URL]
|
||||
|
||||
TASK_TRANSPORT_CARGO demonstration missions:
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-110%20-%20Ground%20-%20Transport%20Cargo%20Group"]TSK-110 - Ground - Transport Cargo Group[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-210%20-%20Helicopter%20-%20Transport%20Cargo%20Group"]TSK-210 - Helicopter - Transport Cargo Group[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-211%20-%20Helicopter%20-%20Transport%20Multiple%20Cargo%20Groups"]TSK-211 - Helicopter - Transport Multiple Cargo Groups[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-212%20-%20Helicopter%20-%20Cargo%20handle%20PickedUp%20and%20Deployed%20events"]TSK-212 - Helicopter - Cargo handle PickedUp and Deployed events[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-213%20-%20Helicopter%20-%20Cargo%20Group%20Destroyed"]TSK-213 - Helicopter - Cargo Group Destroyed[/URL]
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.3. Dynamically spawn STATIC objects into your mission.[/SIZE]
|
||||
|
||||
The [URL="http://flightcontrol-master.github.io/MOOSE/Documentation/SpawnStatic.html#SPAWNSTATIC"]SPAWNSTATIC[/URL] class allows to spawn dynamically new Statics.
|
||||
By creating a copy of an existing static object template as defined in the Mission Editor (ME), SPAWNSTATIC can retireve the properties of the defined static object template (like type, category etc), and "copy" these properties to create a new static object and place it at the desired coordinate.
|
||||
New spawned Statics get the same name as the name of the template Static, or gets the given name when a new name is provided at the Spawn method.
|
||||
|
||||
SPAWNSTATIC demonstration missions:
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/SPS%20-%20Spawning%20Statics/SPS-100%20-%20Simple%20Spawning"]SPS-100 - Simple Spawning[/URL]
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.4. Better coordinate management in MGRS or LLor LLDecimal.[/SIZE]
|
||||
|
||||
The [URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Point.html#COORDINATE"]COORDINATE[/URL] class
|
||||
defines a 2D coordinate in the simulator. A COORDINATE can be expressed in LL or in MGRS.
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.5. Improved scoring system[/SIZE]
|
||||
|
||||
Scoring is implemented throught the [URL="http://flightcontrol-master.github.io/MOOSE/Documentation/Scoring.html"]SCORING[/URL] class.
|
||||
The scoring system has been improved a lot! Now, the scoring is correctly counting scores on normal units, statics and scenary objects.
|
||||
Specific scores can be registered for specific targets. The scoring works together with the tasking system, so players can achieve
|
||||
additional scores when they achieve goals!
|
||||
|
||||
SCORING demonstration missions:
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCO%20-%20Scoring/SCO-100%20-%20Scoring%20of%20Statics"]SCO-100 - Scoring of Statics[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCO%20-%20Scoring/SCO-101%20-%20Scoring%20Client%20to%20Client"]SCO-101 - Scoring Client to Client[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCO%20-%20Scoring/SCO-500%20-%20Scoring%20Multi%20Player%20Demo%20Mission%201"]SCO-500 - Scoring Multi Player Demo Mission 1[/URL]
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.6. Beacons and Radio[/SIZE]
|
||||
|
||||
The Radio contains 2 classes : RADIO and BEACON
|
||||
|
||||
What are radio communications in DCS ?
|
||||
|
||||
* Radio transmissions consist of [B]sound files[/B] that are broadcasted on a specific [B]frequency[/B] (e.g. 115MHz) and [B]modulation[/B] (e.g. AM),
|
||||
* They can be [B]subtitled[/B] for a specific [B]duration[/B], the [B]power[/B] in Watts of the transmiter's antenna can be set, and the transmission can be [B]looped[/B].
|
||||
|
||||
These classes are the work of @Grey-Echo.
|
||||
|
||||
RADIO and BEACON demonstration missions:
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-000%20-%20Transmission%20from%20Static"]RAD-000 - Transmission from Static[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-001%20-%20Transmission%20from%20UNIT%20or%20GROUP"]RAD-001 - Transmission from UNIT or GROUP[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-002%20-%20Transmission%20Tips%20and%20Tricks"]RAD-002 - Transmission Tips and Tricks[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-010%20-%20Beacons"] RAD-010 - Beacons[/URL]
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.7. Build large formations of AI.[/SIZE]
|
||||
|
||||
[URL="http://flightcontrol-master.github.io/MOOSE/Documentation/AI_Formation.html"]AI_FORMATION[/URL] makes AI @{GROUP}s fly in formation of various compositions.
|
||||
The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
|
||||
The purpose of the class is to:
|
||||
|
||||
* Make formation building a process that can be managed while in flight, rather than a task.
|
||||
* Human players can guide formations, consisting of larget planes.
|
||||
* Build large formations (like a large bomber field).
|
||||
* Form formations that DCS does not support off the shelve.
|
||||
|
||||
AI_FORMATION Demo Missions: [URL=""]FOR - AI Group Formation[/URL]
|
||||
|
||||
AI_FORMATION demonstration missions:
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-100%20-%20Bomber%20Left%20Line%20Formation"]FOR-100 - Bomber Left Line Formation[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-101%20-%20Bomber%20Right%20Line%20Formation"]FOR-101 - Bomber Right Line Formation[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-102%20-%20Bomber%20Left%20Wing%20Formation"]FOR-102 - Bomber Left Wing Formation[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-103%20-%20Bomber%20Right%20Wing%20Formation"]FOR-103 - Bomber Right Wing Formation[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-104%20-%20Bomber%20Center%20Wing%20Formation"]FOR-104 - Bomber Center Wing Formation[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-105%20-%20Bomber%20Trail%20Formation"]FOR-105 - Bomber Trail Formation[/URL]
|
||||
* [URL="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-106%20-%20Bomber%20Box%20Formation"]FOR-106 - Bomber Box Formation[/URL]
|
||||
|
||||
Note: The AI_FORMATION is currently a first version showing the potential, a "building block". From this class, further classes will be derived and the class will be fine-tuned.
|
||||
|
||||
|
||||
|
||||
[SIZE=6]3. A lot of components have been reworked and bugs have been fixed.[/SIZE]
|
||||
|
||||
|
||||
|
||||
[SIZE=5]3.1. Better event handling and event dispatching.[/SIZE]
|
||||
|
||||
The underlying mechanisms to handle DCS events has been improved. Bugs have been fixed.
|
||||
The MISSION_END event is now also supported.
|
||||
|
||||
|
||||
|
||||
[SIZE=5]2.2. Cargo handling has been made much better now.[/SIZE]
|
||||
|
||||
As a result, some of the WIP cargo classes that were defined earlier are still WIP.
|
||||
But as mentioned earlier, new CARGO classes can be published faster now.
|
||||
The framework is now more consistent internally.
|
||||
|
||||
|
||||
|
||||
[SIZE=6]3. A lot of new methods have been defined in several existing or new classes.[/SIZE]
|
||||
|
||||
AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefing ) --R2.1
|
||||
AI_FORMATION:TestSmokeDirectionVector( SmokeDirection ) --R2.1
|
||||
AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationTrail( FollowGroupSet, From , Event , To, XStart, XSpace, YStart ) --R2.1
|
||||
AI_FORMATION:onafterFormationStack( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationLeftLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationRightLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationLeftWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationRightWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationVic( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationBox( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, ZLevels ) --R2.1
|
||||
AI_FORMATION:SetFlightRandomization( FlightRandomization ) --R2.1
|
||||
AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
|
||||
|
||||
CARGO:GetName()
|
||||
CARGO:GetObjectName()
|
||||
|
||||
DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... )
|
||||
|
||||
EVENT:Reset( EventObject ) --R2.1
|
||||
|
||||
POINT_VEC3:IsLOS( ToPointVec3 ) --R2.1
|
||||
|
||||
COORDINATE:New( x, y, LandHeightAdd ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:NewFromVec3( Vec3 ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:ToStringLL( LL_Accuracy, LL_DMS ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:ToStringMGRS( MGRS_Accuracy ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:ToString() --R2.1 Fixes issue #424.
|
||||
COORDINATE:CoordinateMenu( RootMenu ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuSystem( System ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuLL_Accuracy( LL_Accuracy ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuLL_DMS( LL_DMS ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuMGRS_Accuracy( MGRS_Accuracy ) --R2.1 Fixes issue #424.
|
||||
|
||||
SET_BASE:FilterDeads() --R2.1 allow deads to be filtered to automatically handle deads in the collection.
|
||||
SET_BASE:FilterCrashes() --R2.1 allow crashes to be filtered to automatically handle crashes in the collection.
|
||||
|
||||
SET_UNIT:ForEachUnitPerThreatLevel( FromThreatLevel, ToThreatLevel, IteratorFunction, ... ) --R2.1 Threat Level implementation
|
||||
|
||||
SET_CARGO:New() --R2.1
|
||||
SET_CARGO:AddCargosByName( AddCargoNames ) --R2.1
|
||||
SET_CARGO:RemoveCargosByName( RemoveCargoNames ) --R2.1
|
||||
SET_CARGO:FindCargo( CargoName ) --R2.1
|
||||
SET_CARGO:FilterCoalitions( Coalitions ) --R2.1
|
||||
SET_CARGO:FilterTypes( Types ) --R2.1
|
||||
SET_CARGO:FilterCountries( Countries ) --R2.1
|
||||
SET_CARGO:FilterPrefixes( Prefixes ) --R2.1
|
||||
SET_CARGO:FilterStart() --R2.1
|
||||
SET_CARGO:AddInDatabase( Event ) --R2.1
|
||||
SET_CARGO:FindInDatabase( Event ) --R2.1
|
||||
SET_CARGO:ForEachCargo( IteratorFunction, ... ) --R2.1
|
||||
SET_CARGO:FindNearestCargoFromPointVec2( PointVec2 ) --R2.1
|
||||
SET_CARGO:IsIncludeObject( MCargo ) --R2.1
|
||||
SET_CARGO:OnEventNewCargo( EventData ) --R2.1
|
||||
SET_CARGO:OnEventDeleteCargo( EventData ) --R2.1 SpawnStatic.lua (5 matches)
|
||||
|
||||
SPAWNSTATIC:NewFromStatic( SpawnTemplatePrefix, CountryID ) --R2.1
|
||||
SPAWNSTATIC:NewFromType( SpawnTypeName, SpawnShapeName, SpawnCategory, CountryID ) --R2.1
|
||||
SPAWNSTATIC:SpawnFromPointVec2( PointVec2, Heading, NewName ) --R2.1
|
||||
SPAWNSTATIC:SpawnFromZone( Zone, Heading, NewName ) --R2.1
|
||||
|
||||
ZONE_BASE:GetCoordinate( Height ) --R2.1
|
||||
|
||||
DESIGNATE:SetFlashStatusMenu( FlashMenu ) --R2.1
|
||||
DESIGNATE:SetLaserCodes( LaserCodes ) --R2.1
|
||||
DESIGNATE:GenerateLaserCodes() --R2.1
|
||||
DESIGNATE:SetAutoLase( AutoLase ) --R2.1
|
||||
DESIGNATE:SetThreatLevelPrioritization( Prioritize ) --R2.1
|
||||
|
||||
DETECTION_BASE:CleanDetectionItems() --R2.1 Clean the DetectionItems list
|
||||
DETECTION_BASE:GetDetectedItemID( Index ) --R2.1
|
||||
DETECTION_BASE:GetDetectedID( Index ) --R2.1
|
||||
DETECTION_AREAS:DetectedReportDetailed() --R2.1 Fixed missing report
|
||||
|
||||
REPORT:HasText() --R2.1
|
||||
REPORT:SetIndent( Indent ) --R2.1
|
||||
REPORT:AddIndent( Text ) --R2.1
|
||||
|
||||
MISSION:GetMenu( TaskGroup ) -- R2.1 -- Changed Menu Structure
|
||||
|
||||
TASK:SetMenu( MenuTime ) --R2.1 Mission Reports and Task Reports added. Fixes issue #424.
|
||||
TASK:ReportSummary() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
TASK:ReportOverview() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
TASK:GetPlayerCount() --R2.1 Get a count of the players.
|
||||
TASK:GetPlayerNames() --R2.1 Get a map of the players.
|
||||
TASK:ReportDetails() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
|
||||
UTILS.tostringMGRS = function(MGRS, acc) --R2.1
|
||||
|
||||
POSITIONABLE:GetBoundingBox() --R2.1
|
||||
POSITIONABLE:GetHeight() --R2.1
|
||||
POSITIONABLE:GetMessageText( Message, Name ) --R2.1 added
|
||||
POSITIONABLE:GetMessage( Message, Duration, Name ) --R2.1 changed callsign and name and using GetMessageText
|
||||
POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Name ) --R2.1
|
||||
POSITIONABLE:GetRadio() --R2.1
|
||||
POSITIONABLE:GetBeacon() --R2.1
|
||||
POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) --R2.1
|
||||
POSITIONABLE:LaseOff() --R2.1
|
||||
POSITIONABLE:IsLasing() --R2.1
|
||||
POSITIONABLE:GetSpot() --R2.1
|
||||
POSITIONABLE:GetLaserCode() --R2.1
|
||||
|
||||
UNIT:IsDetected( TargetUnit ) --R2.1
|
||||
UNIT:IsLOS( TargetUnit ) --R2.1
|
||||
363
Release 2.1.md
Normal file
363
Release 2.1.md
Normal file
@@ -0,0 +1,363 @@
|
||||
# MOOSE Release 2.1.0
|
||||
|
||||
Finally it is here, release 2.1.0 of MOOSE!
|
||||
It took some time to prepare this release, as it was a lot of work to get the building blocks of the framework developed and tested. You'll find in this release a lot of new features as well as a couple of important bug fixes.
|
||||
|
||||
Release 2.1.0 is now published into the **master-release-2.1** branch of this repository on github.
|
||||
You can download the file moose.lua below to use MOOSE in your missions.
|
||||
The moose.lua file is also located [here](https://github.com/FlightControl-Master/MOOSE/blob/master-release-2.1/Moose%20Mission%20Setup/Moose.lua) in the **master-release-2.1** branch.
|
||||
|
||||
Those who are using the **master** branch can continue to beta test, as new bleeding edge features will be added soon in preparation for release 2.2.0! There are many topics on the agenda to be added.
|
||||
|
||||
**This release would not have been possible without the help and contribution of many
|
||||
members of this community. THANK YOU!**
|
||||
|
||||
|
||||
|
||||
## In summary:
|
||||
|
||||
This release brings you **an improved tasking mechanism**.
|
||||
Tasking is the system in MOOSE that allows to:
|
||||
|
||||
* Execute **co-op** missions and tasks
|
||||
* **Detect** targets dynamically
|
||||
* Define new tasks **dynamically**
|
||||
* Execute the tasks
|
||||
* Complete the mission **goals**
|
||||
* Extensive menu system and briefings/reports for **player interaction**
|
||||
* Improved Scoring of mission goal achievements, and task achievements.
|
||||
|
||||
On top, release brings you new functionality by the introduction of new classes to:
|
||||
|
||||
* **Designate targets** (lase, smoke or illuminate targets) by AI, assisting your attack. Allows to drop laser guides bombs.
|
||||
* A new **tasking** system to **transport cargo** of various types
|
||||
* Dynamically **spawn static objects**
|
||||
* Improved **coordinate system**
|
||||
* Build **large formations**, like bombers flying to a target area
|
||||
|
||||
|
||||
|
||||
|
||||
## 1. TASKING SYSTEM!
|
||||
|
||||
A lot of work has been done in improving the tasking framework within MOOSE.
|
||||
|
||||
**The tasking system comes with TASK DISPATCHING mechanisms, that DYNAMICALLY
|
||||
allocate new tasks based on the tactical or strategical situation in the mission!!!
|
||||
These tasks can then be engaged upon by the players!!!**
|
||||
|
||||
The [TASK\_A2G\_DISPATCHER](http://flightcontrol-master.github.io/MOOSE/Documentation/Task_A2G_Dispatcher.html) class implements the dynamic dispatching of tasks upon groups of detected units determined a Set of FAC (groups). The FAC will detect units, will group them, and will dispatch Tasks to groups of players. Depending on the type of target detected, different tasks will be dispatched. Find a summary below describing for which situation a task type is created:
|
||||
|
||||
* **CAS Task**: Is created when there are enemy ground units within range of the FAC, while there are friendly units in the FAC perimeter.
|
||||
* **BAI Task**: Is created when there are enemy ground units within range of the FAC, while there are NO other friendly units within the FAC perimeter.
|
||||
* **SEAD Task**: Is created when there are enemy ground units wihtin range of the FAC, with air search radars.
|
||||
|
||||
More TASK_... dispatcher classes are to come in the future, like A2A, G2G, etc...
|
||||
|
||||
Improvements on the TASKING are in summary:
|
||||
|
||||
* A COMMANDCENTER has a dedicated menu.
|
||||
* A MISSION has a dedicated menu system.
|
||||
* A MISSION has a briefing report.
|
||||
* A MISSION has dedicated status reports.
|
||||
* A MISSION has for each TASK TYPE a menu.
|
||||
* A MISSION has for each TASK TYPE a dedicated menu system for each TASK defined.
|
||||
* A MISSION has an "assigned" task menu that contains menu actions relevant to the assigned task.
|
||||
* A TASK (of various types) has a dedicated menu system.
|
||||
* A TASK has a briefing report.
|
||||
* A TASK has dedicated status reports.
|
||||
* Player reports can be retrieved that explain which player is at which task.
|
||||
* ...
|
||||
|
||||
TASKING is vast, and at the moment there is too much to explain.
|
||||
**The best way to explore the TASKING is to TRY it...**
|
||||
I suggest you have a look at the [GORI Valley Mission - Iteration 3](https://www.youtube.com/watch?v=v2Us8SS1-44&t=1070s).
|
||||
|
||||
Many people have contributed in the testing of the mechanism, especially:
|
||||
@baluballa, @doom, @whiplash
|
||||
|
||||
|
||||
|
||||
## 2. New MOOSE classes have been added.
|
||||
|
||||
MOOSE 2.1.0 comes with new classes that extends the functionality of the MOOSE framework and allow you to do new things in your missions:
|
||||
|
||||
|
||||
|
||||
### 2.1. Target designation by laser, smoke or illumination.
|
||||
|
||||
[DESIGNATE](http://flightcontrol-master.github.io/MOOSE/Documentation/Designate.html) is orchestrating the designation of potential targets executed by a Recce group,
|
||||
and communicates these to a dedicated attacking group of players,
|
||||
so that following a dynamically generated menu system,
|
||||
each detected set of potential targets can be lased or smoked...
|
||||
|
||||
Targets can be:
|
||||
|
||||
* **Lased** for a period of time.
|
||||
* **Smoked**. Artillery or airplanes with Illuminatino ordonance need to be present. (WIP, but early demo ready.)
|
||||
* **Illuminated** through an illumination bomb. Artillery or airplanes with Illuminatino ordonance need to be present. (WIP, but early demo ready.
|
||||
|
||||
This class was made with the help of @EasyEB and many others.
|
||||
|
||||
[DESIGNATE is demonstrated on youtube](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl0dQ9UKQMb7YL8z2sKSqemH)
|
||||
|
||||
DESIGNATE demonstration missions:
|
||||
* [DES - Designation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/DES%20-%20Designation)
|
||||
|
||||
|
||||
|
||||
### 2.2. Transport cargo of different types to various locations as a human task within a mission.
|
||||
|
||||
The Moose framework provides various CARGO classes that allow DCS physical or logical objects to be transported or sling loaded by Carriers.
|
||||
The CARGO_ classes, as part of the moose core, are able to Board, Load, UnBoard and UnLoad cargo between Carrier units.
|
||||
This collection of classes in this module define tasks for human players to handle these cargo objects.
|
||||
Cargo can be transported, picked-up, deployed and sling-loaded from and to other places.
|
||||
|
||||
[TASK\_CARGO\_TRANSPORT](http://flightcontrol-master.github.io/MOOSE/Documentation/Task_Cargo.html#TASK_CARGO_TRANSPORT) defines a task for a human player to transport a set of cargo between various zones.
|
||||
It is the first class that forms part of the TASK_CARGO classes suite.
|
||||
|
||||
The TASK_CARGO classes provide you with a flexible tasking sytem,
|
||||
that allows you to transport cargo of various types between various locations
|
||||
and various dedicated deployment zones.
|
||||
|
||||
A human player can join the battle field in a client airborne slot or a ground vehicle within the CA module (ALT-J).
|
||||
The player needs to accept the task from the task overview list within the mission, using the radio menus.
|
||||
Once the TASK\_CARGO\_TRANSPORT is assigned to the player and accepted by the player, the player will obtain
|
||||
an extra **Cargo Handling Radio Menu** that contains the CARGO objects that need to be transported.
|
||||
Cargo can be transported towards different **Deployment Zones**, but can also be deployed anywhere within the battle field.
|
||||
|
||||
The Cargo Handling Radio Menu system allows to execute **various actions** to handle the cargo.
|
||||
In the menu, you'll find for each CARGO, that is part of the scope of the task, various actions that can be completed.
|
||||
Depending on the location of your Carrier unit, the menu options will vary.
|
||||
|
||||
The [CARGO_GROUP](http://flightcontrol-master.github.io/MOOSE/Documentation/Cargo.html#CARGO_GROUP) class defines a
|
||||
cargo that is represented by a GROUP object within the simulator, and can be transported by a carrier.
|
||||
|
||||
The [CARGO_UNIT](http://flightcontrol-master.github.io/MOOSE/Documentation/Cargo.html#CARGO_UNIT) class defines a
|
||||
cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier.
|
||||
|
||||
Mission designers can use the [SET_CARGO](http://flightcontrol-master.github.io/MOOSE/Documentation/Set.html#SET_CARGO)
|
||||
class to build sets of cargos.
|
||||
|
||||
Note 1: **Various other CARGO classes are defined and are WIP**.
|
||||
Now that the foundation for Cargo handling is getting form, future releases will bring other types of CARGO handling
|
||||
classes to the MOOSE framework quickly. Sling-loading, package, beacon and other types of CARGO will be released soon.
|
||||
|
||||
Note 2: **AI_CARGO has been renamed to CARGO and now forms part of the Core or MOOSE**.
|
||||
If you were using AI_CARGO in your missions, please rename AI_CARGO with CARGO...
|
||||
|
||||
TASK\_TRANSPORT\_CARGO is demonstrated at the [GORI Valley Mission - Iteration 4](https://www.youtube.com/watch?v=v2Us8SS1-44&t=1070s)
|
||||
|
||||
TASK_TRANSPORT_CARGO demonstration missions:
|
||||
* [TSK-110 - Ground - Transport Cargo Group](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-110%20-%20Ground%20-%20Transport%20Cargo%20Group)
|
||||
* [TSK-210 - Helicopter - Transport Cargo Group](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-210%20-%20Helicopter%20-%20Transport%20Cargo%20Group)
|
||||
* [TSK-211 - Helicopter - Transport Multiple Cargo Groups](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-211%20-%20Helicopter%20-%20Transport%20Multiple%20Cargo%20Groups)
|
||||
* [TSK-212 - Helicopter - Cargo handle PickedUp and Deployed events](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-212%20-%20Helicopter%20-%20Cargo%20handle%20PickedUp%20and%20Deployed%20events)
|
||||
* [TSK-213 - Helicopter - Cargo Group Destroyed](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/TSK%20-%20Task%20Modelling/TSK-213%20-%20Helicopter%20-%20Cargo%20Group%20Destroyed)
|
||||
|
||||
|
||||
|
||||
### 2.3. Dynamically spawn STATIC objects into your mission.
|
||||
|
||||
The [SPAWNSTATIC](http://flightcontrol-master.github.io/MOOSE/Documentation/SpawnStatic.html#SPAWNSTATIC) class allows to spawn dynamically new Statics.
|
||||
By creating a copy of an existing static object template as defined in the Mission Editor (ME), SPAWNSTATIC can retireve the properties of the defined static object template (like type, category etc), and "copy" these properties to create a new static object and place it at the desired coordinate.
|
||||
New spawned Statics get the same name as the name of the template Static, or gets the given name when a new name is provided at the Spawn method.
|
||||
|
||||
SPAWNSTATIC demonstration missions:
|
||||
* [SPS-100 - Simple Spawning](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release-2.1/SPS%20-%20Spawning%20Statics/SPS-100%20-%20Simple%20Spawning)
|
||||
|
||||
|
||||
|
||||
### 2.4. Better coordinate management in MGRS or LLor LLDecimal.
|
||||
|
||||
The [COORDINATE](http://flightcontrol-master.github.io/MOOSE/Documentation/Point.html#COORDINATE) class
|
||||
defines a 2D coordinate in the simulator. A COORDINATE can be expressed in LL or in MGRS.
|
||||
|
||||
|
||||
|
||||
### 2.5. Improved scoring system
|
||||
|
||||
Scoring is implemented throught the [SCORING](http://flightcontrol-master.github.io/MOOSE/Documentation/Scoring.html) class.
|
||||
The scoring system has been improved a lot! Now, the scoring is correctly counting scores on normal units, statics and scenary objects.
|
||||
Specific scores can be registered for specific targets. The scoring works together with the tasking system, so players can achieve
|
||||
additional scores when they achieve goals!
|
||||
|
||||
SCORING demonstration missions:
|
||||
* [SCO-100 - Scoring of Statics](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCO%20-%20Scoring/SCO-100%20-%20Scoring%20of%20Statics)
|
||||
* [SCO-101 - Scoring Client to Client](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCO%20-%20Scoring/SCO-101%20-%20Scoring%20Client%20to%20Client)
|
||||
* [SCO-500 - Scoring Multi Player Demo Mission 1](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCO%20-%20Scoring/SCO-500%20-%20Scoring%20Multi%20Player%20Demo%20Mission%201)
|
||||
|
||||
|
||||
|
||||
### 2.6. Beacons and Radio
|
||||
|
||||
The Radio contains 2 classes : RADIO and BEACON
|
||||
|
||||
What are radio communications in DCS ?
|
||||
|
||||
* Radio transmissions consist of **sound files** that are broadcasted on a specific **frequency** (e.g. 115MHz) and **modulation** (e.g. AM),
|
||||
* They can be **subtitled** for a specific **duration**, the **power** in Watts of the transmiter's antenna can be set, and the transmission can be **looped**.
|
||||
|
||||
These classes are the work of @Grey-Echo.
|
||||
|
||||
RADIO and BEACON demonstration missions:
|
||||
* [RAD-000 - Transmission from Static](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-000%20-%20Transmission%20from%20Static)
|
||||
* [RAD-001 - Transmission from UNIT or GROUP](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-001%20-%20Transmission%20from%20UNIT%20or%20GROUP)
|
||||
* [RAD-002 - Transmission Tips and Tricks](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-002%20-%20Transmission%20Tips%20and%20Tricks)
|
||||
* [ RAD-010 - Beacons](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/RAD%20-%20Radio/RAD-010%20-%20Beacons)
|
||||
|
||||
|
||||
|
||||
### 2.7. Build large formations of AI.
|
||||
|
||||
[AI_FORMATION](http://flightcontrol-master.github.io/MOOSE/Documentation/AI_Formation.html) makes AI @{GROUP}s fly in formation of various compositions.
|
||||
The AI_FORMATION class models formations in a different manner than the internal DCS formation logic!!!
|
||||
The purpose of the class is to:
|
||||
|
||||
* Make formation building a process that can be managed while in flight, rather than a task.
|
||||
* Human players can guide formations, consisting of larget planes.
|
||||
* Build large formations (like a large bomber field).
|
||||
* Form formations that DCS does not support off the shelve.
|
||||
|
||||
AI_FORMATION Demo Missions: [FOR - AI Group Formation]()
|
||||
|
||||
AI\_FORMATION demonstration missions:
|
||||
* [FOR-100 - Bomber Left Line Formation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-100%20-%20Bomber%20Left%20Line%20Formation)
|
||||
* [FOR-101 - Bomber Right Line Formation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-101%20-%20Bomber%20Right%20Line%20Formation)
|
||||
* [FOR-102 - Bomber Left Wing Formation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-102%20-%20Bomber%20Left%20Wing%20Formation)
|
||||
* [FOR-103 - Bomber Right Wing Formation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-103%20-%20Bomber%20Right%20Wing%20Formation)
|
||||
* [FOR-104 - Bomber Center Wing Formation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-104%20-%20Bomber%20Center%20Wing%20Formation)
|
||||
* [FOR-105 - Bomber Trail Formation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-105%20-%20Bomber%20Trail%20Formation)
|
||||
* [FOR-106 - Bomber Box Formation](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/FOR%20-%20AI%20Group%20Formation/FOR-106%20-%20Bomber%20Box%20Formation)
|
||||
|
||||
Note: The AI_FORMATION is currently a first version showing the potential, a "building block". From this class, further classes will be derived and the class will be fine-tuned.
|
||||
|
||||
|
||||
|
||||
## 3. A lot of components have been reworked and bugs have been fixed.
|
||||
|
||||
|
||||
|
||||
### 3.1. Better event handling and event dispatching.
|
||||
|
||||
The underlying mechanisms to handle DCS events has been improved. Bugs have been fixed.
|
||||
The MISSION_END event is now also supported.
|
||||
|
||||
|
||||
|
||||
### 2.2. Cargo handling has been made much better now.
|
||||
|
||||
As a result, some of the WIP cargo classes that were defined earlier are still WIP.
|
||||
But as mentioned earlier, new CARGO classes can be published faster now.
|
||||
The framework is now more consistent internally.
|
||||
|
||||
|
||||
|
||||
## 3. A lot of new methods have been defined in several existing or new classes.
|
||||
|
||||
AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefing ) --R2.1
|
||||
AI_FORMATION:TestSmokeDirectionVector( SmokeDirection ) --R2.1
|
||||
AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationTrail( FollowGroupSet, From , Event , To, XStart, XSpace, YStart ) --R2.1
|
||||
AI_FORMATION:onafterFormationStack( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationLeftLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationRightLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationLeftWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationRightWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationVic( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace ) --R2.1
|
||||
AI_FORMATION:onafterFormationBox( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, ZLevels ) --R2.1
|
||||
AI_FORMATION:SetFlightRandomization( FlightRandomization ) --R2.1
|
||||
AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
|
||||
|
||||
CARGO:GetName()
|
||||
CARGO:GetObjectName()
|
||||
|
||||
DATABASE:ForEachStatic( IteratorFunction, FinalizeFunction, ... )
|
||||
|
||||
EVENT:Reset( EventObject ) --R2.1
|
||||
|
||||
POINT_VEC3:IsLOS( ToPointVec3 ) --R2.1
|
||||
|
||||
COORDINATE:New( x, y, LandHeightAdd ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:NewFromVec2( Vec2, LandHeightAdd ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:NewFromVec3( Vec3 ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:ToStringLL( LL_Accuracy, LL_DMS ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:ToStringMGRS( MGRS_Accuracy ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:ToString() --R2.1 Fixes issue #424.
|
||||
COORDINATE:CoordinateMenu( RootMenu ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuSystem( System ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuLL_Accuracy( LL_Accuracy ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuLL_DMS( LL_DMS ) --R2.1 Fixes issue #424.
|
||||
COORDINATE:MenuMGRS_Accuracy( MGRS_Accuracy ) --R2.1 Fixes issue #424.
|
||||
|
||||
SET_BASE:FilterDeads() --R2.1 allow deads to be filtered to automatically handle deads in the collection.
|
||||
SET_BASE:FilterCrashes() --R2.1 allow crashes to be filtered to automatically handle crashes in the collection.
|
||||
|
||||
SET_UNIT:ForEachUnitPerThreatLevel( FromThreatLevel, ToThreatLevel, IteratorFunction, ... ) --R2.1 Threat Level implementation
|
||||
|
||||
SET_CARGO:New() --R2.1
|
||||
SET_CARGO:AddCargosByName( AddCargoNames ) --R2.1
|
||||
SET_CARGO:RemoveCargosByName( RemoveCargoNames ) --R2.1
|
||||
SET_CARGO:FindCargo( CargoName ) --R2.1
|
||||
SET_CARGO:FilterCoalitions( Coalitions ) --R2.1
|
||||
SET_CARGO:FilterTypes( Types ) --R2.1
|
||||
SET_CARGO:FilterCountries( Countries ) --R2.1
|
||||
SET_CARGO:FilterPrefixes( Prefixes ) --R2.1
|
||||
SET_CARGO:FilterStart() --R2.1
|
||||
SET_CARGO:AddInDatabase( Event ) --R2.1
|
||||
SET_CARGO:FindInDatabase( Event ) --R2.1
|
||||
SET_CARGO:ForEachCargo( IteratorFunction, ... ) --R2.1
|
||||
SET_CARGO:FindNearestCargoFromPointVec2( PointVec2 ) --R2.1
|
||||
SET_CARGO:IsIncludeObject( MCargo ) --R2.1
|
||||
SET_CARGO:OnEventNewCargo( EventData ) --R2.1
|
||||
SET_CARGO:OnEventDeleteCargo( EventData ) --R2.1 SpawnStatic.lua (5 matches)
|
||||
|
||||
SPAWNSTATIC:NewFromStatic( SpawnTemplatePrefix, CountryID ) --R2.1
|
||||
SPAWNSTATIC:NewFromType( SpawnTypeName, SpawnShapeName, SpawnCategory, CountryID ) --R2.1
|
||||
SPAWNSTATIC:SpawnFromPointVec2( PointVec2, Heading, NewName ) --R2.1
|
||||
SPAWNSTATIC:SpawnFromZone( Zone, Heading, NewName ) --R2.1
|
||||
|
||||
ZONE_BASE:GetCoordinate( Height ) --R2.1
|
||||
|
||||
DESIGNATE:SetFlashStatusMenu( FlashMenu ) --R2.1
|
||||
DESIGNATE:SetLaserCodes( LaserCodes ) --R2.1
|
||||
DESIGNATE:GenerateLaserCodes() --R2.1
|
||||
DESIGNATE:SetAutoLase( AutoLase ) --R2.1
|
||||
DESIGNATE:SetThreatLevelPrioritization( Prioritize ) --R2.1
|
||||
|
||||
DETECTION_BASE:CleanDetectionItems() --R2.1 Clean the DetectionItems list
|
||||
DETECTION_BASE:GetDetectedItemID( Index ) --R2.1
|
||||
DETECTION_BASE:GetDetectedID( Index ) --R2.1
|
||||
DETECTION_AREAS:DetectedReportDetailed() --R2.1 Fixed missing report
|
||||
|
||||
REPORT:HasText() --R2.1
|
||||
REPORT:SetIndent( Indent ) --R2.1
|
||||
REPORT:AddIndent( Text ) --R2.1
|
||||
|
||||
MISSION:GetMenu( TaskGroup ) -- R2.1 -- Changed Menu Structure
|
||||
|
||||
TASK:SetMenu( MenuTime ) --R2.1 Mission Reports and Task Reports added. Fixes issue #424.
|
||||
TASK:ReportSummary() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
TASK:ReportOverview() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
TASK:GetPlayerCount() --R2.1 Get a count of the players.
|
||||
TASK:GetPlayerNames() --R2.1 Get a map of the players.
|
||||
TASK:ReportDetails() --R2.1 fixed report. Now nicely formatted and contains the info required.
|
||||
|
||||
UTILS.tostringMGRS = function(MGRS, acc) --R2.1
|
||||
|
||||
POSITIONABLE:GetBoundingBox() --R2.1
|
||||
POSITIONABLE:GetHeight() --R2.1
|
||||
POSITIONABLE:GetMessageText( Message, Name ) --R2.1 added
|
||||
POSITIONABLE:GetMessage( Message, Duration, Name ) --R2.1 changed callsign and name and using GetMessageText
|
||||
POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Name ) --R2.1
|
||||
POSITIONABLE:GetRadio() --R2.1
|
||||
POSITIONABLE:GetBeacon() --R2.1
|
||||
POSITIONABLE:LaseUnit( Target, LaserCode, Duration ) --R2.1
|
||||
POSITIONABLE:LaseOff() --R2.1
|
||||
POSITIONABLE:IsLasing() --R2.1
|
||||
POSITIONABLE:GetSpot() --R2.1
|
||||
POSITIONABLE:GetLaserCode() --R2.1
|
||||
|
||||
UNIT:IsDetected( TargetUnit ) --R2.1
|
||||
UNIT:IsLOS( TargetUnit ) --R2.1
|
||||
@@ -5,9 +5,9 @@ echo Generating LuaDocumentor Documentation
|
||||
echo --------------------------------------
|
||||
call luadocumentor.bat
|
||||
|
||||
:: Generate Slate documentation
|
||||
echo Generating Slate Documentation
|
||||
echo ------------------------------
|
||||
cd "Slate Documentation Generator"
|
||||
call Generate.bat
|
||||
cd ..
|
||||
rem :: Generate Slate documentation
|
||||
rem echo Generating Slate Documentation
|
||||
rem echo ------------------------------
|
||||
rem cd "Slate Documentation Generator"
|
||||
rem call Generate.bat
|
||||
rem cd ..
|
||||
19
Utils/Patterns.txt
Normal file
19
Utils/Patterns.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
Replace hyperlinks from md to bb
|
||||
\[(.*?)\]\((.*?)\)
|
||||
[URL="$2"]$1[/URL]
|
||||
|
||||
Replace bold from md to bb
|
||||
\*\*(.*?)\*\*
|
||||
[b]$1[/b]
|
||||
|
||||
Replace heading 3 from md to bb
|
||||
### (.*?)$
|
||||
[SIZE=5]$1[/SIZE]
|
||||
|
||||
Replace heading 2 from md to bb
|
||||
## (.*?)$
|
||||
[SIZE=6]$1[/SIZE]
|
||||
|
||||
Replace heading 1 from md to bb
|
||||
# (.*?)$
|
||||
[SIZE=7]$1[/SIZE]
|
||||
@@ -1,35 +0,0 @@
|
||||
@K=function, @M=Task_A2G, @N=onafterRouteToRendezVous, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=5157,
|
||||
@K=function, @M=Task_A2G, @N=OnAfterArriveAtRendezVous, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=5817,
|
||||
@K=function, @M=Task_A2G, @N=onafterEngage, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=6214,
|
||||
@K=function, @M=Task_A2G, @N=onafterRouteToTarget, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=6536,
|
||||
@K=function, @M=Task_A2G, @N=onafterRouteToTargets, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_A2G.lua, @C=7408,
|
||||
@K=function, @M=Task_Cargo, @N=onafterSelectAction, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=10439,
|
||||
@K=function, @M=Task_Cargo, @N=OnLeaveWaitingForCommand, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=13084,
|
||||
@K=function, @M=Task_Cargo, @N=onafterRouteToPickup, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=13860,
|
||||
@K=function, @M=Task_Cargo, @N=onafterArriveAtPickup, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=14479,
|
||||
@K=function, @M=Task_Cargo, @N=onafterRouteToDeploy, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=15020,
|
||||
@K=function, @M=Task_Cargo, @N=onafterArriveAtDeploy, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=15467,
|
||||
@K=function, @M=Task_Cargo, @N=onafterLand, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=15897,
|
||||
@K=function, @M=Task_Cargo, @N=onafterLanded, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=16856,
|
||||
@K=function, @M=Task_Cargo, @N=onafterPrepareBoarding, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=17622,
|
||||
@K=function, @M=Task_Cargo, @N=onafterBoard, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=18082,
|
||||
@K=function, @M=Task_Cargo, @N=onafterBoarded, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=19023,
|
||||
@K=function, @M=Task_Cargo, @N=onafterPrepareUnBoarding, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=19706,
|
||||
@K=function, @M=Task_Cargo, @N=onafterUnBoard, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=20666,
|
||||
@K=function, @M=Task_Cargo, @N=onafterUnBoarded, @P=Fsm, @F=../../../MOOSE/Moose Development/Moose\Tasking\Task_CARGO.lua, @C=21541,
|
||||
@K=function, @M=Designate, @N=OnBeforeLaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12232,
|
||||
@K=function, @M=Designate, @N=OnAfterLaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12480,
|
||||
@K=function, @M=Designate, @N=LaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12701,
|
||||
@K=function, @M=Designate, @N=__LaseOn, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=12824,
|
||||
@K=function, @M=Designate, @N=OnBeforeLaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13114,
|
||||
@K=function, @M=Designate, @N=OnAfterLaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13364,
|
||||
@K=function, @M=Designate, @N=LaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13587,
|
||||
@K=function, @M=Designate, @N=__LaseOff, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13712,
|
||||
@K=function, @M=Designate, @N=OnBeforeSmoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=13944,
|
||||
@K=function, @M=Designate, @N=OnAfterSmoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=14190,
|
||||
@K=function, @M=Designate, @N=Smoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=14409,
|
||||
@K=function, @M=Designate, @N=__Smoke, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=14530,
|
||||
@K=function, @M=Designate, @N=OnBeforeStatus, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=15628,
|
||||
@K=function, @M=Designate, @N=OnAfterStatus, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=15876,
|
||||
@K=function, @M=Designate, @N=Status, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=16097,
|
||||
@K=function, @M=Designate, @N=__Status, @P=DESIGNATE , @F=../../../MOOSE/Moose Development/Moose\Functional\Designate.lua, @C=16220,
|
||||
|
1841
docs/Documentation/AI_A2A.html
Normal file
1841
docs/Documentation/AI_A2A.html
Normal file
File diff suppressed because it is too large
Load Diff
1712
docs/Documentation/AI_A2A_Cap.html
Normal file
1712
docs/Documentation/AI_A2A_Cap.html
Normal file
File diff suppressed because it is too large
Load Diff
3762
docs/Documentation/AI_A2A_Dispatcher.html
Normal file
3762
docs/Documentation/AI_A2A_Dispatcher.html
Normal file
File diff suppressed because it is too large
Load Diff
1566
docs/Documentation/AI_A2A_GCI.html
Normal file
1566
docs/Documentation/AI_A2A_GCI.html
Normal file
File diff suppressed because it is too large
Load Diff
1093
docs/Documentation/AI_A2A_Patrol.html
Normal file
1093
docs/Documentation/AI_A2A_Patrol.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li>AI_Bai</li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -131,22 +139,7 @@
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>API CHANGE HISTORY</strong></h1>
|
||||
|
||||
<p>The underlying change log documents the API changes. Please read this carefully. The following notation is used:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Added</strong> parts are expressed in bold type face.</li>
|
||||
<li><em>Removed</em> parts are expressed in italic type face.</li>
|
||||
</ul>
|
||||
|
||||
<p>Hereby the change log:</p>
|
||||
|
||||
<p>2017-01-15: Initial class and API.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>AUTHORS and CONTRIBUTIONS</strong></h1>
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
@@ -154,11 +147,7 @@
|
||||
<li><strong><a href="http://forums.eagle.ru:8080/member.php?u=75036">Gunterlund</a></strong>: Test case revision.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Authors:</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong>FlightControl</strong>: Concept, Design & Programming.</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li>AI_Balancer</li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,7 +105,7 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>AI_Balancer</code></h1>
|
||||
|
||||
<p>Single-Player:<strong>No</strong> / Multi-Player:<strong>Yes</strong> / AI:<strong>Yes</strong> / Human:<strong>No</strong> / Types:<strong>All</strong> -- <strong>AI Balancing will replace in multi player missions
|
||||
<p><strong>AI</strong> -- <strong>AI Balancing will replace in multi player missions
|
||||
non-occupied human slots with AI groups, in order to provide an engaging simulation environment,
|
||||
even when there are hardly any players in the mission.</strong></p>
|
||||
|
||||
@@ -121,40 +129,17 @@ even when there are hardly any players in the mission.</strong></p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>API CHANGE HISTORY</strong></h1>
|
||||
|
||||
<p>The underlying change log documents the API changes.</p>
|
||||
|
||||
|
||||
<p>Please read this carefully. The following notation is used:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Added</strong> parts are expressed in bold type face.</li>
|
||||
<li><em>Removed</em> parts are expressed in italic type face.</li>
|
||||
</ul>
|
||||
|
||||
<p>Hereby the change log:</p>
|
||||
|
||||
<p>2017-01-17: There is still a problem with AI being destroyed, but not respawned. Need to check further upon that.</p>
|
||||
|
||||
<p>2017-01-08: AI_BALANCER:<strong>InitSpawnInterval( Earliest, Latest )</strong> added.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>AUTHORS and CONTRIBUTIONS</strong></h1>
|
||||
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong><a href="https://forums.eagle.ru/member.php?u=112075">Dutch_Baron</a></strong>: Working together with James has resulted in the creation of the AI_BALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)</li>
|
||||
<li><strong>SNAFU</strong>: Had a couple of mails with the guys to validate, if the same concept in the GCI/CAP script could be reworked within MOOSE. None of the script code has been used however within the new AI_BALANCER moose class.</li>
|
||||
<li><strong><a href="https://forums.eagle.ru/member.php?u=112075">Dutch_Baron</a></strong>: Working together with James has resulted in the creation of the AI_BALANCER class.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Authors:</h3>
|
||||
|
||||
<p>James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)</p>
|
||||
|
||||
<ul>
|
||||
<li>FlightControl: Framework Design & Programming and Documentation.</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li>AI_Cap</li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,7 +105,7 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>AI_Cap</code></h1>
|
||||
|
||||
<p><strong>AI</strong> - <strong>Execute Combat Air Patrol (CAP).</strong></p>
|
||||
<p><strong>AI</strong> -- <strong>Execute Combat Air Patrol (CAP).</strong></p>
|
||||
|
||||
<p><img src="..\Presentations\AI_CAP\Dia1.JPG" alt="Banner Image"/></p>
|
||||
|
||||
@@ -131,22 +139,7 @@
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>API CHANGE HISTORY</strong></h1>
|
||||
|
||||
<p>The underlying change log documents the API changes. Please read this carefully. The following notation is used:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Added</strong> parts are expressed in bold type face.</li>
|
||||
<li><em>Removed</em> parts are expressed in italic type face.</li>
|
||||
</ul>
|
||||
|
||||
<p>Hereby the change log:</p>
|
||||
|
||||
<p>2017-01-15: Initial class and API.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>AUTHORS and CONTRIBUTIONS</strong></h1>
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
@@ -158,11 +151,7 @@
|
||||
<li>**<a href="https://forums.eagle.ru/member.php?u=125166">Delta99</a>: Testing. </li>
|
||||
</ul>
|
||||
|
||||
<h3>Authors:</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong>FlightControl</strong>: Concept, Design & Programming.</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -131,7 +139,8 @@
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>AUTHORS and CONTRIBUTIONS</strong></h1>
|
||||
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
@@ -141,11 +150,7 @@
|
||||
<li><strong><a href="http://forums.eagle.ru:8080/member.php?u=75036">Gunterlund</a></strong>: Test case revision.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Authors:</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong>FlightControl</strong>: Concept, Design & Programming.</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
@@ -488,13 +493,13 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
|
||||
<p><img src="..\Presentations\AI_CAS\Dia12.JPG" alt="Engage Event"/></p>
|
||||
|
||||
<h1>1. AI<em>CAS</em>ZONE constructor</h1>
|
||||
<h2>AI<em>CAS</em>ZONE constructor</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(AI_CAS_ZONE).New">AI<em>CAS</em>ZONE.New</a>(): Creates a new AI<em>CAS</em>ZONE object.</li>
|
||||
</ul>
|
||||
|
||||
<h2>2. AI<em>CAS</em>ZONE is a FSM</h2>
|
||||
<h2>AI<em>CAS</em>ZONE is a FSM</h2>
|
||||
|
||||
<p><img src="..\Presentations\AI_CAS\Dia2.JPG" alt="Process"/></p>
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,7 +105,7 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>AI_Formation</code></h1>
|
||||
|
||||
<p><strong>AI</strong> -- (R2.1) Build large <strong>formations</strong> of AI <a href="Group.html">Group</a>s flying together.</p>
|
||||
<p><strong>AI</strong> -- Build large <strong>formations</strong> of AI <a href="Group.html">Group</a>s flying together.</p>
|
||||
|
||||
|
||||
|
||||
@@ -157,16 +165,12 @@ The purpose of the class is to:</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>AUTHORS and CONTRIBUTIONS</strong></h1>
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<h3>Authors:</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong>FlightControl</strong>: Concept, Design & Programming.
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
<p> </p>
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -131,38 +139,7 @@
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>OPEN ISSUES</strong></h1>
|
||||
|
||||
<p>2017-01-17: When Spawned AI is located at an airbase, it will be routed first back to the airbase after take-off.</p>
|
||||
|
||||
<p>2016-01-17:
|
||||
-- Fixed problem with AI returning to base too early and unexpected.
|
||||
-- ReSpawning of AI will reset the AI_PATROL and derived classes.
|
||||
-- Checked the correct workings of SCHEDULER, and it DOES work correctly.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>API CHANGE HISTORY</strong></h1>
|
||||
|
||||
<p>The underlying change log documents the API changes. Please read this carefully. The following notation is used:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Added</strong> parts are expressed in bold type face.</li>
|
||||
<li><em>Removed</em> parts are expressed in italic type face.</li>
|
||||
</ul>
|
||||
|
||||
<p>Hereby the change log:</p>
|
||||
|
||||
<p>2017-01-17: Rename of class: <strong>AI_PATROL_ZONE</strong> is the new name for the old <em>AI_PATROLZONE</em>.</p>
|
||||
|
||||
<p>2017-01-15: Complete revision. AI<em>PATROL</em>ZONE is the base class for other AI_PATROL like classes.</p>
|
||||
|
||||
<p>2016-09-01: Initial class and API.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>AUTHORS and CONTRIBUTIONS</strong></h1>
|
||||
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<ul>
|
||||
@@ -170,11 +147,7 @@
|
||||
<li><strong><a href="https://forums.eagle.ru/member.php?u=62835">Pikey</a></strong>: Testing and API concept review.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Authors:</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong>FlightControl</strong>: Design & Programming.</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -215,6 +223,18 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).New">ACT_ACCOUNT_DEADS:New(TargetSetUnit, TaskName)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new DESTROY process.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).OnEventHit">ACT_ACCOUNT_DEADS:OnEventHit(EventData)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).PlayerHits">ACT_ACCOUNT_DEADS.PlayerHits</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -230,13 +250,19 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).onafterEvent">ACT_ACCOUNT_DEADS:onafterEvent(ProcessUnit, Event, From, To, Task)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).onafterEvent">ACT_ACCOUNT_DEADS:onafterEvent(ProcessClient, Task, From, Event, To, EventData)</a></td>
|
||||
<td class="summary">
|
||||
<p>StateMachine callback function</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).onenterAccount">ACT_ACCOUNT_DEADS:onenterAccount(ProcessUnit, Event, From, To, Task, EventData)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).onenterAccountForOther">ACT_ACCOUNT_DEADS:onenterAccountForOther(ProcessClient, Task, From, Event, To, EventData)</a></td>
|
||||
<td class="summary">
|
||||
<p>StateMachine callback function</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).onenterAccountForPlayer">ACT_ACCOUNT_DEADS:onenterAccountForPlayer(ProcessClient, Task, From, Event, To, EventData)</a></td>
|
||||
<td class="summary">
|
||||
<p>StateMachine callback function</p>
|
||||
</td>
|
||||
@@ -245,6 +271,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).onenterReport">ACT_ACCOUNT_DEADS:onenterReport(ProcessUnit, Event, From, To, Task)</a></td>
|
||||
<td class="summary">
|
||||
<p>StateMachine callback function</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).onfuncEventCrash">ACT_ACCOUNT_DEADS:onfuncEventCrash(EventData)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -666,6 +698,40 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS).OnEventHit" >
|
||||
<strong>ACT_ACCOUNT_DEADS:OnEventHit(EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS).PlayerHits" >
|
||||
<strong>ACT_ACCOUNT_DEADS.PlayerHits</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -700,7 +766,7 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS).onafterEvent" >
|
||||
<strong>ACT_ACCOUNT_DEADS:onafterEvent(ProcessUnit, Event, From, To, Task)</strong>
|
||||
<strong>ACT_ACCOUNT_DEADS:onafterEvent(ProcessClient, Task, From, Event, To, EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@@ -711,12 +777,12 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Wrapper.Controllable.html##(CONTROLLABLE)">Wrapper.Controllable#CONTROLLABLE</a> ProcessUnit </em></code>: </p>
|
||||
<p><code><em><a href="Wrapper.Client.html##(CLIENT)">Wrapper.Client#CLIENT</a> ProcessClient </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
<p><code><em><a href="Tasking.Task.html##(TASK)">Tasking.Task#TASK</a> Task </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
@@ -726,12 +792,17 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string To </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Task </em></code>: </p>
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
@@ -740,8 +811,8 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS).onenterAccount" >
|
||||
<strong>ACT_ACCOUNT_DEADS:onenterAccount(ProcessUnit, Event, From, To, Task, EventData)</strong>
|
||||
<a id="#(ACT_ACCOUNT_DEADS).onenterAccountForOther" >
|
||||
<strong>ACT_ACCOUNT_DEADS:onenterAccountForOther(ProcessClient, Task, From, Event, To, EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@@ -752,12 +823,12 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Wrapper.Controllable.html##(CONTROLLABLE)">Wrapper.Controllable#CONTROLLABLE</a> ProcessUnit </em></code>: </p>
|
||||
<p><code><em><a href="Wrapper.Client.html##(CLIENT)">Wrapper.Client#CLIENT</a> ProcessClient </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
<p><code><em><a href="Tasking.Task.html##(TASK)">Tasking.Task#TASK</a> Task </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
@@ -767,17 +838,63 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string To </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Task </em></code>: </p>
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS).onenterAccountForPlayer" >
|
||||
<strong>ACT_ACCOUNT_DEADS:onenterAccountForPlayer(ProcessClient, Task, From, Event, To, EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>StateMachine callback function</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Wrapper.Client.html##(CLIENT)">Wrapper.Client#CLIENT</a> ProcessClient </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> EventData </em></code>: </p>
|
||||
<p><code><em><a href="Tasking.Task.html##(TASK)">Tasking.Task#TASK</a> Task </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string From </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string To </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
@@ -827,6 +944,27 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS).onfuncEventCrash" >
|
||||
<strong>ACT_ACCOUNT_DEADS:onfuncEventCrash(EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Event.html##(EVENTDATA)">Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS).onfuncEventDead" >
|
||||
<strong>ACT_ACCOUNT_DEADS:onfuncEventDead(EventData)</strong>
|
||||
</a>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,49 +105,17 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>Airbase</code></h1>
|
||||
|
||||
<p>This module contains the AIRBASE classes.</p>
|
||||
<p><strong>Wrapper</strong> -- AIRBASE is a wrapper class to handle the DCS Airbase objects.</p>
|
||||
|
||||
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1>1) <a href="Airbase.html##(AIRBASE)">Airbase#AIRBASE</a> class, extends <a href="Positionable.html##(POSITIONABLE)">Positionable#POSITIONABLE</a></h1>
|
||||
<p>The <a href="AIRBASE.html">AIRBASE</a> class is a wrapper class to handle the DCS Airbase objects:</p>
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<ul>
|
||||
<li>Support all DCS Airbase APIs.</li>
|
||||
<li>Enhance with Airbase specific APIs not in the DCS Airbase API set.</li>
|
||||
</ul>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
|
||||
<h2>1.1) AIRBASE reference methods</h2>
|
||||
<p>For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _<a href="DATABASE.html">DATABASE</a> object.
|
||||
This is done at the beginning of the mission (when the mission starts).</p>
|
||||
|
||||
<p>The AIRBASE class <strong>does not contain a :New()</strong> method, rather it provides <strong>:Find()</strong> methods to retrieve the object reference
|
||||
using the DCS Airbase or the DCS AirbaseName.</p>
|
||||
|
||||
<p>Another thing to know is that AIRBASE objects do not "contain" the DCS Airbase object.
|
||||
The AIRBASE methods will reference the DCS Airbase object by name when it is needed during API execution.
|
||||
If the DCS Airbase object does not exist or is nil, the AIRBASE methods will return nil and log an exception in the DCS.log file.</p>
|
||||
|
||||
<p>The AIRBASE class provides the following functions to retrieve quickly the relevant AIRBASE instance:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(AIRBASE).Find">AIRBASE.Find</a>(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase object.</li>
|
||||
<li><a href="##(AIRBASE).FindByName">AIRBASE.FindByName</a>(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase name.</li>
|
||||
</ul>
|
||||
|
||||
<p>IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil).</p>
|
||||
|
||||
<h2>1.2) DCS AIRBASE APIs</h2>
|
||||
<p>The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method.
|
||||
To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call,
|
||||
the first letter of the method is also capitalized. So, by example, the DCS Airbase method <a href="DCSWrapper.Airbase.html##(Airbase).getName">DCSWrapper.Airbase#Airbase.getName</a>()
|
||||
is implemented in the AIRBASE class as <a href="##(AIRBASE).GetName">AIRBASE.GetName</a>().</p>
|
||||
|
||||
<h2>More functions will be added</h2>
|
||||
<p>During the MOOSE development, more functions will be added. </p>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
@@ -147,20 +123,20 @@ is implemented in the AIRBASE class as <a href="##(AIRBASE).GetName">AIRBASE.Get
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#AIRBASE">AIRBASE</a></td>
|
||||
<td class="summary">
|
||||
<h1>AIRBASE class, extends <a href="Positionable.html##(POSITIONABLE)">Positionable#POSITIONABLE</a></h1>
|
||||
|
||||
<p>AIRBASE is a wrapper class to handle the DCS Airbase objects:</p>
|
||||
|
||||
<ul>
|
||||
<li>Support all DCS Airbase APIs.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(AIRBASE)">Type <code>AIRBASE</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AIRBASE).CategoryName">AIRBASE.CategoryName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AIRBASE).ClassName">AIRBASE.ClassName</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AIRBASE).Caucasus">AIRBASE.Caucasus</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
@@ -181,6 +157,24 @@ is implemented in the AIRBASE class as <a href="##(AIRBASE).GetName">AIRBASE.Get
|
||||
<td class="name" nowrap="nowrap"><a href="##(AIRBASE).GetDCSObject">AIRBASE:GetDCSObject()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AIRBASE).GetZone">AIRBASE:GetZone()</a></td>
|
||||
<td class="summary">
|
||||
<p>Get the airbase zone.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AIRBASE).Nevada">AIRBASE.Nevada</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AIRBASE).Normandy">AIRBASE.Normandy</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -202,6 +196,46 @@ is implemented in the AIRBASE class as <a href="##(AIRBASE).GetName">AIRBASE.Get
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<h1>AIRBASE class, extends <a href="Positionable.html##(POSITIONABLE)">Positionable#POSITIONABLE</a></h1>
|
||||
|
||||
<p>AIRBASE is a wrapper class to handle the DCS Airbase objects:</p>
|
||||
|
||||
<ul>
|
||||
<li>Support all DCS Airbase APIs.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul>
|
||||
<li>Enhance with Airbase specific APIs not in the DCS Airbase API set.</li>
|
||||
</ul>
|
||||
|
||||
<h2>AIRBASE reference methods</h2>
|
||||
|
||||
<p>For each DCS Airbase object alive within a running mission, a AIRBASE wrapper object (instance) will be created within the _<a href="DATABASE.html">DATABASE</a> object.
|
||||
This is done at the beginning of the mission (when the mission starts).</p>
|
||||
|
||||
<p>The AIRBASE class <strong>does not contain a :New()</strong> method, rather it provides <strong>:Find()</strong> methods to retrieve the object reference
|
||||
using the DCS Airbase or the DCS AirbaseName.</p>
|
||||
|
||||
<p>Another thing to know is that AIRBASE objects do not "contain" the DCS Airbase object.
|
||||
The AIRBASE methods will reference the DCS Airbase object by name when it is needed during API execution.
|
||||
If the DCS Airbase object does not exist or is nil, the AIRBASE methods will return nil and log an exception in the DCS.log file.</p>
|
||||
|
||||
<p>The AIRBASE class provides the following functions to retrieve quickly the relevant AIRBASE instance:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(AIRBASE).Find">AIRBASE.Find</a>(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase object.</li>
|
||||
<li><a href="##(AIRBASE).FindByName">AIRBASE.FindByName</a>(): Find a AIRBASE instance from the _DATABASE object using a DCS Airbase name.</li>
|
||||
</ul>
|
||||
|
||||
<p>IMPORTANT: ONE SHOULD NEVER SANATIZE these AIRBASE OBJECT REFERENCES! (make the AIRBASE object references nil).</p>
|
||||
|
||||
<h2>DCS Airbase APIs</h2>
|
||||
|
||||
<p>The DCS Airbase APIs are used extensively within MOOSE. The AIRBASE class has for each DCS Airbase API a corresponding method.
|
||||
To be able to distinguish easily in your code the difference between a AIRBASE API call and a DCS Airbase API call,
|
||||
the first letter of the method is also capitalized. So, by example, the DCS Airbase method <a href="DCSWrapper.Airbase.html##(Airbase).getName">DCSWrapper.Airbase#Airbase.getName</a>()
|
||||
is implemented in the AIRBASE class as <a href="##(AIRBASE).GetName">AIRBASE.GetName</a>().</p>
|
||||
|
||||
|
||||
</dd>
|
||||
@@ -209,30 +243,13 @@ is implemented in the AIRBASE class as <a href="##(AIRBASE).GetName">AIRBASE.Get
|
||||
<h2><a id="#(Airbase)" >Type <code>Airbase</code></a></h2>
|
||||
|
||||
<h2><a id="#(AIRBASE)" >Type <code>AIRBASE</code></a></h2>
|
||||
|
||||
<p>The AIRBASE class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(AIRBASE).CategoryName" >
|
||||
<strong>AIRBASE.CategoryName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(AIRBASE).ClassName" >
|
||||
<strong>AIRBASE.ClassName</strong>
|
||||
<a id="#(AIRBASE).Caucasus" >
|
||||
<strong>AIRBASE.Caucasus</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@@ -306,6 +323,52 @@ self</p>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AIRBASE).GetZone" >
|
||||
<strong>AIRBASE:GetZone()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Get the airbase zone.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="Core.Zone.html##(ZONE_RADIUS)">Core.Zone#ZONE_RADIUS</a>:</em>
|
||||
The zone radius of the airbase.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(AIRBASE).Nevada" >
|
||||
<strong>AIRBASE.Nevada</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(AIRBASE).Normandy" >
|
||||
<strong>AIRBASE.Normandy</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,7 +105,7 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>AirbasePolice</code></h1>
|
||||
|
||||
<p>This module contains the AIRBASEPOLICE classes.</p>
|
||||
<p><strong>Functional</strong> -- This module monitors airbases traffic.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,7 +105,7 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>Base</code></h1>
|
||||
|
||||
<p><strong>Core</strong> - BASE forms <strong>the basis of the MOOSE framework</strong>.</p>
|
||||
<p><strong>Core</strong> -- BASE forms <strong>the basis of the MOOSE framework</strong>.</p>
|
||||
|
||||
|
||||
<p>Each class within the MOOSE framework derives from BASE.</p>
|
||||
@@ -106,39 +114,10 @@
|
||||
|
||||
<hr/>
|
||||
|
||||
<p>The <a href="##(BASE)">#BASE</a> class is the core root class from where every other class in moose is derived.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>API CHANGE HISTORY</strong></h1>
|
||||
|
||||
<p>The underlying change log documents the API changes. Please read this carefully. The following notation is used:</p>
|
||||
|
||||
<ul>
|
||||
<li><strong>Added</strong> parts are expressed in bold type face.</li>
|
||||
<li><em>Removed</em> parts are expressed in italic type face.</li>
|
||||
</ul>
|
||||
|
||||
<p>YYYY-MM-DD: CLASS:<strong>NewFunction</strong>( Params ) replaces CLASS:<em>OldFunction</em>( Params )
|
||||
YYYY-MM-DD: CLASS:<strong>NewFunction( Params )</strong> added</p>
|
||||
|
||||
<p>Hereby the change log:</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1><strong>AUTHORS and CONTRIBUTIONS</strong></h1>
|
||||
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<ul>
|
||||
<li>None.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Authors:</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong>FlightControl</strong>: Design & Programming</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
@@ -263,7 +242,7 @@ YYYY-MM-DD: CLASS:<strong>NewFunction( Params )</strong> added</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).GetState">BASE:GetState(Object, Key, Value)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).GetState">BASE:GetState(Object, Key)</a></td>
|
||||
<td class="summary">
|
||||
<p>Get a Value given a Key from the Object.</p>
|
||||
</td>
|
||||
@@ -493,30 +472,24 @@ When Moose is loaded statically, (as one file), tracing is switched off by defau
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).UnHandleEvent">BASE:UnHandleEvent(Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>UnSubscribe to a DCS event.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE)._Destructor">BASE:_Destructor()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE)._F">BASE:_F(Arguments, DebugInfoCurrentParam, DebugInfoFromParam)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function call.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE)._SetDestructor">BASE:_SetDestructor()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE)._T">BASE:_T(Arguments, DebugInfoCurrentParam, DebugInfoFromParam)</a></td>
|
||||
<td class="summary">
|
||||
<p>Trace a function logic.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(BASE).__">BASE.__</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1152,7 +1125,7 @@ is the Child class from which the Parent class needs to be retrieved.</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE).GetState" >
|
||||
<strong>BASE:GetState(Object, Key, Value)</strong>
|
||||
<strong>BASE:GetState(Object, Key)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@@ -1175,12 +1148,6 @@ The object that holds the Value set by the Key.</p>
|
||||
<p><code><em> Key </em></code>:
|
||||
The key that is used to retrieve the value. Note that the key can be a #string, but it can also be any other type!</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Value </em></code>:
|
||||
The value to is stored in the Object.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
@@ -2161,19 +2128,6 @@ BASE:TraceOnOff( false )</code></pre>
|
||||
<p><em><a href="##(BASE)">#BASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE)._Destructor" >
|
||||
<strong>BASE:_Destructor()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -2214,22 +2168,6 @@ A #table or any field.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE)._SetDestructor" >
|
||||
<strong>BASE:_SetDestructor()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> THIS IS WHY WE NEED LUA 5.2 ...</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(BASE)._T" >
|
||||
<strong>BASE:_T(Arguments, DebugInfoCurrentParam, DebugInfoFromParam)</strong>
|
||||
</a>
|
||||
@@ -2257,6 +2195,20 @@ A #table or any field.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(BASE.__)">#BASE.__</a></em>
|
||||
<a id="#(BASE).__" >
|
||||
<strong>BASE.__</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -2287,6 +2239,8 @@ A #table or any field.</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(BASE.__)" >Type <code>BASE.__</code></a></h2>
|
||||
|
||||
<h2><a id="#(FORMATION)" >Type <code>FORMATION</code></a></h2>
|
||||
|
||||
<p>The Formation Class</p>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,7 +105,7 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>Cargo</code></h1>
|
||||
|
||||
<p><strong>(R2.1) Core</strong> -- Management of CARGO logistics, that can be transported from and to transportation carriers.</p>
|
||||
<p><strong>Core</strong> -- Management of CARGO logistics, that can be transported from and to transportation carriers.</p>
|
||||
|
||||
|
||||
|
||||
@@ -112,13 +120,15 @@
|
||||
<li>CARGO_GROUP, represented by a <a href="Group.html">Group</a>. A CARGO_GROUP is reportable...</li>
|
||||
</ul>
|
||||
|
||||
<p>This module is still under construction, but is described above works already, and will keep working ...</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h1>Demo Missions</h1>
|
||||
|
||||
<h3><a href="">CARGO Demo Missions source code</a></h3>
|
||||
<h3><a href="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/CGO%20-%20Cargo">CARGO Demo Missions source code</a></h3>
|
||||
|
||||
<h3><a href="">CARGO Demo Missions, only for beta testers</a></h3>
|
||||
<h3><a href="https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/CGO%20-%20Cargo">CARGO Demo Missions, only for beta testers</a></h3>
|
||||
|
||||
<h3><a href="https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases">ALL Demo Missions pack of the last release</a></h3>
|
||||
|
||||
@@ -126,11 +136,14 @@
|
||||
|
||||
<h1>YouTube Channel</h1>
|
||||
|
||||
<h3><a href="">SPAWNSTATIC YouTube Channel</a></h3>
|
||||
<h3><a href="https://www.youtube.com/watch?v=tM00lTlkpYs&list=PL7ZUrU4zZUl2zUTuKrLW5RsO9zLMqUtbf">CARGO YouTube Channel</a></h3>
|
||||
|
||||
<hr/>
|
||||
|
||||
<p>This module is still under construction, but is described above works already, and will keep working ...</p>
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
@@ -214,6 +227,48 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).Containable">CARGO.Containable</a></td>
|
||||
<td class="summary">
|
||||
<p>This flag defines if the cargo can be contained within a DCS Unit.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).Deployed">CARGO.Deployed</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).Destroy">CARGO:Destroy()</a></td>
|
||||
<td class="summary">
|
||||
<p>Destroy the cargo.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).Flare">CARGO:Flare(FlareColor)</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a flare at the position of the CARGO.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).FlareGreen">CARGO:FlareGreen()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a green flare at the position of the CARGO.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).FlareRed">CARGO:FlareRed()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a red flare at the position of the CARGO.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).FlareWhite">CARGO:FlareWhite()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a white flare at the position of the CARGO.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).FlareYellow">CARGO:FlareYellow()</a></td>
|
||||
<td class="summary">
|
||||
<p>Signal a yellow flare at the position of the CARGO.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -250,6 +305,18 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).IsAlive">CARGO:IsAlive()</a></td>
|
||||
<td class="summary">
|
||||
<p>Check if cargo is alive.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).IsDeployed">CARGO:IsDeployed()</a></td>
|
||||
<td class="summary">
|
||||
<p>Is the cargo deployed</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).IsDestroyed">CARGO:IsDestroyed()</a></td>
|
||||
<td class="summary">
|
||||
<p>Check if cargo is destroyed.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -358,6 +425,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).Representable">CARGO.Representable</a></td>
|
||||
<td class="summary">
|
||||
<p>This flag defines if the cargo can be represented by a DCS Unit.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).SetDeployed">CARGO:SetDeployed(Deployed)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set the cargo as deployed</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -370,6 +443,42 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).Slingloadable">CARGO.Slingloadable</a></td>
|
||||
<td class="summary">
|
||||
<p>This flag defines if the cargo can be slingloaded.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).Smoke">CARGO:Smoke(SmokeColor, Range)</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the CARGO.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).SmokeBlue">CARGO:SmokeBlue()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the CARGO Blue.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).SmokeGreen">CARGO:SmokeGreen()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the CARGO Green.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).SmokeOrange">CARGO:SmokeOrange()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the CARGO Orange.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).SmokeRed">CARGO:SmokeRed()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the CARGO Red.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO).SmokeWhite">CARGO:SmokeWhite()</a></td>
|
||||
<td class="summary">
|
||||
<p>Smoke the CARGO White.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -434,6 +543,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).CargoCarrier">CARGO_GROUP.CargoCarrier</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).CargoGroup">CARGO_GROUP.CargoGroup</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -443,15 +558,27 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).CargoSet">CARGO_GROUP.CargoSet</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).GetCount">CARGO_GROUP:GetCount()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
<p>Get the amount of cargo units in the group.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).New">CARGO_GROUP:New(CargoGroup, Type, Name, ReportRadius, NearRadius)</a></td>
|
||||
<td class="summary">
|
||||
<p>CARGO_GROUP constructor.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).OnEventCargoDead">CARGO_GROUP:OnEventCargoDead(EventData)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).RespawnOnDestroyed">CARGO_GROUP:RespawnOnDestroyed(RespawnDestroyed)</a></td>
|
||||
<td class="summary">
|
||||
<p>Respawn the cargo when destroyed</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -470,6 +597,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).onenterBoarding">CARGO_GROUP:onenterBoarding(CargoCarrier, Event, From, To, NearRadius, ...)</a></td>
|
||||
<td class="summary">
|
||||
<p>Enter Boarding State.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_GROUP).onenterDestroyed">CARGO_GROUP:onenterDestroyed()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -574,6 +707,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_REPORTABLE).CargoObject">CARGO_REPORTABLE.CargoObject</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_REPORTABLE).CargoSet">CARGO_REPORTABLE.CargoSet</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -610,6 +749,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_REPORTABLE).ReportRadius">CARGO_REPORTABLE.ReportRadius</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CARGO_REPORTABLE).Respawn">CARGO_REPORTABLE:Respawn()</a></td>
|
||||
<td class="summary">
|
||||
<p>Respawn the cargo.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -928,7 +1073,7 @@ The radius when the cargo will board the Carrier (to avoid collision).</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="Wrapper.Controllable.html##(CONTROLLABLE)">Wrapper.Controllable#CONTROLLABLE</a></em>
|
||||
<em><a href="Wrapper.Client.html##(CLIENT)">Wrapper.Client#CLIENT</a></em>
|
||||
<a id="#(CARGO).CargoCarrier" >
|
||||
<strong>CARGO.CargoCarrier</strong>
|
||||
</a>
|
||||
@@ -979,6 +1124,106 @@ The radius when the cargo will board the Carrier (to avoid collision).</p>
|
||||
|
||||
<p>This flag defines if the cargo can be contained within a DCS Unit.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CARGO).Deployed" >
|
||||
<strong>CARGO.Deployed</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).Destroy" >
|
||||
<strong>CARGO:Destroy()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Destroy the cargo.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).Flare" >
|
||||
<strong>CARGO:Flare(FlareColor)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a flare at the position of the CARGO.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Utilities.Utils.html##(FLARECOLOR)">Utilities.Utils#FLARECOLOR</a> FlareColor </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).FlareGreen" >
|
||||
<strong>CARGO:FlareGreen()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a green flare at the position of the CARGO.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).FlareRed" >
|
||||
<strong>CARGO:FlareRed()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a red flare at the position of the CARGO.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).FlareWhite" >
|
||||
<strong>CARGO:FlareWhite()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a white flare at the position of the CARGO.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).FlareYellow" >
|
||||
<strong>CARGO:FlareYellow()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Signal a yellow flare at the position of the CARGO.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -1092,6 +1337,42 @@ true if unloaded</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).IsDeployed" >
|
||||
<strong>CARGO:IsDeployed()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Is the cargo deployed</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#boolean:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).IsDestroyed" >
|
||||
<strong>CARGO:IsDestroyed()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Check if cargo is destroyed.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#boolean:</em>
|
||||
true if destroyed</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).IsInZone" >
|
||||
<strong>CARGO:IsInZone(Zone)</strong>
|
||||
</a>
|
||||
@@ -1507,6 +1788,27 @@ The radius when the cargo will board the Carrier (to avoid collision).</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).SetDeployed" >
|
||||
<strong>CARGO:SetDeployed(Deployed)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set the cargo as deployed</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> Deployed </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).SetWeight" >
|
||||
<strong>CARGO:SetWeight(Weight)</strong>
|
||||
</a>
|
||||
@@ -1548,6 +1850,97 @@ The weight in kg.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).Smoke" >
|
||||
<strong>CARGO:Smoke(SmokeColor, Range)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the CARGO.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> SmokeColor </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Range </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).SmokeBlue" >
|
||||
<strong>CARGO:SmokeBlue()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the CARGO Blue.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).SmokeGreen" >
|
||||
<strong>CARGO:SmokeGreen()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the CARGO Green.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).SmokeOrange" >
|
||||
<strong>CARGO:SmokeOrange()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the CARGO Orange.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).SmokeRed" >
|
||||
<strong>CARGO:SmokeRed()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the CARGO Red.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).SmokeWhite" >
|
||||
<strong>CARGO:SmokeWhite()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Smoke the CARGO White.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO).Spawn" >
|
||||
<strong>CARGO:Spawn(PointVec2)</strong>
|
||||
</a>
|
||||
@@ -1802,6 +2195,23 @@ The amount of seconds to delay the action.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p>self.CargoObject:Destroy()</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CARGO_GROUP).CargoGroup" >
|
||||
<strong>CARGO_GROUP.CargoGroup</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -1821,13 +2231,17 @@ The amount of seconds to delay the action.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CARGO_GROUP).CargoSet" >
|
||||
<strong>CARGO_GROUP.CargoSet</strong>
|
||||
<a id="#(CARGO_GROUP).GetCount" >
|
||||
<strong>CARGO_GROUP:GetCount()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Get the amount of cargo units in the group.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(CARGO_GROUP)">#CARGO_GROUP</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
@@ -1883,6 +2297,48 @@ The amount of seconds to delay the action.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO_GROUP).OnEventCargoDead" >
|
||||
<strong>CARGO_GROUP:OnEventCargoDead(EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO_GROUP).RespawnOnDestroyed" >
|
||||
<strong>CARGO_GROUP:RespawnOnDestroyed(RespawnDestroyed)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Respawn the cargo when destroyed</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#boolean RespawnDestroyed </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO_GROUP).onafterBoarding" >
|
||||
<strong>CARGO_GROUP:onafterBoarding(CargoCarrier, Event, From, To, NearRadius, ...)</strong>
|
||||
</a>
|
||||
@@ -2016,6 +2472,19 @@ The amount of seconds to delay the action.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO_GROUP).onenterDestroyed" >
|
||||
<strong>CARGO_GROUP:onenterDestroyed()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -2654,6 +3123,20 @@ The UNIT carrying the package.</p>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="Core.Set.html##(SET_CARGO)">Core.Set#SET_CARGO</a></em>
|
||||
<a id="#(CARGO_REPORTABLE).CargoSet" >
|
||||
<strong>CARGO_REPORTABLE.CargoSet</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -2810,6 +3293,19 @@ The range till cargo will board.</p>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CARGO_REPORTABLE).Respawn" >
|
||||
<strong>CARGO_REPORTABLE:Respawn()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Respawn the cargo.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
@@ -3397,8 +3893,6 @@ Point#POINT_VEC2</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(COMMANDCENTER)" >Type <code>COMMANDCENTER</code></a></h2>
|
||||
|
||||
<h2><a id="#(sring)" >Type <code>sring</code></a></h2>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,116 +105,72 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>CleanUp</code></h1>
|
||||
|
||||
<p>The CLEANUP class keeps an area clean of crashing or colliding airplanes.</p>
|
||||
<p><strong>Functional</strong> -- The CLEANUP_AIRBASE class keeps an area clean of crashing or colliding airplanes.</p>
|
||||
|
||||
|
||||
<p>It also prevents airplanes from firing within this area.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CLEANUP">CLEANUP</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="#CLEANUP_AIRBASE">CLEANUP_AIRBASE</a></td>
|
||||
<td class="summary">
|
||||
<h1>CLEANUP_AIRBASE, extends <a href="Base.html##(BASE)">Base#BASE</a></h1>
|
||||
|
||||
<p><img src="..\Presentations\CLEANUP_AIRBASE\Dia1.JPG" alt="Banner Image"/></p>
|
||||
|
||||
<p>The CLEANUP_AIRBASE class keeps airbases clean, and tries to guarantee continuous airbase operations, even under combat.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(CLEANUP)">Type <code>CLEANUP</code></a></h2>
|
||||
<h2><a id="#(CLEANUP_AIRBASE)">Type <code>CLEANUP_AIRBASE</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP).ClassName">CLEANUP.ClassName</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP_AIRBASE).AddAirbase">CLEANUP_AIRBASE:AddAirbase(AirbaseName)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
<p>Adds an airbase to the airbase validation list.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP).CleanUpList">CLEANUP.CleanUpList</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP).CleanUpScheduler">CLEANUP.CleanUpScheduler</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP).New">CLEANUP:New(ZoneNames, TimeInterval)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP_AIRBASE).New">CLEANUP_AIRBASE:New(<, AirbaseNames)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates the main object which is handling the cleaning of the debris within the given Zone Names.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP).TimeInterval">CLEANUP.TimeInterval</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP_AIRBASE).RemoveAirbase">CLEANUP_AIRBASE:RemoveAirbase(AirbaseName)</a></td>
|
||||
<td class="summary">
|
||||
<p>Removes an airbase from the airbase validation list.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP_AIRBASE).SetCleanMissiles">CLEANUP_AIRBASE:SetCleanMissiles(CleanMissiles)</a></td>
|
||||
<td class="summary">
|
||||
<p>Enables or disables the cleaning of missiles within the airbase zones.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP_AIRBASE).__">CLEANUP_AIRBASE.__</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP).ZoneNames">CLEANUP.ZoneNames</a></td>
|
||||
<td class="summary">
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<h2><a id="#(CLEANUP_AIRBASE.__)">Type <code>CLEANUP_AIRBASE.__</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._AddForCleanUp">CLEANUP:_AddForCleanUp(CleanUpUnit, CleanUpUnitName)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP_AIRBASE.__).<">CLEANUP_AIRBASE.__.<</a></td>
|
||||
<td class="summary">
|
||||
<p>Add the <a href="DCSWrapper.Unit.html##(Unit)">DCSWrapper.Unit#Unit</a> to the CleanUpList for CleanUp.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._CleanUpScheduler">CLEANUP:_CleanUpScheduler()</a></td>
|
||||
<td class="summary">
|
||||
<p>At the defined time interval, CleanUp the Groups within the CleanUpList.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._DestroyGroup">CLEANUP:_DestroyGroup(GroupObject, CleanUpGroupName)</a></td>
|
||||
<td class="summary">
|
||||
<p>Destroys a group from the simulator, but checks first if it is still existing!</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._DestroyMissile">CLEANUP:_DestroyMissile(MissileObject)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._DestroyUnit">CLEANUP:_DestroyUnit(CleanUpUnit, CleanUpUnitName)</a></td>
|
||||
<td class="summary">
|
||||
<p>Destroys a <a href="DCSWrapper.Unit.html##(Unit)">DCSWrapper.Unit#Unit</a> from the simulator, but checks first if it is still existing!</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._EventAddForCleanUp">CLEANUP:_EventAddForCleanUp(event, Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>Detects if the Unit has an S<em>EVENT</em>ENGINE<em>SHUTDOWN or an S</em>EVENT_HIT within the given ZoneNames.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._EventCrash">CLEANUP:_EventCrash(event, Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>Detects if a crash event occurs.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._EventHitCleanUp">CLEANUP:_EventHitCleanUp(event, Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>Detects if the Unit has an S<em>EVENT</em>HIT within the given ZoneNames.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._EventShot">CLEANUP:_EventShot(event, Event)</a></td>
|
||||
<td class="summary">
|
||||
<p>Detects if a unit shoots a missile.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLEANUP)._OnEventBirth">CLEANUP:_OnEventBirth(EventData)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
<p>string,Wrapper.Airbase#AIRBASE> Airbases Map of Airbases.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -215,34 +179,100 @@
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em><a href="##(CLEANUP)">#CLEANUP</a></em>
|
||||
<a id="CLEANUP" >
|
||||
<strong>CLEANUP</strong>
|
||||
<em><a href="##(CLEANUP_AIRBASE)">#CLEANUP_AIRBASE</a></em>
|
||||
<a id="CLEANUP_AIRBASE" >
|
||||
<strong>CLEANUP_AIRBASE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<h1>CLEANUP_AIRBASE, extends <a href="Base.html##(BASE)">Base#BASE</a></h1>
|
||||
|
||||
<p><img src="..\Presentations\CLEANUP_AIRBASE\Dia1.JPG" alt="Banner Image"/></p>
|
||||
|
||||
<p>The CLEANUP_AIRBASE class keeps airbases clean, and tries to guarantee continuous airbase operations, even under combat.</p>
|
||||
|
||||
|
||||
<p>Specific airbases need to be provided that need to be guarded. Each airbase registered, will be guarded within a zone of 8 km around the airbase.
|
||||
Any unit that fires a missile, or shoots within the zone of an airbase, will be monitored by CLEANUP_AIRBASE.
|
||||
Within the 8km zone, units cannot fire any missile, which prevents the airbase runway to receive missile or bomb hits.
|
||||
Any airborne or ground unit that is on the runway below 30 meters (default value) will be automatically removed if it is damaged.</p>
|
||||
|
||||
<p>This is not a full 100% secure implementation. It is still possible that CLEANUP_AIRBASE cannot prevent (in-time) to keep the airbase clean.
|
||||
The following situations may happen that will still stop the runway of an airbase:</p>
|
||||
|
||||
<ul>
|
||||
<li>A damaged unit is not removed on time when above the runway, and crashes on the runway.</li>
|
||||
<li>A bomb or missile is still able to dropped on the runway.</li>
|
||||
<li>Units collide on the airbase, and could not be removed on time.</li>
|
||||
</ul>
|
||||
|
||||
<p>When a unit is within the airbase zone and needs to be monitored,
|
||||
its status will be checked every 0.25 seconds! This is required to ensure that the airbase is kept clean.
|
||||
But as a result, there is more CPU overload.</p>
|
||||
|
||||
<p>So as an advise, I suggest you use the CLEANUP_AIRBASE class with care:</p>
|
||||
|
||||
<ul>
|
||||
<li>Only monitor airbases that really need to be monitored!</li>
|
||||
<li>Try not to monitor airbases that are likely to be invaded by enemy troops.
|
||||
For these airbases, there is little use to keep them clean, as they will be invaded anyway...</li>
|
||||
</ul>
|
||||
|
||||
<p>By following the above guidelines, you can add airbase cleanup with acceptable CPU overhead.</p>
|
||||
|
||||
<h2>1. CLEANUP_AIRBASE Constructor</h2>
|
||||
|
||||
<p>Creates the main object which is preventing the airbase to get polluted with debris on the runway, which halts the airbase.</p>
|
||||
|
||||
<pre><code> -- Clean these Zones.
|
||||
CleanUpAirports = CLEANUP_AIRBASE:New( { AIRBASE.Caucasus.Tbilisi, AIRBASE.Caucasus.Kutaisi )
|
||||
|
||||
-- or
|
||||
CleanUpTbilisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Tbilisi )
|
||||
CleanUpKutaisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Kutaisi )
|
||||
</code></pre>
|
||||
|
||||
<h2>2. Add or Remove airbases</h2>
|
||||
|
||||
<p>The method <a href="##(CLEANUP_AIRBASE).AddAirbase">CLEANUP_AIRBASE.AddAirbase</a>() to add an airbase to the cleanup validation process.
|
||||
The method <a href="##(CLEANUP_AIRBASE).RemoveAirbase">CLEANUP_AIRBASE.RemoveAirbase</a>() removes an airbase from the cleanup validation process.</p>
|
||||
|
||||
<h2>3. Clean missiles and bombs within the airbase zone.</h2>
|
||||
|
||||
<p>When missiles or bombs hit the runway, the airbase operations stop.
|
||||
Use the method <a href="##(CLEANUP_AIRBASE).SetCleanMissiles">CLEANUP_AIRBASE.SetCleanMissiles</a>() to control the cleaning of missiles, which will prevent airbases to stop.
|
||||
Note that this method will not allow anymore airbases to be attacked, so there is a trade-off here to do.</p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h2><a id="#(CleanUp)" >Type <code>CleanUp</code></a></h2>
|
||||
|
||||
<h2><a id="#(CLEANUP)" >Type <code>CLEANUP</code></a></h2>
|
||||
<h2><a id="#(CLEANUP_AIRBASE)" >Type <code>CLEANUP_AIRBASE</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP_AIRBASE).AddAirbase" >
|
||||
<strong>CLEANUP_AIRBASE:AddAirbase(AirbaseName)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Adds an airbase to the airbase validation list.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p>The CLEANUP class.</p>
|
||||
<p><code><em>#string AirbaseName </em></code>: </p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(CLEANUP).ClassName" >
|
||||
<strong>CLEANUP.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(CLEANUP_AIRBASE)">#CLEANUP_AIRBASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
@@ -250,36 +280,8 @@
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CLEANUP).CleanUpList" >
|
||||
<strong>CLEANUP.CleanUpList</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CLEANUP).CleanUpScheduler" >
|
||||
<strong>CLEANUP.CleanUpScheduler</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP).New" >
|
||||
<strong>CLEANUP:New(ZoneNames, TimeInterval)</strong>
|
||||
<a id="#(CLEANUP_AIRBASE).New" >
|
||||
<strong>CLEANUP_AIRBASE:New(<, AirbaseNames)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@@ -290,41 +292,87 @@
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#table ZoneNames </em></code>:
|
||||
Is a table of zone names where the debris should be cleaned. Also a single string can be passed with one zone name.</p>
|
||||
<p><code><em><a href="##(list)">#list</a> < </em></code>:
|
||||
string> AirbaseNames Is a table of airbase names where the debris should be cleaned. Also a single string can be passed with one airbase name.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number TimeInterval </em></code>:
|
||||
The interval in seconds when the clean activity takes place. The default is 300 seconds, thus every 5 minutes.</p>
|
||||
<p><code><em> AirbaseNames </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(CLEANUP)">#CLEANUP</a>:</em></p>
|
||||
<p><em><a href="##(CLEANUP_AIRBASE)">#CLEANUP_AIRBASE</a>:</em></p>
|
||||
|
||||
|
||||
<h3>Usage:</h3>
|
||||
<pre class="example"><code> -- Clean these Zones.
|
||||
CleanUpAirports = CLEANUP:New( { 'CLEAN Tbilisi', 'CLEAN Kutaisi' }, 150 )
|
||||
CleanUpAirports = CLEANUP_AIRBASE:New( { AIRBASE.Caucasus.Tbilisi, AIRBASE.Caucasus.Kutaisi )
|
||||
or
|
||||
CleanUpTbilisi = CLEANUP:New( 'CLEAN Tbilisi', 150 )
|
||||
CleanUpKutaisi = CLEANUP:New( 'CLEAN Kutaisi', 600 )</code></pre>
|
||||
CleanUpTbilisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Tbilisi )
|
||||
CleanUpKutaisi = CLEANUP_AIRBASE:New( AIRBASE.Caucasus.Kutaisi )</code></pre>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CLEANUP).TimeInterval" >
|
||||
<strong>CLEANUP.TimeInterval</strong>
|
||||
<a id="#(CLEANUP_AIRBASE).RemoveAirbase" >
|
||||
<strong>CLEANUP_AIRBASE:RemoveAirbase(AirbaseName)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Removes an airbase from the airbase validation list.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string AirbaseName </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(CLEANUP_AIRBASE)">#CLEANUP_AIRBASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP_AIRBASE).SetCleanMissiles" >
|
||||
<strong>CLEANUP_AIRBASE:SetCleanMissiles(CleanMissiles)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Enables or disables the cleaning of missiles within the airbase zones.</p>
|
||||
|
||||
|
||||
<p>Airbase operations stop when a missile or bomb is dropped at a runway.
|
||||
Note that when this method is used, the airbase operations won't stop if
|
||||
the missile or bomb was cleaned within the airbase zone, which is 8km from the center of the airbase.
|
||||
However, there is a trade-off to make. Attacks on airbases won't be possible anymore if this method is used.
|
||||
Note, one can also use the method <a href="##(CLEANUP_AIRBASE).RemoveAirbase">CLEANUP_AIRBASE.RemoveAirbase</a>() to remove the airbase from the control process as a whole,
|
||||
when an enemy unit is near. That is also an option...</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string CleanMissiles </em></code>:
|
||||
(Default=true) If true, missiles fired are immediately destroyed. If false missiles are not controlled.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(CLEANUP_AIRBASE)">#CLEANUP_AIRBASE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
@@ -333,276 +381,43 @@ CleanUpKutaisi = CLEANUP:New( 'CLEAN Kutaisi', 600 )</code></pre>
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CLEANUP).ZoneNames" >
|
||||
<strong>CLEANUP.ZoneNames</strong>
|
||||
<a id="#(CLEANUP_AIRBASE).__" >
|
||||
<strong>CLEANUP_AIRBASE.__</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> @field #CLEANUP<em>AIRBASE.</em>_</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(CLEANUP_AIRBASE.__)" >Type <code>CLEANUP_AIRBASE.__</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._AddForCleanUp" >
|
||||
<strong>CLEANUP:_AddForCleanUp(CleanUpUnit, CleanUpUnitName)</strong>
|
||||
<em><a href="##(map)">#map</a></em>
|
||||
<a id="#(CLEANUP_AIRBASE.__).<" >
|
||||
<strong>CLEANUP_AIRBASE.__.<</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Add the <a href="DCSWrapper.Unit.html##(Unit)">DCSWrapper.Unit#Unit</a> to the CleanUpList for CleanUp.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> CleanUpUnit </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> CleanUpUnitName </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._CleanUpScheduler" >
|
||||
<strong>CLEANUP:_CleanUpScheduler()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>At the defined time interval, CleanUp the Groups within the CleanUpList.</p>
|
||||
<p>string,Wrapper.Airbase#AIRBASE> Airbases Map of Airbases.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._DestroyGroup" >
|
||||
<strong>CLEANUP:_DestroyGroup(GroupObject, CleanUpGroupName)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Destroys a group from the simulator, but checks first if it is still existing!</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSWrapper.Group.html##(Group)">Dcs.DCSWrapper.Group#Group</a> GroupObject </em></code>:
|
||||
The object to be destroyed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string CleanUpGroupName </em></code>:
|
||||
The groupname...</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._DestroyMissile" >
|
||||
<strong>CLEANUP:_DestroyMissile(MissileObject)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> TODO check Dcs.DCSTypes#Weapon
|
||||
- Destroys a missile from the simulator, but checks first if it is still existing!
|
||||
@param #CLEANUP self
|
||||
@param Dcs.DCSTypes#Weapon MissileObject</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> MissileObject </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._DestroyUnit" >
|
||||
<strong>CLEANUP:_DestroyUnit(CleanUpUnit, CleanUpUnitName)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Destroys a <a href="DCSWrapper.Unit.html##(Unit)">DCSWrapper.Unit#Unit</a> from the simulator, but checks first if it is still existing!</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSWrapper.Unit.html##(Unit)">Dcs.DCSWrapper.Unit#Unit</a> CleanUpUnit </em></code>:
|
||||
The object to be destroyed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string CleanUpUnitName </em></code>:
|
||||
The Unit name ...</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._EventAddForCleanUp" >
|
||||
<strong>CLEANUP:_EventAddForCleanUp(event, Event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Detects if the Unit has an S<em>EVENT</em>ENGINE<em>SHUTDOWN or an S</em>EVENT_HIT within the given ZoneNames.</p>
|
||||
|
||||
|
||||
<p>If this is the case, add the Group to the CLEANUP List.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Event)">Dcs.DCSTypes#Event</a> event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._EventCrash" >
|
||||
<strong>CLEANUP:_EventCrash(event, Event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Detects if a crash event occurs.</p>
|
||||
|
||||
|
||||
<p>Crashed units go into a CleanUpList for removal.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Event)">Dcs.DCSTypes#Event</a> event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._EventHitCleanUp" >
|
||||
<strong>CLEANUP:_EventHitCleanUp(event, Event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Detects if the Unit has an S<em>EVENT</em>HIT within the given ZoneNames.</p>
|
||||
|
||||
|
||||
<p>If this is the case, destroy the unit.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Event)">Dcs.DCSTypes#Event</a> event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._EventShot" >
|
||||
<strong>CLEANUP:_EventShot(event, Event)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Detects if a unit shoots a missile.</p>
|
||||
|
||||
|
||||
<p>If this occurs within one of the zones, then the weapon used must be destroyed.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Event)">Dcs.DCSTypes#Event</a> event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLEANUP)._OnEventBirth" >
|
||||
<strong>CLEANUP:_OnEventBirth(EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(CLEANUP_AIRBASE.__.Airbases)" >Type <code>CLEANUP_AIRBASE.__.Airbases</code></a></h2>
|
||||
|
||||
<h2><a id="#(list)" >Type <code>list</code></a></h2>
|
||||
|
||||
<h2><a id="#(map)" >Type <code>map</code></a></h2>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,45 +105,17 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>Client</code></h1>
|
||||
|
||||
<p>This module contains the CLIENT class.</p>
|
||||
<p><strong>Wrapper</strong> -- CLIENT wraps DCS Unit objects acting as a <strong>Client</strong> or <strong>Player</strong> within a mission.</p>
|
||||
|
||||
|
||||
|
||||
<h1>1) <a href="Client.html##(CLIENT)">Client#CLIENT</a> class, extends <a href="Unit.html##(UNIT)">Unit#UNIT</a></h1>
|
||||
<p>Clients are those <strong>Units</strong> defined within the Mission Editor that have the skillset defined as <strong>Client</strong> or <strong>Player</strong>.
|
||||
Note that clients are NOT the same as Units, they are NOT necessarily alive.
|
||||
The <a href="Client.html##(CLIENT)">Client#CLIENT</a> class is a wrapper class to handle the DCS Unit objects that have the skillset defined as <strong>Client</strong> or <strong>Player</strong>:</p>
|
||||
<hr/>
|
||||
|
||||
<ul>
|
||||
<li>Wraps the DCS Unit objects with skill level set to Player or Client.</li>
|
||||
<li>Support all DCS Unit APIs.</li>
|
||||
<li>Enhance with Unit specific APIs not in the DCS Group API set.</li>
|
||||
<li>When player joins Unit, execute alive init logic.</li>
|
||||
<li>Handles messages to players.</li>
|
||||
<li>Manage the "state" of the DCS Unit.</li>
|
||||
</ul>
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<p>Clients are being used by the <a href="MISSION.html">MISSION</a> class to follow players and register their successes.</p>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<h2>1.1) CLIENT reference methods</h2>
|
||||
<p>For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _<a href="DATABASE.html">DATABASE</a> object.
|
||||
This is done at the beginning of the mission (when the mission starts).</p>
|
||||
|
||||
<p>The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference
|
||||
using the DCS Unit or the DCS UnitName.</p>
|
||||
|
||||
<p>Another thing to know is that CLIENT objects do not "contain" the DCS Unit object.
|
||||
The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution.
|
||||
If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file.</p>
|
||||
|
||||
<p>The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CLIENT).Find">CLIENT.Find</a>(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object.</li>
|
||||
<li><a href="##(CLIENT).FindByName">CLIENT.FindByName</a>(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name.</li>
|
||||
</ul>
|
||||
|
||||
<p>IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).</p>
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
@@ -143,7 +123,9 @@ If the DCS Unit object does not exist or is nil, the CLIENT methods will return
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CLIENT">CLIENT</a></td>
|
||||
<td class="summary">
|
||||
<h1>CLIENT class, extends <a href="Unit.html##(UNIT)">Unit#UNIT</a></h1>
|
||||
|
||||
<p>Clients are those <strong>Units</strong> defined within the Mission Editor that have the skillset defined as <strong>Client</strong> or <strong>Player</strong>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -159,18 +141,6 @@ If the DCS Unit object does not exist or is nil, the CLIENT methods will return
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).Alive">CLIENT:Alive(CallBackFunction, ...)</a></td>
|
||||
<td class="summary">
|
||||
<p>Checks for a client alive event and calls a function on a continuous basis.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClassName">CLIENT.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClientAlive">CLIENT.ClientAlive</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -213,12 +183,6 @@ If the DCS Unit object does not exist or is nil, the CLIENT methods will return
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClientGroupUnit">CLIENT.ClientGroupUnit</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ClientName">CLIENT.ClientName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -291,18 +255,6 @@ If the DCS Unit object does not exist or is nil, the CLIENT methods will return
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).Message">CLIENT:Message(Message, MessageDuration, MessageCategory, MessageInterval, MessageID)</a></td>
|
||||
<td class="summary">
|
||||
<p>The main message driver for the CLIENT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).Messages">CLIENT.Messages</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT).ONBOARDSIDE">CLIENT.ONBOARDSIDE</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -357,12 +309,6 @@ If the DCS Unit object does not exist or is nil, the CLIENT methods will return
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT)._Menus">CLIENT._Menus</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CLIENT)._Tasks">CLIENT._Tasks</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -378,6 +324,45 @@ If the DCS Unit object does not exist or is nil, the CLIENT methods will return
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<h1>CLIENT class, extends <a href="Unit.html##(UNIT)">Unit#UNIT</a></h1>
|
||||
|
||||
<p>Clients are those <strong>Units</strong> defined within the Mission Editor that have the skillset defined as <strong>Client</strong> or <strong>Player</strong>.</p>
|
||||
|
||||
|
||||
<p>Note that clients are NOT the same as Units, they are NOT necessarily alive.
|
||||
The CLIENT class is a wrapper class to handle the DCS Unit objects that have the skillset defined as <strong>Client</strong> or <strong>Player</strong>:</p>
|
||||
|
||||
<ul>
|
||||
<li>Wraps the DCS Unit objects with skill level set to Player or Client.</li>
|
||||
<li>Support all DCS Unit APIs.</li>
|
||||
<li>Enhance with Unit specific APIs not in the DCS Group API set.</li>
|
||||
<li>When player joins Unit, execute alive init logic.</li>
|
||||
<li>Handles messages to players.</li>
|
||||
<li>Manage the "state" of the DCS Unit.</li>
|
||||
</ul>
|
||||
|
||||
<p>Clients are being used by the <a href="MISSION.html">MISSION</a> class to follow players and register their successes.</p>
|
||||
|
||||
<h2>CLIENT reference methods</h2>
|
||||
|
||||
<p>For each DCS Unit having skill level Player or Client, a CLIENT wrapper object (instance) will be created within the _<a href="DATABASE.html">DATABASE</a> object.
|
||||
This is done at the beginning of the mission (when the mission starts).</p>
|
||||
|
||||
<p>The CLIENT class does not contain a :New() method, rather it provides :Find() methods to retrieve the object reference
|
||||
using the DCS Unit or the DCS UnitName.</p>
|
||||
|
||||
<p>Another thing to know is that CLIENT objects do not "contain" the DCS Unit object.
|
||||
The CLIENT methods will reference the DCS Unit object by name when it is needed during API execution.
|
||||
If the DCS Unit object does not exist or is nil, the CLIENT methods will return nil and log an exception in the DCS.log file.</p>
|
||||
|
||||
<p>The CLIENT class provides the following functions to retrieve quickly the relevant CLIENT instance:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CLIENT).Find">CLIENT.Find</a>(): Find a CLIENT instance from the _DATABASE object using a DCS Unit object.</li>
|
||||
<li><a href="##(CLIENT).FindByName">CLIENT.FindByName</a>(): Find a CLIENT instance from the _DATABASE object using a DCS Unit name.</li>
|
||||
</ul>
|
||||
|
||||
<p><strong>IMPORTANT: ONE SHOULD NEVER SANATIZE these CLIENT OBJECT REFERENCES! (make the CLIENT object references nil).</strong></p>
|
||||
|
||||
|
||||
</dd>
|
||||
@@ -446,34 +431,6 @@ Create a function that will be called when a player joins the slot.</p>
|
||||
<p><em><a href="##(CLIENT)">#CLIENT</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(CLIENT).ClassName" >
|
||||
<strong>CLIENT.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#boolean</em>
|
||||
<a id="#(CLIENT).ClientAlive" >
|
||||
<strong>CLIENT.ClientAlive</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -571,19 +528,6 @@ Create a function that will be called when a player joins the slot.</p>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CLIENT).ClientName" >
|
||||
<strong>CLIENT.ClientName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -896,34 +840,6 @@ is the identifier of the message when displayed with intervals.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CLIENT).Messages" >
|
||||
<strong>CLIENT.Messages</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CLIENT).ONBOARDSIDE" >
|
||||
<strong>CLIENT.ONBOARDSIDE</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -1108,20 +1024,6 @@ self</p>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CLIENT)._Tasks" >
|
||||
<strong>CLIENT._Tasks</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,17 +105,28 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>CommandCenter</code></h1>
|
||||
|
||||
<p>A COMMANDCENTER is the owner of multiple missions within MOOSE.</p>
|
||||
<p><strong>Tasking</strong> -- A COMMANDCENTER is the owner of multiple missions within MOOSE.</p>
|
||||
|
||||
|
||||
<p>A COMMANDCENTER governs multiple missions, the tasking and the reporting.</p>
|
||||
|
||||
<hr/>
|
||||
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<hr/>
|
||||
|
||||
|
||||
<h2>Global(s)</h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#COMMANDCENTER">COMMANDCENTER</a></td>
|
||||
<td class="summary">
|
||||
<h1>COMMANDCENTER class, extends <a href="Base.html##(BASE)">Base#BASE</a></h1>
|
||||
|
||||
<p> The COMMANDCENTER class governs multiple missions, the tasking and the reporting.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -123,12 +142,6 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).AddMission">COMMANDCENTER:AddMission(Mission)</a></td>
|
||||
<td class="summary">
|
||||
<p>Add a MISSION to be governed by the HQ command center.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).ClassName">COMMANDCENTER.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -144,13 +157,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).CommandCenterName">COMMANDCENTER.CommandCenterName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).CommandCenterPositionable">COMMANDCENTER.CommandCenterPositionable</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).CommunicationMode">COMMANDCENTER.CommunicationMode</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
@@ -189,6 +196,12 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).HasGroup">COMMANDCENTER:HasGroup(Wrapper, MissionGroup)</a></td>
|
||||
<td class="summary">
|
||||
<p>Checks of the COMMANDCENTER has a GROUP.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).IsModeWWII">COMMANDCENTER:IsModeWWII()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns if the commandcenter operations is in WWII mode</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -207,12 +220,6 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).MessageToGroup">COMMANDCENTER:MessageToGroup(Message, TaskGroup, Name)</a></td>
|
||||
<td class="summary">
|
||||
<p>Send a CC message to a GROUP.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).Name">COMMANDCENTER.Name</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -249,6 +256,20 @@
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).SetMenu">COMMANDCENTER:SetMenu()</a></td>
|
||||
<td class="summary">
|
||||
<p>Sets the menu structure of the Missions governed by the HQ command center.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).SetModeWWII">COMMANDCENTER:SetModeWWII()</a></td>
|
||||
<td class="summary">
|
||||
<p>Set the commandcenter operations in WWII mode
|
||||
This will disable LL, MGRS, BRA, BULLS navigatin messages sent by the Command Center,
|
||||
and will be replaced by a navigation using Reference Zones.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(COMMANDCENTER).SetReferenceZones">COMMANDCENTER:SetReferenceZones(ReferenceZonePrefix)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set special Reference Zones known by the Command Center to guide airborne pilots during WWII.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -328,6 +349,57 @@
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<h1>COMMANDCENTER class, extends <a href="Base.html##(BASE)">Base#BASE</a></h1>
|
||||
|
||||
<p> The COMMANDCENTER class governs multiple missions, the tasking and the reporting.</p>
|
||||
|
||||
|
||||
<p>
|
||||
The commandcenter communicates important messages between the various groups of human players executing tasks in missions.</p>
|
||||
|
||||
<h2>COMMANDCENTER constructor</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(COMMANDCENTER).New">COMMANDCENTER.New</a>(): Creates a new COMMANDCENTER object.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Mission Management</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(COMMANDCENTER).AddMission">COMMANDCENTER.AddMission</a>(): Adds a mission to the commandcenter control.</li>
|
||||
<li><a href="##(COMMANDCENTER).RemoveMission">COMMANDCENTER.RemoveMission</a>(): Removes a mission to the commandcenter control.</li>
|
||||
<li><a href="##(COMMANDCENTER).GetMissions">COMMANDCENTER.GetMissions</a>(): Retrieves the missions table controlled by the commandcenter.</li>
|
||||
</ul>
|
||||
|
||||
<h2>Reference Zones</h2>
|
||||
|
||||
<p>Command Centers may be aware of certain Reference Zones within the battleground. These Reference Zones can refer to
|
||||
known areas, recognizable buildings or sites, or any other point of interest.
|
||||
Command Centers will use these Reference Zones to help pilots with defining coordinates in terms of navigation
|
||||
during the WWII era.
|
||||
The Reference Zones are related to the WWII mode that the Command Center will operate in.
|
||||
Use the method <a href="##(COMMANDCENTER).SetModeWWII">COMMANDCENTER.SetModeWWII</a>() to set the mode of communication to the WWII mode.</p>
|
||||
|
||||
<p>In WWII mode, the Command Center will receive detected targets, and will select for each target the closest
|
||||
nearby Reference Zone. This allows pilots to navigate easier through the battle field readying for combat.</p>
|
||||
|
||||
<p>The Reference Zones need to be set by the Mission Designer in the Mission Editor.
|
||||
Reference Zones are set by normal trigger zones. One can color the zones in a specific color,
|
||||
and the radius of the zones doesn't matter, only the point is important. Place the center of these Reference Zones at
|
||||
specific scenery objects or points of interest (like cities, rivers, hills, crossing etc).
|
||||
The trigger zones indicating a Reference Zone need to follow a specific syntax.
|
||||
The name of each trigger zone expressing a Reference Zone need to start with a classification name of the object,
|
||||
followed by a #, followed by a symbolic name of the Reference Zone.
|
||||
A few examples:</p>
|
||||
|
||||
<ul>
|
||||
<li>A church at Tskinvali would be indicated as: <em>Church#Tskinvali</em></li>
|
||||
<li>A train station near Kobuleti would be indicated as: <em>Station#Kobuleti</em></li>
|
||||
</ul>
|
||||
|
||||
<p>The COMMANDCENTER class contains a method to indicate which trigger zones need to be used as Reference Zones.
|
||||
This is done by using the method <a href="##(COMMANDCENTER).SetReferenceZones">COMMANDCENTER.SetReferenceZones</a>().
|
||||
For the moment, only one Reference Zone class can be specified, but in the future, more classes will become possible.</p>
|
||||
|
||||
|
||||
</dd>
|
||||
@@ -377,20 +449,6 @@
|
||||
<p><em><a href="Tasking.Mission.html##(MISSION)">Tasking.Mission#MISSION</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(COMMANDCENTER).ClassName" >
|
||||
<strong>COMMANDCENTER.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -424,21 +482,8 @@
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(COMMANDCENTER).CommandCenterName" >
|
||||
<strong>COMMANDCENTER.CommandCenterName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(COMMANDCENTER).CommandCenterPositionable" >
|
||||
<strong>COMMANDCENTER.CommandCenterPositionable</strong>
|
||||
<a id="#(COMMANDCENTER).CommunicationMode" >
|
||||
<strong>COMMANDCENTER.CommunicationMode</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@@ -563,6 +608,24 @@ Group#GROUP</p>
|
||||
<p><em>#boolean:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(COMMANDCENTER).IsModeWWII" >
|
||||
<strong>COMMANDCENTER:IsModeWWII()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns if the commandcenter operations is in WWII mode</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#boolean:</em>
|
||||
true if in WWII mode.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -637,20 +700,6 @@ Group#GROUP</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(COMMANDCENTER).Name" >
|
||||
<strong>COMMANDCENTER.Name</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -801,6 +850,81 @@ Group#GROUP</p>
|
||||
|
||||
<p>Sets the menu structure of the Missions governed by the HQ command center.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(COMMANDCENTER).SetModeWWII" >
|
||||
<strong>COMMANDCENTER:SetModeWWII()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set the commandcenter operations in WWII mode
|
||||
This will disable LL, MGRS, BRA, BULLS navigatin messages sent by the Command Center,
|
||||
and will be replaced by a navigation using Reference Zones.</p>
|
||||
|
||||
|
||||
<p>It will also disable the settings at the settings menu for these.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(COMMANDCENTER)">#COMMANDCENTER</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(COMMANDCENTER).SetReferenceZones" >
|
||||
<strong>COMMANDCENTER:SetReferenceZones(ReferenceZonePrefix)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set special Reference Zones known by the Command Center to guide airborne pilots during WWII.</p>
|
||||
|
||||
|
||||
|
||||
<p>These Reference Zones are normal trigger zones, with a special naming.
|
||||
The Reference Zones need to be set by the Mission Designer in the Mission Editor.
|
||||
Reference Zones are set by normal trigger zones. One can color the zones in a specific color,
|
||||
and the radius of the zones doesn't matter, only the center of the zone is important. Place the center of these Reference Zones at
|
||||
specific scenery objects or points of interest (like cities, rivers, hills, crossing etc).
|
||||
The trigger zones indicating a Reference Zone need to follow a specific syntax.
|
||||
The name of each trigger zone expressing a Reference Zone need to start with a classification name of the object,
|
||||
followed by a #, followed by a symbolic name of the Reference Zone.
|
||||
A few examples:</p>
|
||||
|
||||
<ul>
|
||||
<li>A church at Tskinvali would be indicated as: <em>Church#Tskinvali</em></li>
|
||||
<li>A train station near Kobuleti would be indicated as: <em>Station#Kobuleti</em></li>
|
||||
</ul>
|
||||
|
||||
<p>Taking the above example, this is how this method would be used:</p>
|
||||
|
||||
<pre><code>CC:SetReferenceZones( "Church" )
|
||||
CC:SetReferenceZones( "Station" )
|
||||
</code></pre>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string ReferenceZonePrefix </em></code>:
|
||||
The name before the #-mark indicating the class of the Reference Zones.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(COMMANDCENTER)">#COMMANDCENTER</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
@@ -97,145 +105,15 @@
|
||||
<div id="content">
|
||||
<h1>Module <code>Controllable</code></h1>
|
||||
|
||||
<p>This module contains the CONTROLLABLE class.</p>
|
||||
<p><strong>Wrapper</strong> -- CONTROLLABLE is an intermediate class wrapping Group and Unit classes "controllers".</p>
|
||||
|
||||
|
||||
|
||||
<h1>1) <a href="Controllable.html##(CONTROLLABLE)">Controllable#CONTROLLABLE</a> class, extends <a href="Positionable.html##(POSITIONABLE)">Positionable#POSITIONABLE</a></h1>
|
||||
<p>The <a href="Controllable.html##(CONTROLLABLE)">Controllable#CONTROLLABLE</a> class is a wrapper class to handle the DCS Controllable objects:</p>
|
||||
<hr/>
|
||||
|
||||
<ul>
|
||||
<li>Support all DCS Controllable APIs.</li>
|
||||
<li>Enhance with Controllable specific APIs not in the DCS Controllable API set.</li>
|
||||
<li>Handle local Controllable Controller.</li>
|
||||
<li>Manage the "state" of the DCS Controllable.</li>
|
||||
</ul>
|
||||
<h3>Author: <strong>Sven Van de Velde (FlightControl)</strong></h3>
|
||||
|
||||
<h2>1.1) CONTROLLABLE constructor</h2>
|
||||
<p>The CONTROLLABLE class provides the following functions to construct a CONTROLLABLE instance:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).New">CONTROLLABLE.New</a>(): Create a CONTROLLABLE instance.</li>
|
||||
</ul>
|
||||
|
||||
<h2>1.2) CONTROLLABLE task methods</h2>
|
||||
<p>Several controllable task methods are available that help you to prepare tasks.
|
||||
These methods return a string consisting of the task description, which can then be given to either a <a href="Controllable.html##(CONTROLLABLE).PushTask">Controllable#CONTROLLABLE.PushTask</a> or <a href="Controllable.html##(SetTask)">Controllable#SetTask</a> method to assign the task to the CONTROLLABLE.
|
||||
Tasks are specific for the category of the CONTROLLABLE, more specific, for AIR, GROUND or AIR and GROUND.
|
||||
Each task description where applicable indicates for which controllable category the task is valid.
|
||||
There are 2 main subdivisions of tasks: Assigned tasks and EnRoute tasks.</p>
|
||||
|
||||
<h3>1.2.1) Assigned task methods</h3>
|
||||
|
||||
<p>Assigned task methods make the controllable execute the task where the location of the (possible) targets of the task are known before being detected.
|
||||
This is different from the EnRoute tasks, where the targets of the task need to be detected before the task can be executed.</p>
|
||||
|
||||
<p>Find below a list of the <strong>assigned task</strong> methods:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).TaskAttackGroup">CONTROLLABLE.TaskAttackGroup</a>: (AIR) Attack a Controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskAttackMapObject">CONTROLLABLE.TaskAttackMapObject</a>: (AIR) Attacking the map object (building, structure, e.t.c).</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskAttackUnit">CONTROLLABLE.TaskAttackUnit</a>: (AIR) Attack the Unit.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskBombing">CONTROLLABLE.TaskBombing</a>: (AIR) Delivering weapon at the point on the ground.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskBombingRunway">CONTROLLABLE.TaskBombingRunway</a>: (AIR) Delivering weapon on the runway.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskEmbarking">CONTROLLABLE.TaskEmbarking</a>: (AIR) Move the controllable to a Vec2 Point, wait for a defined duration and embark a controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskEmbarkToTransport">CONTROLLABLE.TaskEmbarkToTransport</a>: (GROUND) Embark to a Transport landed at a location.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskEscort">CONTROLLABLE.TaskEscort</a>: (AIR) Escort another airborne controllable. </li>
|
||||
<li><a href="##(CONTROLLABLE).TaskFAC_AttackGroup">CONTROLLABLE.TaskFAC_AttackGroup</a>: (AIR + GROUND) The task makes the controllable/unit a FAC and orders the FAC to control the target (enemy ground controllable) destruction.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskFireAtPoint">CONTROLLABLE.TaskFireAtPoint</a>: (GROUND) Fire some or all ammunition at a VEC2 point.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskFollow">CONTROLLABLE.TaskFollow</a>: (AIR) Following another airborne controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskHold">CONTROLLABLE.TaskHold</a>: (GROUND) Hold ground controllable from moving.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskHoldPosition">CONTROLLABLE.TaskHoldPosition</a>: (AIR) Hold position at the current position of the first unit of the controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskLand">CONTROLLABLE.TaskLand</a>: (AIR HELICOPTER) Landing at the ground. For helicopters only.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskLandAtZone">CONTROLLABLE.TaskLandAtZone</a>: (AIR) Land the controllable at a <a href="##(CONTROLLABLE).TaskOrbitCircle">CONTROLLABLE.TaskOrbitCircle</a>: (AIR) Orbit at the current position of the first unit of the controllable at a specified alititude.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskOrbitCircleAtVec2">CONTROLLABLE.TaskOrbitCircleAtVec2</a>: (AIR) Orbit at a specified position at a specified alititude during a specified duration with a specified speed.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRefueling">CONTROLLABLE.TaskRefueling</a>: (AIR) Refueling from the nearest tanker. No parameters.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRoute">CONTROLLABLE.TaskRoute</a>: (AIR + GROUND) Return a Misson task to follow a given route defined by Points.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRouteToVec2">CONTROLLABLE.TaskRouteToVec2</a>: (AIR + GROUND) Make the Controllable move to a given point.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRouteToVec3">CONTROLLABLE.TaskRouteToVec3</a>: (AIR + GROUND) Make the Controllable move to a given point.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRouteToZone">CONTROLLABLE.TaskRouteToZone</a>: (AIR + GROUND) Route the controllable to a given zone.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskReturnToBase">CONTROLLABLE.TaskReturnToBase</a>: (AIR) Route the controllable to an airbase.</li>
|
||||
</ul>
|
||||
|
||||
<h3>1.2.2) EnRoute task methods</h3>
|
||||
|
||||
<p>EnRoute tasks require the targets of the task need to be detected by the controllable (using its sensors) before the task can be executed:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskAWACS">CONTROLLABLE.EnRouteTaskAWACS</a>: (AIR) Aircraft will act as an AWACS for friendly units (will provide them with information about contacts). No parameters.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskEngageControllable">CONTROLLABLE.EnRouteTaskEngageControllable</a>: (AIR) Engaging a controllable. The task does not assign the target controllable to the unit/controllable to attack now; it just allows the unit/controllable to engage the target controllable as well as other assigned targets.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskEngageTargets">CONTROLLABLE.EnRouteTaskEngageTargets</a>: (AIR) Engaging targets of defined types.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskEWR">CONTROLLABLE.EnRouteTaskEWR</a>: (AIR) Attack the Unit.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskFAC">CONTROLLABLE.EnRouteTaskFAC</a>: (AIR + GROUND) The task makes the controllable/unit a FAC and lets the FAC to choose a targets (enemy ground controllable) around as well as other assigned targets.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskFAC_EngageControllable">CONTROLLABLE.EnRouteTaskFAC_EngageControllable</a>: (AIR + GROUND) The task makes the controllable/unit a FAC and lets the FAC to choose the target (enemy ground controllable) as well as other assigned targets.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskTanker">CONTROLLABLE.EnRouteTaskTanker</a>: (AIR) Aircraft will act as a tanker for friendly units. No parameters.</li>
|
||||
</ul>
|
||||
|
||||
<h3>1.2.3) Preparation task methods</h3>
|
||||
|
||||
<p>There are certain task methods that allow to tailor the task behaviour:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).TaskWrappedAction">CONTROLLABLE.TaskWrappedAction</a>: Return a WrappedAction Task taking a Command.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskCombo">CONTROLLABLE.TaskCombo</a>: Return a Combo Task taking an array of Tasks.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskCondition">CONTROLLABLE.TaskCondition</a>: Return a condition section for a controlled task.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskControlled">CONTROLLABLE.TaskControlled</a>: Return a Controlled Task taking a Task and a TaskCondition.</li>
|
||||
</ul>
|
||||
|
||||
<h3>1.2.4) Obtain the mission from controllable templates</h3>
|
||||
|
||||
<p>Controllable templates contain complete mission descriptions. Sometimes you want to copy a complete mission from a controllable and assign it to another:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).TaskMission">CONTROLLABLE.TaskMission</a>: (AIR + GROUND) Return a mission task from a mission template.</li>
|
||||
</ul>
|
||||
|
||||
<h2>1.3) CONTROLLABLE Command methods</h2>
|
||||
<p>Controllable <strong>command methods</strong> prepare the execution of commands using the <a href="##(CONTROLLABLE).SetCommand">CONTROLLABLE.SetCommand</a> method:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).CommandDoScript">CONTROLLABLE.CommandDoScript</a>: Do Script command.</li>
|
||||
<li><a href="##(CONTROLLABLE).CommandSwitchWayPoint">CONTROLLABLE.CommandSwitchWayPoint</a>: Perform a switch waypoint command.</li>
|
||||
</ul>
|
||||
|
||||
<h2>1.4) CONTROLLABLE Option methods</h2>
|
||||
<p>Controllable <strong>Option methods</strong> change the behaviour of the Controllable while being alive.</p>
|
||||
|
||||
<h3>1.4.1) Rule of Engagement:</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEWeaponFree">CONTROLLABLE.OptionROEWeaponFree</a> </li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEOpenFire">CONTROLLABLE.OptionROEOpenFire</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEReturnFire">CONTROLLABLE.OptionROEReturnFire</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEEvadeFire">CONTROLLABLE.OptionROEEvadeFire</a></li>
|
||||
</ul>
|
||||
|
||||
<p>To check whether an ROE option is valid for a specific controllable, use:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEWeaponFreePossible">CONTROLLABLE.OptionROEWeaponFreePossible</a> </li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEOpenFirePossible">CONTROLLABLE.OptionROEOpenFirePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEReturnFirePossible">CONTROLLABLE.OptionROEReturnFirePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEEvadeFirePossible">CONTROLLABLE.OptionROEEvadeFirePossible</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>1.4.2) Rule on thread:</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTNoReaction">CONTROLLABLE.OptionROTNoReaction</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTPassiveDefense">CONTROLLABLE.OptionROTPassiveDefense</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTEvadeFire">CONTROLLABLE.OptionROTEvadeFire</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTVertical">CONTROLLABLE.OptionROTVertical</a></li>
|
||||
</ul>
|
||||
|
||||
<p>To test whether an ROT option is valid for a specific controllable, use:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTNoReactionPossible">CONTROLLABLE.OptionROTNoReactionPossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTPassiveDefensePossible">CONTROLLABLE.OptionROTPassiveDefensePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTEvadeFirePossible">CONTROLLABLE.OptionROTEvadeFirePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTVerticalPossible">CONTROLLABLE.OptionROTVerticalPossible</a></li>
|
||||
</ul>
|
||||
<h3>Contributions:</h3>
|
||||
|
||||
<hr/>
|
||||
|
||||
@@ -245,19 +123,19 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="#CONTROLLABLE">CONTROLLABLE</a></td>
|
||||
<td class="summary">
|
||||
<h1>CONTROLLABLE class, extends <a href="Positionable.html##(POSITIONABLE)">Positionable#POSITIONABLE</a></h1>
|
||||
|
||||
<p>CONTROLLABLE is a wrapper class to handle the "DCS Controllable objects", which are Groups and Units:</p>
|
||||
|
||||
<ul>
|
||||
<li>Support all DCS Controllable APIs.</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<h2><a id="#(CONTROLLABLE)">Type <code>CONTROLLABLE</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).ClassName">CONTROLLABLE.ClassName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).ClearTasks">CONTROLLABLE:ClearTasks()</a></td>
|
||||
<td class="summary">
|
||||
<p>Clear all tasks from the controllable.</p>
|
||||
@@ -321,6 +199,12 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).EnRouteTaskEngageTargets">CONTROLLABLE:EnRouteTaskEngageTargets(Distance, TargetTypes, Priority)</a></td>
|
||||
<td class="summary">
|
||||
<p>(AIR) Engaging targets of defined types.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).EnRouteTaskEngageTargetsInZone">CONTROLLABLE:EnRouteTaskEngageTargetsInZone(Vec2, Radius, TargetTypes, Priority)</a></td>
|
||||
<td class="summary">
|
||||
<p>(AIR) Engaging a targets of defined types at circle-shaped zone.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -357,6 +241,18 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).GetLife">CONTROLLABLE:GetLife()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns the health.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).GetLife0">CONTROLLABLE:GetLife0()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns the initial health.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).GetSize">CONTROLLABLE:GetSize()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -381,6 +277,18 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).GetWayPoints">CONTROLLABLE:GetWayPoints()</a></td>
|
||||
<td class="summary">
|
||||
<p>Get the current WayPoints set with the WayPoint functions( Note that the WayPoints can be nil, although there ARE waypoints).</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).HasTask">CONTROLLABLE:HasTask()</a></td>
|
||||
<td class="summary">
|
||||
<p>Checking the Task Queue of the controllable.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).IsAirPlane">CONTROLLABLE:IsAirPlane()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns if the Controllable contains AirPlanes.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -489,6 +397,18 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).OptionROTVerticalPossible">CONTROLLABLE:OptionROTVerticalPossible()</a></td>
|
||||
<td class="summary">
|
||||
<p>Can the CONTROLLABLE evade on fire using vertical manoeuvres?</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).OptionRTBAmmo">CONTROLLABLE:OptionRTBAmmo(WeaponsFlag)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set RTB on ammo.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).OptionRTBBingoFuel">CONTROLLABLE:OptionRTBBingoFuel(RTB)</a></td>
|
||||
<td class="summary">
|
||||
<p>Set RTB on bingo fuel.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -675,12 +595,24 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).TaskRoute">CONTROLLABLE:TaskRoute(Points)</a></td>
|
||||
<td class="summary">
|
||||
<p>Return a Misson task to follow a given route defined by Points.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).TaskRouteToVec2">CONTROLLABLE:TaskRouteToVec2(Vec2, Speed, Formation)</a></td>
|
||||
<td class="summary">
|
||||
<p>(GROUND) Route the controllable to a given Vec2.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).TaskRouteToZone">CONTROLLABLE:TaskRouteToZone(Zone, Randomize, Speed, Formation)</a></td>
|
||||
<td class="summary">
|
||||
<p>(AIR + GROUND) Route the controllable to a given zone.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).TaskScheduler">CONTROLLABLE.TaskScheduler</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -699,12 +631,6 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).WayPointFunction">CONTROLLABLE:WayPointFunction(WayPoint, WayPointIndex, WayPointFunction, ...)</a></td>
|
||||
<td class="summary">
|
||||
<p>Registers a waypoint function that will be executed when the controllable moves over the WayPoint.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE).WayPointFunctions">CONTROLLABLE.WayPointFunctions</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -723,6 +649,22 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<td class="name" nowrap="nowrap"><a href="##(CONTROLLABLE)._GetController">CONTROLLABLE:_GetController()</a></td>
|
||||
<td class="summary">
|
||||
<p>Get the controller for the CONTROLLABLE.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2><a id="#(Vec2)">Type <code>Vec2</code></a></h2>
|
||||
<table class="function_list">
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(Vec2).x">Vec2.x</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(Vec2).y">Vec2.y</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -738,6 +680,151 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<h1>CONTROLLABLE class, extends <a href="Positionable.html##(POSITIONABLE)">Positionable#POSITIONABLE</a></h1>
|
||||
|
||||
<p>CONTROLLABLE is a wrapper class to handle the "DCS Controllable objects", which are Groups and Units:</p>
|
||||
|
||||
<ul>
|
||||
<li>Support all DCS Controllable APIs.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<ul>
|
||||
<li>Enhance with Controllable specific APIs not in the DCS Controllable API set.</li>
|
||||
<li>Handle local Controllable Controller.</li>
|
||||
<li>Manage the "state" of the DCS Controllable.</li>
|
||||
</ul>
|
||||
|
||||
<h2>CONTROLLABLE constructor</h2>
|
||||
|
||||
<p>The CONTROLLABLE class provides the following functions to construct a CONTROLLABLE instance:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).New">CONTROLLABLE.New</a>(): Create a CONTROLLABLE instance.</li>
|
||||
</ul>
|
||||
|
||||
<h2>CONTROLLABLE Task methods</h2>
|
||||
|
||||
<p>Several controllable task methods are available that help you to prepare tasks.
|
||||
These methods return a string consisting of the task description, which can then be given to either a <a href="Controllable.html##(CONTROLLABLE).PushTask">Controllable#CONTROLLABLE.PushTask</a> or <a href="Controllable.html##(SetTask)">Controllable#SetTask</a> method to assign the task to the CONTROLLABLE.
|
||||
Tasks are specific for the category of the CONTROLLABLE, more specific, for AIR, GROUND or AIR and GROUND.
|
||||
Each task description where applicable indicates for which controllable category the task is valid.
|
||||
There are 2 main subdivisions of tasks: Assigned tasks and EnRoute tasks.</p>
|
||||
|
||||
<h3>Task assignment</h3>
|
||||
|
||||
<p>Assigned task methods make the controllable execute the task where the location of the (possible) targets of the task are known before being detected.
|
||||
This is different from the EnRoute tasks, where the targets of the task need to be detected before the task can be executed.</p>
|
||||
|
||||
<p>Find below a list of the <strong>assigned task</strong> methods:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).TaskAttackGroup">CONTROLLABLE.TaskAttackGroup</a>: (AIR) Attack a Controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskAttackMapObject">CONTROLLABLE.TaskAttackMapObject</a>: (AIR) Attacking the map object (building, structure, e.t.c).</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskAttackUnit">CONTROLLABLE.TaskAttackUnit</a>: (AIR) Attack the Unit.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskBombing">CONTROLLABLE.TaskBombing</a>: (AIR) Delivering weapon at the point on the ground.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskBombingRunway">CONTROLLABLE.TaskBombingRunway</a>: (AIR) Delivering weapon on the runway.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskEmbarking">CONTROLLABLE.TaskEmbarking</a>: (AIR) Move the controllable to a Vec2 Point, wait for a defined duration and embark a controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskEmbarkToTransport">CONTROLLABLE.TaskEmbarkToTransport</a>: (GROUND) Embark to a Transport landed at a location.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskEscort">CONTROLLABLE.TaskEscort</a>: (AIR) Escort another airborne controllable. </li>
|
||||
<li><a href="##(CONTROLLABLE).TaskFAC_AttackGroup">CONTROLLABLE.TaskFAC_AttackGroup</a>: (AIR + GROUND) The task makes the controllable/unit a FAC and orders the FAC to control the target (enemy ground controllable) destruction.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskFireAtPoint">CONTROLLABLE.TaskFireAtPoint</a>: (GROUND) Fire some or all ammunition at a VEC2 point.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskFollow">CONTROLLABLE.TaskFollow</a>: (AIR) Following another airborne controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskHold">CONTROLLABLE.TaskHold</a>: (GROUND) Hold ground controllable from moving.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskHoldPosition">CONTROLLABLE.TaskHoldPosition</a>: (AIR) Hold position at the current position of the first unit of the controllable.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskLand">CONTROLLABLE.TaskLand</a>: (AIR HELICOPTER) Landing at the ground. For helicopters only.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskLandAtZone">CONTROLLABLE.TaskLandAtZone</a>: (AIR) Land the controllable at a <a href="##(CONTROLLABLE).TaskOrbitCircle">CONTROLLABLE.TaskOrbitCircle</a>: (AIR) Orbit at the current position of the first unit of the controllable at a specified alititude.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskOrbitCircleAtVec2">CONTROLLABLE.TaskOrbitCircleAtVec2</a>: (AIR) Orbit at a specified position at a specified alititude during a specified duration with a specified speed.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRefueling">CONTROLLABLE.TaskRefueling</a>: (AIR) Refueling from the nearest tanker. No parameters.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRoute">CONTROLLABLE.TaskRoute</a>: (AIR + GROUND) Return a Misson task to follow a given route defined by Points.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRouteToVec2">CONTROLLABLE.TaskRouteToVec2</a>: (AIR + GROUND) Make the Controllable move to a given point.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRouteToVec3">CONTROLLABLE.TaskRouteToVec3</a>: (AIR + GROUND) Make the Controllable move to a given point.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskRouteToZone">CONTROLLABLE.TaskRouteToZone</a>: (AIR + GROUND) Route the controllable to a given zone.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskReturnToBase">CONTROLLABLE.TaskReturnToBase</a>: (AIR) Route the controllable to an airbase.</li>
|
||||
</ul>
|
||||
|
||||
<h3>EnRoute assignment</h3>
|
||||
|
||||
<p>EnRoute tasks require the targets of the task need to be detected by the controllable (using its sensors) before the task can be executed:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskAWACS">CONTROLLABLE.EnRouteTaskAWACS</a>: (AIR) Aircraft will act as an AWACS for friendly units (will provide them with information about contacts). No parameters.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskEngageControllable">CONTROLLABLE.EnRouteTaskEngageControllable</a>: (AIR) Engaging a controllable. The task does not assign the target controllable to the unit/controllable to attack now; it just allows the unit/controllable to engage the target controllable as well as other assigned targets.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskEngageTargets">CONTROLLABLE.EnRouteTaskEngageTargets</a>: (AIR) Engaging targets of defined types.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskEngageTargetsInZone">CONTROLLABLE.EnRouteTaskEngageTargetsInZone</a>: (AIR) Engaging a targets of defined types at circle-shaped zone.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskEWR">CONTROLLABLE.EnRouteTaskEWR</a>: (AIR) Attack the Unit.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskFAC">CONTROLLABLE.EnRouteTaskFAC</a>: (AIR + GROUND) The task makes the controllable/unit a FAC and lets the FAC to choose a targets (enemy ground controllable) around as well as other assigned targets.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskFAC_EngageControllable">CONTROLLABLE.EnRouteTaskFAC_EngageControllable</a>: (AIR + GROUND) The task makes the controllable/unit a FAC and lets the FAC to choose the target (enemy ground controllable) as well as other assigned targets.</li>
|
||||
<li><a href="##(CONTROLLABLE).EnRouteTaskTanker">CONTROLLABLE.EnRouteTaskTanker</a>: (AIR) Aircraft will act as a tanker for friendly units. No parameters.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Task preparation</h3>
|
||||
|
||||
<p>There are certain task methods that allow to tailor the task behaviour:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).TaskWrappedAction">CONTROLLABLE.TaskWrappedAction</a>: Return a WrappedAction Task taking a Command.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskCombo">CONTROLLABLE.TaskCombo</a>: Return a Combo Task taking an array of Tasks.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskCondition">CONTROLLABLE.TaskCondition</a>: Return a condition section for a controlled task.</li>
|
||||
<li><a href="##(CONTROLLABLE).TaskControlled">CONTROLLABLE.TaskControlled</a>: Return a Controlled Task taking a Task and a TaskCondition.</li>
|
||||
</ul>
|
||||
|
||||
<h3>Obtain the mission from controllable templates</h3>
|
||||
|
||||
<p>Controllable templates contain complete mission descriptions. Sometimes you want to copy a complete mission from a controllable and assign it to another:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).TaskMission">CONTROLLABLE.TaskMission</a>: (AIR + GROUND) Return a mission task from a mission template.</li>
|
||||
</ul>
|
||||
|
||||
<h2>CONTROLLABLE Command methods</h2>
|
||||
|
||||
<p>Controllable <strong>command methods</strong> prepare the execution of commands using the <a href="##(CONTROLLABLE).SetCommand">CONTROLLABLE.SetCommand</a> method:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).CommandDoScript">CONTROLLABLE.CommandDoScript</a>: Do Script command.</li>
|
||||
<li><a href="##(CONTROLLABLE).CommandSwitchWayPoint">CONTROLLABLE.CommandSwitchWayPoint</a>: Perform a switch waypoint command.</li>
|
||||
</ul>
|
||||
|
||||
<h2>CONTROLLABLE Option methods</h2>
|
||||
|
||||
<p>Controllable <strong>Option methods</strong> change the behaviour of the Controllable while being alive.</p>
|
||||
|
||||
<h3>Rule of Engagement:</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEWeaponFree">CONTROLLABLE.OptionROEWeaponFree</a> </li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEOpenFire">CONTROLLABLE.OptionROEOpenFire</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEReturnFire">CONTROLLABLE.OptionROEReturnFire</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEEvadeFire">CONTROLLABLE.OptionROEEvadeFire</a></li>
|
||||
</ul>
|
||||
|
||||
<p>To check whether an ROE option is valid for a specific controllable, use:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEWeaponFreePossible">CONTROLLABLE.OptionROEWeaponFreePossible</a> </li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEOpenFirePossible">CONTROLLABLE.OptionROEOpenFirePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEReturnFirePossible">CONTROLLABLE.OptionROEReturnFirePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROEEvadeFirePossible">CONTROLLABLE.OptionROEEvadeFirePossible</a></li>
|
||||
</ul>
|
||||
|
||||
<h3>Rule on thread:</h3>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTNoReaction">CONTROLLABLE.OptionROTNoReaction</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTPassiveDefense">CONTROLLABLE.OptionROTPassiveDefense</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTEvadeFire">CONTROLLABLE.OptionROTEvadeFire</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTVertical">CONTROLLABLE.OptionROTVertical</a></li>
|
||||
</ul>
|
||||
|
||||
<p>To test whether an ROT option is valid for a specific controllable, use:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTNoReactionPossible">CONTROLLABLE.OptionROTNoReactionPossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTPassiveDefensePossible">CONTROLLABLE.OptionROTPassiveDefensePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTEvadeFirePossible">CONTROLLABLE.OptionROTEvadeFirePossible</a></li>
|
||||
<li><a href="##(CONTROLLABLE).OptionROTVerticalPossible">CONTROLLABLE.OptionROTVerticalPossible</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
</dd>
|
||||
@@ -745,24 +832,7 @@ This is different from the EnRoute tasks, where the targets of the task need to
|
||||
<h2><a id="#(Controllable)" >Type <code>Controllable</code></a></h2>
|
||||
|
||||
<h2><a id="#(CONTROLLABLE)" >Type <code>CONTROLLABLE</code></a></h2>
|
||||
|
||||
<p>The CONTROLLABLE class</p>
|
||||
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#string</em>
|
||||
<a id="#(CONTROLLABLE).ClassName" >
|
||||
<strong>CONTROLLABLE.ClassName</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
@@ -1114,6 +1184,51 @@ The DCS task structure.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).EnRouteTaskEngageTargetsInZone" >
|
||||
<strong>CONTROLLABLE:EnRouteTaskEngageTargetsInZone(Vec2, Radius, TargetTypes, Priority)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>(AIR) Engaging a targets of defined types at circle-shaped zone.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Vec2)">Dcs.DCSTypes#Vec2</a> Vec2 </em></code>:
|
||||
2D-coordinates of the zone. </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> Radius </em></code>:
|
||||
Radius of the zone. </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(AttributeNameArray)">Dcs.DCSTypes#AttributeNameArray</a> TargetTypes </em></code>:
|
||||
Array of target categories allowed to engage. </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number Priority </em></code>:
|
||||
All en-route tasks have the priority parameter. This is a number (less value - higher priority) that determines actions related to what task will be performed first. </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="Dcs.DCSTasking.Task.html##(Task)">Dcs.DCSTasking.Task#Task</a>:</em>
|
||||
The DCS task structure.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).EnRouteTaskEngageUnit" >
|
||||
<strong>CONTROLLABLE:EnRouteTaskEngageUnit(EngageUnit, Priority, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, Visible, ControllableAttack)</strong>
|
||||
</a>
|
||||
@@ -1389,6 +1504,47 @@ The controllable is not existing or alive. </p>
|
||||
|
||||
</li>
|
||||
</ol>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).GetLife0" >
|
||||
<strong>CONTROLLABLE:GetLife0()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns the initial health.</p>
|
||||
|
||||
<h3>Return values</h3>
|
||||
<ol>
|
||||
<li>
|
||||
|
||||
<p><em>#number:</em>
|
||||
The controllable health value (unit or group average).</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><em>#nil:</em>
|
||||
The controllable is not existing or alive. </p>
|
||||
|
||||
</li>
|
||||
</ol>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).GetSize" >
|
||||
<strong>CONTROLLABLE:GetSize()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -1467,6 +1623,45 @@ WayPoints If WayPoints is given, then return the WayPoints structure.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).HasTask" >
|
||||
<strong>CONTROLLABLE:HasTask()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Checking the Task Queue of the controllable.</p>
|
||||
|
||||
|
||||
<p>Returns false if no task is on the queue. true if there is a task.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="Wrapper.Controllable.html##(CONTROLLABLE)">Wrapper.Controllable#CONTROLLABLE</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).IsAirPlane" >
|
||||
<strong>CONTROLLABLE:IsAirPlane()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns if the Controllable contains AirPlanes.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#boolean:</em>
|
||||
true if Controllable contains AirPlanes.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).IsTargetDetected" >
|
||||
<strong>CONTROLLABLE:IsTargetDetected(DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK)</strong>
|
||||
</a>
|
||||
@@ -1828,6 +2023,61 @@ self</p>
|
||||
<p><em>#boolean:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).OptionRTBAmmo" >
|
||||
<strong>CONTROLLABLE:OptionRTBAmmo(WeaponsFlag)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set RTB on ammo.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#boolean WeaponsFlag </em></code>:
|
||||
Weapons.flag enumerator.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(CONTROLLABLE)">#CONTROLLABLE</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).OptionRTBBingoFuel" >
|
||||
<strong>CONTROLLABLE:OptionRTBBingoFuel(RTB)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Set RTB on bingo fuel.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#boolean RTB </em></code>:
|
||||
true if RTB on bingo fuel (default), false if no RTB on bingo fuel.
|
||||
Warning! When you switch this option off, the airborne group will continue to fly until all fuel has been consumed, and will crash.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(CONTROLLABLE)">#CONTROLLABLE</a>:</em>
|
||||
self</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -3022,6 +3272,44 @@ A table of route points.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).TaskRouteToVec2" >
|
||||
<strong>CONTROLLABLE:TaskRouteToVec2(Vec2, Speed, Formation)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>(GROUND) Route the controllable to a given Vec2.</p>
|
||||
|
||||
|
||||
<p>A speed can be given in km/h.
|
||||
A given formation can be given.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="##(Vec2)">#Vec2</a> Vec2 </em></code>:
|
||||
The Vec2 where to route to.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#number Speed </em></code>:
|
||||
The speed.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Base.html##(FORMATION)">Base#FORMATION</a> Formation </em></code>:
|
||||
The formation string.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(CONTROLLABLE).TaskRouteToZone" >
|
||||
<strong>CONTROLLABLE:TaskRouteToZone(Zone, Randomize, Speed, Formation)</strong>
|
||||
</a>
|
||||
@@ -3062,6 +3350,20 @@ The formation string.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CONTROLLABLE).TaskScheduler" >
|
||||
<strong>CONTROLLABLE.TaskScheduler</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -3174,20 +3476,6 @@ The waypoint function to be called when the controllable moves over the waypoint
|
||||
<p><em><a href="##(CONTROLLABLE)">#CONTROLLABLE</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(CONTROLLABLE).WayPointFunctions" >
|
||||
<strong>CONTROLLABLE.WayPointFunctions</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@@ -3259,6 +3547,37 @@ If WayPoints is given, then use the route.</p>
|
||||
|
||||
<h2><a id="#(DCSStopCondition)" >Type <code>DCSStopCondition</code></a></h2>
|
||||
|
||||
<h2><a id="#(Vec2)" >Type <code>Vec2</code></a></h2>
|
||||
<h3>Field(s)</h3>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(Vec2).x" >
|
||||
<strong>Vec2.x</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(Vec2).y" >
|
||||
<strong>Vec2.y</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2><a id="#(list)" >Type <code>list</code></a></h2>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
@@ -17,6 +17,11 @@
|
||||
<a href="index.html">index</a>
|
||||
</li></ul>
|
||||
<ul>
|
||||
<li><a href="AI_A2A.html">AI_A2A</a></li>
|
||||
<li><a href="AI_A2A_Cap.html">AI_A2A_Cap</a></li>
|
||||
<li><a href="AI_A2A_Dispatcher.html">AI_A2A_Dispatcher</a></li>
|
||||
<li><a href="AI_A2A_GCI.html">AI_A2A_GCI</a></li>
|
||||
<li><a href="AI_A2A_Patrol.html">AI_A2A_Patrol</a></li>
|
||||
<li><a href="AI_Bai.html">AI_Bai</a></li>
|
||||
<li><a href="AI_Balancer.html">AI_Balancer</a></li>
|
||||
<li><a href="AI_Cap.html">AI_Cap</a></li>
|
||||
@@ -75,6 +80,7 @@
|
||||
<li><a href="Scoring.html">Scoring</a></li>
|
||||
<li><a href="Sead.html">Sead</a></li>
|
||||
<li><a href="Set.html">Set</a></li>
|
||||
<li><a href="Settings.html">Settings</a></li>
|
||||
<li><a href="Smoke.html">Smoke</a></li>
|
||||
<li><a href="Spawn.html">Spawn</a></li>
|
||||
<li><a href="SpawnStatic.html">SpawnStatic</a></li>
|
||||
@@ -82,6 +88,8 @@
|
||||
<li><a href="Static.html">Static</a></li>
|
||||
<li><a href="StaticObject.html">StaticObject</a></li>
|
||||
<li><a href="Task.html">Task</a></li>
|
||||
<li><a href="Task_A2A.html">Task_A2A</a></li>
|
||||
<li><a href="Task_A2A_Dispatcher.html">Task_A2A_Dispatcher</a></li>
|
||||
<li><a href="Task_A2G.html">Task_A2G</a></li>
|
||||
<li><a href="Task_A2G_Dispatcher.html">Task_A2G_Dispatcher</a></li>
|
||||
<li><a href="Task_Cargo.html">Task_Cargo</a></li>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user