mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Compare commits
266 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 | ||
|
|
72ccd7c6ea | ||
|
|
e23fd20d69 | ||
|
|
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 | ||
|
|
e2a0aa5573 | ||
|
|
a932f49554 | ||
|
|
a57e24212e | ||
|
|
312007b51c | ||
|
|
3106f62709 | ||
|
|
48595e1282 | ||
|
|
0d2e398e37 | ||
|
|
9abc4f9725 | ||
|
|
cc064c95b1 | ||
|
|
4b62fbd497 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -221,4 +221,3 @@ _gsdata_/
|
||||
.gitattributes
|
||||
.gitignore
|
||||
Moose Test Missions/MOOSE_Test_Template.miz
|
||||
Moose.lua
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1192,7 +1317,7 @@ do -- DETECTION_BASE
|
||||
end
|
||||
|
||||
DetectedItem.Set = Set or SET_UNIT:New():FilterDeads():FilterCrashes()
|
||||
DetectedItem.Index = DetectedItemIndex
|
||||
DetectedItem.Index = DetectedItemIndex or self.DetectedItemCount
|
||||
DetectedItem.ItemID = ItemPrefix .. "." .. self.DetectedItemMax
|
||||
DetectedItem.ID = self.DetectedItemMax
|
||||
DetectedItem.Removed = false
|
||||
@@ -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
@@ -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 ..
|
||||
@@ -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>
|
||||
|
||||
@@ -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