From 91d0507b4d3a457dae52aa89d842b7cb178e4d50 Mon Sep 17 00:00:00 2001 From: Sven Van de Velde Date: Sun, 21 Aug 2016 14:22:05 +0200 Subject: [PATCH] Progress AI_PATROLZONE --- Moose Development/Moose/AI_PatrolZone.lua | 159 ++++++++---------- Moose Development/Moose/StateMachine.lua | 51 +++++- .../MOOSE_Test_PATROLZONE.miz | Bin 19558 -> 19600 bytes .../Moose_Test_PATROLZONE.lua | 14 +- 4 files changed, 127 insertions(+), 97 deletions(-) diff --git a/Moose Development/Moose/AI_PatrolZone.lua b/Moose Development/Moose/AI_PatrolZone.lua index af0a6d8d7..783e61032 100644 --- a/Moose Development/Moose/AI_PatrolZone.lua +++ b/Moose Development/Moose/AI_PatrolZone.lua @@ -4,7 +4,7 @@ -- -- 1) @{#AI_PATROLZONE} class, extends @{StateMachine#STATEMACHINE} -- ================================================================ --- The @{#AI_PATROLZONE} class implements the core functions to patrol a @{Zone} by an AIR @{Group}. +-- The @{#AI_PATROLZONE} class implements the core functions to patrol a @{Zone} by an AIR @{Controllable}. -- The patrol algorithm works that for each airplane patrolling, upon arrival at the patrol zone, -- a random point is selected as the route point within the 3D space, within the given boundary limits. -- The airplane will fly towards the random 3D point within the patrol zone, using a random speed within the given altitude and speed limits. @@ -19,22 +19,22 @@ -- -- 1.2) AI\_PATROLZONE state machine: -- ---------------------------------- --- The AI\_PATROLZONE is a state machine: it manages the different events and states of the AIGroup it is controlling. +-- The AI\_PATROLZONE is a state machine: it manages the different events and states of the AIControllable it is controlling. -- -- ### 1.2.1) AI\_PATROLZONE Events: -- --- * @{#AI_PATROLZONE.Route}( AIGroup ): A new 3D route point is selected and the AIGroup will fly towards that point with the given speed. --- * @{#AI_PATROLZONE.Patrol}( AIGroup ): The AIGroup reports it is patrolling. This event is called every 30 seconds. --- * @{#AI_PATROLZONE.RTB}( AIGroup ): The AIGroup will report return to base. --- * @{#AI_PATROLZONE.End}( AIGroup ): The end of the AI\_PATROLZONE process. --- * @{#AI_PATROLZONE.Dead}( AIGroup ): The AIGroup is dead. The AI\_PATROLZONE process will be ended. +-- * @{#AI_PATROLZONE.Route}( AIControllable ): A new 3D route point is selected and the AIControllable will fly towards that point with the given speed. +-- * @{#AI_PATROLZONE.Patrol}( AIControllable ): The AIControllable reports it is patrolling. This event is called every 30 seconds. +-- * @{#AI_PATROLZONE.RTB}( AIControllable ): The AIControllable will report return to base. +-- * @{#AI_PATROLZONE.End}( AIControllable ): The end of the AI\_PATROLZONE process. +-- * @{#AI_PATROLZONE.Dead}( AIControllable ): The AIControllable is dead. The AI\_PATROLZONE process will be ended. -- -- ### 1.2.2) AI\_PATROLZONE States: -- --- * **Route**: A new 3D route point is selected and the AIGroup will fly towards that point with the given speed. --- * **Patrol**: The AIGroup is patrolling. This state is set every 30 seconds, so every 30 seconds, a state transition function can be used. --- * **RTB**: The AIGroup reports it wants to return to the base. --- * **Dead**: The AIGroup is dead ... +-- * **Route**: A new 3D route point is selected and the AIControllable will fly towards that point with the given speed. +-- * **Patrol**: The AIControllable is patrolling. This state is set every 30 seconds, so every 30 seconds, a state transition function can be used. +-- * **RTB**: The AIControllable reports it wants to return to the base. +-- * **Dead**: The AIControllable is dead ... -- * **End**: The process has come to an end. -- -- ### 1.2.3) AI\_PATROLZONE state transition functions: @@ -45,8 +45,8 @@ -- * **Before** the state transition. -- The state transition function needs to start with the name **OnBefore + the name of the state**. -- If the state transition function returns false, then the processing of the state transition will not be done! --- If you want to change the behaviour of the AIGroup at this event, return false, --- but then you'll need to specify your own logic using the AIGroup! +-- If you want to change the behaviour of the AIControllable at this event, return false, +-- but then you'll need to specify your own logic using the AIControllable! -- -- * **After** the state transition. -- The state transition function needs to start with the name **OnAfter + the name of the state**. @@ -61,14 +61,14 @@ -- local PatrolGroup = PatrolSpawn:Spawn() -- -- local Patrol = AI_PATROLZONE:New( PatrolZone, 3000, 6000, 300, 600 ) --- Patrol:AddGroup( PatrolGroup ) +-- Patrol:SetControllable( PatrolGroup ) -- Patrol:ManageFuel( 0.2, 60 ) -- -- **OnBefore**RTB( AIGroup ) will be called by the AI\_PATROLZONE object when the AIGroup reports RTB, but **before** the RTB default action is processed by the AI_PATROLZONE object. -- -- --- State transition function for the AI\_PATROLZONE **Patrol** object -- -- @param #AI_PATROLZONE self --- -- @param Group#GROUP AIGroup +-- -- @param Controllable#CONTROLLABLE AIGroup -- -- @return #boolean If false is returned, then the OnAfter state transition function will not be called. -- function Patrol:OnBeforeRTB( AIGroup ) -- AIGroup:MessageToRed( "Returning to base", 20 ) @@ -78,26 +78,27 @@ -- -- --- State transition function for the AI\_PATROLZONE **Patrol** object -- -- @param #AI_PATROLZONE self --- -- @param Group#GROUP AIGroup --- -- @return #Group#GROUP The new AIGroup object that is set to be patrolling the zone. +-- -- @param Controllable#CONTROLLABLE AIGroup +-- -- @return #Controllable#CONTROLLABLE The new AIGroup object that is set to be patrolling the zone. -- function Patrol:OnAfterRTB( AIGroup ) -- return PatrolSpawn:Spawn() -- end -- --- 1.3) Modify the AI\_PATROLZONE parameters: --- -------------------------------------- +-- 1.3) Manage the AI\_PATROLZONE parameters: +-- ------------------------------------------ -- The following methods are available to modify the parameters of a AI\_PATROLZONE object: -- --- * @{#AI_PATROLZONE.SetGroup}(): Set the AI Patrol Group. +-- * @{#AI_PATROLZONE.SetControllable}(): Set the AIControllable. +-- * @{#AI_PATROLZONE.GetControllable}(): Get the AIControllable. -- * @{#AI_PATROLZONE.SetSpeed}(): Set the patrol speed of the AI, for the next patrol. -- * @{#AI_PATROLZONE.SetAltitude}(): Set altitude of the AI, for the next patrol. -- -- 1.3) Manage the out of fuel in the AI\_PATROLZONE: -- ---------------------------------------------- --- When the PatrolGroup is out of fuel, it is required that a new PatrolGroup is started, before the old PatrolGroup can return to the home base. +-- When the AIControllable is out of fuel, it is required that a new AIControllable is started, before the old AIControllable 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 PatrolGroup will continue for a given time its patrol task in orbit, while a new PatrolGroup is targetted to the AI\_PATROLZONE. --- Once the time is finished, the old PatrolGroup will return to the base. +-- When the fuel treshold is reached, the AIControllable will continue for a given time its patrol task in orbit, while a new AIControllable is targetted to the AI\_PATROLZONE. +-- Once the time is finished, the old AIControllable will return to the base. -- Use the method @{#AI_PATROLZONE.ManageFuel}() to have this proces in place. -- -- ==== @@ -124,10 +125,11 @@ -- ### Contributions: -- -- * **DutchBaron**: Testing. +-- * **Pikey**: Testing and API concept review. -- -- ### Authors: -- --- * **FlightControl**: Design & Programming +-- * **FlightControl**: Design & Programming. -- -- -- @module AI_PatrolZone @@ -136,13 +138,13 @@ --- AI\_PATROLZONE class -- @type AI_PATROLZONE --- @field Group#GROUP PatrolGroup The @{Group} patrolling. +-- @field Controllable#CONTROLLABLE AIControllable The @{Controllable} patrolling. -- @field Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed. -- @field DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol. -- @field DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol. --- @field DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h. --- @field DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h. --- @extends StateMachine#StateMachine +-- @field DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h. +-- @field DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h. +-- @extends StateMachine#STATEMACHINE_CONTROLLABLE AI_PATROLZONE = { ClassName = "AI_PATROLZONE", } @@ -154,11 +156,11 @@ AI_PATROLZONE = { -- @param Zone#ZONE_BASE PatrolZone The @{Zone} where the patrol needs to be executed. -- @param DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol. -- @param DCSTypes#Altitude PatrolCeilingAltitude The highest altitude in meters where to execute the patrol. --- @param DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h. --- @param DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h. +-- @param DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h. +-- @param DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h. -- @return #AI_PATROLZONE self -- @usage --- -- Define a new AI_PATROLZONE Object. This PatrolArea will patrol a group within PatrolZone between 3000 and 6000 meters, with a variying speed between 600 and 900 km/h. +-- -- Define a new AI_PATROLZONE 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_PATROLZONE:New( PatrolZone, 3000, 6000, 600, 900 ) @@ -174,16 +176,10 @@ function AI_PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitu { name = 'End', from = '*', to = 'End' }, { name = 'Dead', from = '*', to = 'End' }, }, - callbacks = { - onenterRoute = self._EnterRoute, - onenterPatrol = self._EnterPatrol, - onenterRTB = self._EnterRTB, - onenterEnd = self._EnterEnd, - }, } -- Inherits from BASE - local self = BASE:Inherit( self, STATEMACHINE:New( FSMT ) ) + local self = BASE:Inherit( self, STATEMACHINE_CONTROLLABLE:New( FSMT ) ) self.PatrolZone = PatrolZone self.PatrolFloorAltitude = PatrolFloorAltitude @@ -196,24 +192,11 @@ end ---- Set the @{Group} to act as the Patroller. --- @param #AI_PATROLZONE self --- @param Group#GROUP PatrolGroup The @{Group} patrolling. --- @return #AI_PATROLZONE self -function AI_PATROLZONE:SetGroup( PatrolGroup ) - - self.PatrolGroup = PatrolGroup - self.PatrolGroupTemplateName = PatrolGroup:GetName() - - return self -end - - --- Sets (modifies) the minimum and maximum speed of the patrol. -- @param #AI_PATROLZONE self --- @param DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h. --- @param DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Group} in km/h. +-- @param DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Controllable} in km/h. +-- @param DCSTypes#Speed PatrolMaxSpeed The maximum speed of the @{Controllable} in km/h. -- @return #AI_PATROLZONE self function AI_PATROLZONE:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed ) self:F2( { PatrolMinSpeed, PatrolMaxSpeed } ) @@ -238,24 +221,24 @@ end ---- @param Group#GROUP PatrolGroup -function _NewPatrolRoute( PatrolGroup ) +--- @param Controllable#CONTROLLABLE AIControllable +function _NewPatrolRoute( AIControllable ) - PatrolGroup:T( "NewPatrolRoute" ) - local PatrolZone = PatrolGroup:GetState( PatrolGroup, "PatrolZone" ) -- PatrolZone#AI_PATROLZONE - PatrolZone:__Route( 1, PatrolGroup ) + AIControllable:T( "NewPatrolRoute" ) + local PatrolZone = AIControllable:GetState( AIControllable, "PatrolZone" ) -- PatrolZone#AI_PATROLZONE + PatrolZone:__Route( 1 ) end ---- When the PatrolGroup is out of fuel, it is required that a new PatrolGroup is started, before the old PatrolGroup can return to the home base. +--- When the AIControllable is out of fuel, it is required that a new AIControllable is started, before the old AIControllable 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 PatrolGroup will continue for a given time its patrol task in orbit, while a new PatrolGroup is targetted to the AI\_PATROLZONE. --- Once the time is finished, the old PatrolGroup will return to the base. +-- When the fuel treshold is reached, the AIControllable will continue for a given time its patrol task in orbit, while a new AIControllable is targetted to the AI\_PATROLZONE. +-- Once the time is finished, the old AIControllable will return to the base. -- @param #AI_PATROLZONE self --- @param #number PatrolFuelTresholdPercentage The treshold in percentage (between 0 and 1) when the PatrolGroup is considered to get out of fuel. --- @param #number PatrolOutOfFuelOrbitTime The amount of seconds the out of fuel PatrolGroup will orbit before returning to the base. +-- @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_PATROLZONE self function AI_PATROLZONE:ManageFuel( PatrolFuelTresholdPercentage, PatrolOutOfFuelOrbitTime ) @@ -266,22 +249,22 @@ function AI_PATROLZONE:ManageFuel( PatrolFuelTresholdPercentage, PatrolOutOfFuel return self end ---- Defines a new patrol route using the @{PatrolZone} parameters and settings. +--- Defines a new patrol route using the @{AI_PatrolZone} parameters and settings. -- @param #AI_PATROLZONE self -- @return #AI_PATROLZONE self -function AI_PATROLZONE:_EnterRoute( AIGroup ) +function AI_PATROLZONE:onenterRoute() self:F2() local PatrolRoute = {} - if self.PatrolGroup:IsAlive() then - --- Determine if the PatrolGroup is within the PatrolZone. - -- If not, make a waypoint within the to that the PatrolGroup will fly at maximum speed to that point. + if self.Controllable:IsAlive() then + --- Determine if the AIControllable is within the PatrolZone. + -- If not, make a waypoint within the to that the AIControllable will fly at maximum speed to that point. -- --- Calculate the current route point. --- local CurrentVec2 = self.PatrolGroup:GetVec2() --- local CurrentAltitude = self.PatrolGroup:GetUnit(1):GetAltitude() +-- local CurrentVec2 = self.Controllable:GetVec2() +-- local CurrentAltitude = self.Controllable:GetUnit(1):GetAltitude() -- local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y ) -- local CurrentRoutePoint = CurrentPointVec3:RoutePointAir( -- POINT_VEC3.RoutePointAltType.BARO, @@ -295,7 +278,7 @@ function AI_PATROLZONE:_EnterRoute( AIGroup ) self:T2( PatrolRoute ) - if self.PatrolGroup:IsNotInZone( self.PatrolZone ) then + if self.Controllable:IsNotInZone( self.PatrolZone ) then --- Find a random 2D point in PatrolZone. local ToPatrolZoneVec2 = self.PatrolZone:GetRandomVec2() self:T2( ToPatrolZoneVec2 ) @@ -348,40 +331,40 @@ function AI_PATROLZONE:_EnterRoute( AIGroup ) PatrolRoute[#PatrolRoute+1] = ToTargetRoutePoint - --- Now we're going to do something special, we're going to call a function from a waypoint action at the PatrolGroup... - self.PatrolGroup:WayPointInitialize( PatrolRoute ) + --- 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( PatrolRoute ) - --- Do a trick, link the NewPatrolRoute function of the PATROLGROUP object to the PatrolGroup in a temporary variable ... - self.PatrolGroup:SetState( self.PatrolGroup, "PatrolZone", self ) - self.PatrolGroup:WayPointFunction( #PatrolRoute, 1, "_NewPatrolRoute" ) + --- Do a trick, link the NewPatrolRoute function of the PATROLGROUP object to the AIControllable in a temporary variable ... + self.Controllable:SetState( self.Controllable, "PatrolZone", self ) + self.Controllable:WayPointFunction( #PatrolRoute, 1, "_NewPatrolRoute" ) --- NOW ROUTE THE GROUP! - self.PatrolGroup:WayPointExecute( 1 ) + self.Controllable:WayPointExecute( 1 ) - self:__Patrol( 30, self.PatrolGroup ) + self:__Patrol( 30 ) end end --- @param #AI_PATROLZONE self -function AI_PATROLZONE:_EnterPatrol( AIGroup ) +function AI_PATROLZONE:onenterPatrol() self:F2() - if self.PatrolGroup and self.PatrolGroup:IsAlive() then + if self.Controllable and self.Controllable:IsAlive() then - local Fuel = self.PatrolGroup:GetUnit(1):GetFuel() + local Fuel = self.Controllable:GetUnit(1):GetFuel() if Fuel < self.PatrolFuelTresholdPercentage then - local OldPatrolGroup = self.PatrolGroup - local PatrolGroupTemplate = self.PatrolGroup:GetTemplate() + local OldAIControllable = self.Controllable + local AIControllableTemplate = self.Controllable:GetTemplate() - local OrbitTask = OldPatrolGroup:TaskOrbitCircle( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ), self.PatrolMinSpeed ) - local TimedOrbitTask = OldPatrolGroup:TaskControlled( OrbitTask, OldPatrolGroup:TaskCondition(nil,nil,nil,nil,self.PatrolOutOfFuelOrbitTime,nil ) ) - OldPatrolGroup:SetTask( TimedOrbitTask, 10 ) + 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:RTB( self.PatrolGroup ) + self:RTB() else - self:__Patrol( 30, self.PatrolGroup ) -- Execute the Patrol event after 30 seconds. + self:__Patrol( 30 ) -- Execute the Patrol event after 30 seconds. end end diff --git a/Moose Development/Moose/StateMachine.lua b/Moose Development/Moose/StateMachine.lua index 86554f653..e6f3e6bd1 100644 --- a/Moose Development/Moose/StateMachine.lua +++ b/Moose Development/Moose/StateMachine.lua @@ -95,7 +95,7 @@ end function STATEMACHINE:_call_handler(handler, params) if handler then - return handler(unpack(params)) + return handler( self, unpack(params) ) end end @@ -110,7 +110,7 @@ function STATEMACHINE._handler( self, EventName, ... ) if can then local from = self.current - local params = { self, ..., EventName, from, to } + local params = { ..., EventName, from, to } if self:_call_handler(self["onbefore" .. EventName], params) == false or self:_call_handler(self["onleave" .. from], params) == false then @@ -317,3 +317,50 @@ function STATEMACHINE_TASK:_call_handler( handler, params ) return handler( self.Task, self.TaskUnit, unpack( params ) ) end end + +--- STATEMACHINE_CONTROLLABLE class +-- @type STATEMACHINE_CONTROLLABLE +-- @field Controllable#CONTROLLABLE Controllable +-- @extends StateMachine#STATEMACHINE +STATEMACHINE_CONTROLLABLE = { + ClassName = "STATEMACHINE_CONTROLLABLE", +} + +--- Creates a new STATEMACHINE_CONTROLLABLE object. +-- @param #STATEMACHINE_CONTROLLABLE self +-- @param #table FSMT Finite State Machine Table +-- @param Controllable#CONTROLLABLE Controllable (optional) The CONTROLLABLE object that the STATEMACHINE_CONTROLLABLE governs. +-- @return #STATEMACHINE_CONTROLLABLE +function STATEMACHINE_CONTROLLABLE:New( FSMT, Controllable ) + + -- Inherits from BASE + local self = BASE:Inherit( self, STATEMACHINE:New( FSMT ) ) -- StateMachine#STATEMACHINE_CONTROLLABLE + + if Controllable then + self:SetControllable( Controllable ) + end + + return self +end + +--- Sets the CONTROLLABLE object that the STATEMACHINE_CONTROLLABLE governs. +-- @param #STATEMACHINE_CONTROLLABLE self +-- @param Controllable#CONTROLLABLE Controllable +-- @return #STATEMACHINE_CONTROLLABLE +function STATEMACHINE_CONTROLLABLE:SetControllable( FSMControllable ) + self:F( FSMControllable ) + self.Controllable = FSMControllable +end + +--- Gets the CONTROLLABLE object that the STATEMACHINE_CONTROLLABLE governs. +-- @param #STATEMACHINE_CONTROLLABLE self +-- @return Controllable#CONTROLLABLE +function STATEMACHINE_CONTROLLABLE:GetControllable() + return self.Controllable +end + +function STATEMACHINE_CONTROLLABLE:_call_handler( handler, params ) + if handler then + return handler( self, self.Controllable, unpack( params ) ) + end +end \ No newline at end of file diff --git a/Moose Test Missions/Moose_Test_PATROLZONE/MOOSE_Test_PATROLZONE.miz b/Moose Test Missions/Moose_Test_PATROLZONE/MOOSE_Test_PATROLZONE.miz index 2dcbb97d3ec3b526397deae448e0778d2023aea4..ec8e9012aad6b3f440a05a0171a765252394ca92 100644 GIT binary patch delta 6097 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 Vijz1@Gy%htZA={oZ%F_E0062{r9uDz diff --git a/Moose Test Missions/Moose_Test_PATROLZONE/Moose_Test_PATROLZONE.lua b/Moose Test Missions/Moose_Test_PATROLZONE/Moose_Test_PATROLZONE.lua index 82d76170f..ba93d7f1e 100644 --- a/Moose Test Missions/Moose_Test_PATROLZONE/Moose_Test_PATROLZONE.lua +++ b/Moose Test Missions/Moose_Test_PATROLZONE/Moose_Test_PATROLZONE.lua @@ -1,7 +1,7 @@ -- This test mission models the behaviour of the AI_PATROLZONE class. -- -- It creates a 2 AI_PATROLZONE objects with the name Patrol1 and Patrol2. --- Patrol1 will goven a GROUP object to patrol the zone defined by PatrolZone1, within 3000 meters and 6000 meters, within a speed of 400 and 600 km/h. +-- Patrol1 will govern a GROUP object to patrol the zone defined by PatrolZone1, within 3000 meters and 6000 meters, within a speed of 400 and 600 km/h. -- When the GROUP object that is assigned to Patrol has fuel below 20%, the GROUP object will orbit for 60 secondes, before returning to base. -- -- Patrol2 will goven a GROUP object to patrol the zone defined by PatrolZone2, within 600 meters and 1000 meters, within a speed of 300 and 400 km/h. @@ -25,8 +25,8 @@ local PatrolGroup = PatrolSpawn:Spawn() local Patrol1 = AI_PATROLZONE:New( PatrolZone1, 3000, 6000, 400, 600 ) Patrol1:ManageFuel( 0.2, 60 ) -Patrol1:SetGroup( PatrolGroup ) -Patrol1:__Start( 1, PatrolGroup ) +Patrol1:SetControllable( PatrolGroup ) +Patrol1:__Start( 5 ) local Patrol2 = AI_PATROLZONE:New( PatrolZone2, 600, 1000, 300, 400 ) Patrol2:ManageFuel( 0.2, 0 ) @@ -44,8 +44,8 @@ end -- @param Group#GROUP AIGroup function Patrol1:OnAfterRTB( AIGroup ) local NewGroup = PatrolSpawn:Spawn() - Patrol2:SetGroup( NewGroup ) - Patrol2:__Start( 1, NewGroup ) + Patrol2:SetControllable( NewGroup ) + Patrol2:__Start( 1 ) end --- State transition function for the AI\_PATROLZONE **Patrol1** object @@ -68,8 +68,8 @@ end -- @param Group#GROUP AIGroup function Patrol2:OnAfterRTB( AIGroup ) local NewGroup = PatrolSpawn:Spawn() - Patrol1:SetGroup( NewGroup ) - Patrol1:__Start( 1, NewGroup ) + Patrol1:SetControllable( NewGroup ) + Patrol1:__Start( 1 ) end --- State transition function for the AI\_PATROLZONE **Patrol2** object