Progress on the AI_PATROLZONE!!! Working test mission!!!

This commit is contained in:
Sven Van de Velde 2016-08-21 10:56:56 +02:00
parent 3861362ed9
commit a800531ea0
89 changed files with 2115 additions and 55817 deletions

View File

@ -3,9 +3,10 @@
-- ===
--
-- 1) @{AIBalancer#AIBALANCER} class, extends @{Base#BASE}
-- ================================================
-- =======================================================
-- The @{AIBalancer#AIBALANCER} class controls the dynamic spawning of AI GROUPS depending on a SET_CLIENT.
-- There will be as many AI GROUPS spawned as there at CLIENTS in SET_CLIENT not spawned.
-- The AIBalancer uses the @{PatrolZone#PATROLZONE} class to make AI patrol an zone until the fuel treshold is reached.
--
-- 1.1) AIBALANCER construction method:
-- ------------------------------------
@ -26,22 +27,44 @@
--
-- ===
--
-- **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:
--
-- 2016-08-17: SPAWN:**InitCleanUp**( SpawnCleanUpInterval ) replaces SPAWN:_CleanUp_( SpawnCleanUpInterval )
--
-- * Want to ensure that the methods starting with **Init** are the first called methods before any _Spawn_ method is called!
-- * This notation makes it now more clear which methods are initialization methods and which methods are Spawn enablement methods.
--
-- ===
--
-- AUTHORS and CONTRIBUTIONS
-- =========================
--
-- ### Contributions:
--
-- * **Dutch_Baron (James)** Who you can search on the Eagle Dynamics Forums.
-- * **Dutch_Baron (James)**: Who you can search on the Eagle Dynamics Forums.
-- Working together with James has resulted in the creation of the AIBALANCER 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**
-- * **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 AIBALANCER moose class.
--
-- ### Authors:
--
-- * FlightControl - Framework Design & Programming
-- * FlightControl: Framework Design & Programming
--
-- @module AIBalancer
--- AIBALANCER class
-- @type AIBALANCER
-- @field Set#SET_CLIENT SetClient
@ -122,11 +145,28 @@ end
-- @param #AIBALANCER self
-- @param PatrolZone#PATROLZONE PatrolZone The @{PatrolZone} where the AI needs to patrol.
-- @return PatrolZone#PATROLZONE self
function AIBALANCER:SetPatrolZone( PatrolZone )
function AIBALANCER:SetPatrolZone( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
self.PatrolZone = PatrolZone
self.PatrolZone = PATROLZONE:New(
self.SpawnAI,
PatrolZone,
PatrolFloorAltitude,
PatrolCeilingAltitude,
PatrolMinSpeed,
PatrolMaxSpeed
)
end
--- Get the @{PatrolZone} object assigned by the @{AIBalancer} object.
-- @param #AIBALANCER self
-- @return PatrolZone#PATROLZONE PatrolZone The @{PatrolZone} where the AI needs to patrol.
function AIBALANCER:GetPatrolZone()
return self.PatrolZone
end
--- @param #AIBALANCER self
function AIBALANCER:_ClientAliveMonitorScheduler()

View File

@ -0,0 +1,388 @@
--- This module contains the AI\_PATROLZONE class.
--
-- ===
--
-- 1) @{#AI_PATROLZONE} class, extends @{StateMachine#STATEMACHINE}
-- ================================================================
-- The @{#AI_PATROLZONE} class implements the core functions to patrol a @{Zone} by an AIR @{Group}.
-- 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.
-- Upon arrival at the random 3D point, a new 3D random point will be selected within the patrol zone using the given limits.
-- This cycle will continue until a fuel treshold has been reached by the airplane.
-- When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.
--
-- 1.1) AI\_PATROLZONE constructor:
-- ----------------------------
--
-- * @{#AI_PATROLZONE.New}(): Creates a new AI\_PATROLZONE object.
--
-- 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.
--
-- ### 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.
--
-- ### 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 ...
-- * **End**: The process has come to an end.
--
-- ### 1.2.3) AI\_PATROLZONE state transition functions:
--
-- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state.
-- There are 2 moments when state transition functions will be called by the state machine:
--
-- * **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!
--
-- * **After** the state transition.
-- The state transition function needs to start with the name **OnAfter + the name of the state**.
-- These state transition functions need to provide a return value, which is specified at the function description.
--
-- An example how to manage a state transition for an AI\_PATROLZONE object **Patrol** for the state **RTB**:
--
-- local PatrolZoneGroup = GROUP:FindByName( "Patrol Zone" )
-- local PatrolZone = ZONE_POLYGON:New( "PatrolZone", PatrolZoneGroup )
--
-- local PatrolSpawn = SPAWN:New( "Patrol Group" )
-- local PatrolGroup = PatrolSpawn:Spawn()
--
-- local Patrol = AI_PATROLZONE:New( PatrolZone, 3000, 6000, 300, 600 )
-- Patrol:AddGroup( 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
-- -- @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 )
-- end
--
-- **OnAfter**RTB( AIGroup ) will be called by the AI\_PATROLZONE object when the AIGroup reports RTB, but **after** the RTB default action was processed by the AI_PATROLZONE object.
--
-- --- 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.
-- function Patrol:OnAfterRTB( AIGroup )
-- return PatrolSpawn:Spawn()
-- end
--
-- 1.3) Modify 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.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.
-- 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.
-- Use the method @{#AI_PATROLZONE.ManageFuel}() to have this proces in place.
--
-- ====
--
-- **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:
--
-- 2016-08-17: AI\_PATROLZONE:New( **PatrolSpawn,** PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed ) replaces AI\_PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
--
-- 2016-07-01: Initial class and API.
--
-- ===
--
-- AUTHORS and CONTRIBUTIONS
-- =========================
--
-- ### Contributions:
--
-- * **DutchBaron**: Testing.
--
-- ### Authors:
--
-- * **FlightControl**: Design & Programming
--
--
-- @module AI_PatrolZone
--- AI\_PATROLZONE class
-- @type AI_PATROLZONE
-- @field Group#GROUP PatrolGroup The @{Group} 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
AI_PATROLZONE = {
ClassName = "AI_PATROLZONE",
}
--- Creates a new AI\_PATROLZONE object
-- @param #AI_PATROLZONE self
-- @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.
-- @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.
-- PatrolZone = ZONE:New( 'PatrolZone' )
-- PatrolSpawn = SPAWN:New( 'Patrol Group' )
-- PatrolArea = AI_PATROLZONE:New( PatrolZone, 3000, 6000, 600, 900 )
function AI_PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
local FSMT = {
initial = 'None',
events = {
{ name = 'Start', from = '*', to = 'Route' },
{ name = 'Route', from = '*', to = 'Route' },
{ name = 'Patrol', from = { 'Patrol', 'Route' }, to = 'Patrol' },
{ name = 'RTB', from = 'Patrol', to = 'RTB' },
{ 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 ) )
self.PatrolZone = PatrolZone
self.PatrolFloorAltitude = PatrolFloorAltitude
self.PatrolCeilingAltitude = PatrolCeilingAltitude
self.PatrolMinSpeed = PatrolMinSpeed
self.PatrolMaxSpeed = PatrolMaxSpeed
return self
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.
-- @return #AI_PATROLZONE self
function AI_PATROLZONE: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_PATROLZONE self
-- @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.
-- @return #AI_PATROLZONE self
function AI_PATROLZONE:SetAltitude( PatrolFloorAltitude, PatrolCeilingAltitude )
self:F2( { PatrolFloorAltitude, PatrolCeilingAltitude } )
self.PatrolFloorAltitude = PatrolFloorAltitude
self.PatrolCeilingAltitude = PatrolCeilingAltitude
end
--- @param Group#GROUP PatrolGroup
function _NewPatrolRoute( PatrolGroup )
PatrolGroup:T( "NewPatrolRoute" )
local PatrolZone = PatrolGroup:GetState( PatrolGroup, "PatrolZone" ) -- PatrolZone#AI_PATROLZONE
PatrolZone:__Route( 1, PatrolGroup )
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.
-- 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.
-- @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.
-- @return #AI_PATROLZONE self
function AI_PATROLZONE:ManageFuel( PatrolFuelTresholdPercentage, PatrolOutOfFuelOrbitTime )
self.PatrolManageFuel = true
self.PatrolFuelTresholdPercentage = PatrolFuelTresholdPercentage
self.PatrolOutOfFuelOrbitTime = PatrolOutOfFuelOrbitTime
return self
end
--- Defines a new patrol route using the @{PatrolZone} parameters and settings.
-- @param #AI_PATROLZONE self
-- @return #AI_PATROLZONE self
function AI_PATROLZONE:_EnterRoute( AIGroup )
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.
-- --- Calculate the current route point.
-- local CurrentVec2 = self.PatrolGroup:GetVec2()
-- local CurrentAltitude = self.PatrolGroup:GetUnit(1):GetAltitude()
-- local CurrentPointVec3 = POINT_VEC3:New( CurrentVec2.x, CurrentAltitude, CurrentVec2.y )
-- local CurrentRoutePoint = CurrentPointVec3:RoutePointAir(
-- POINT_VEC3.RoutePointAltType.BARO,
-- POINT_VEC3.RoutePointType.TurningPoint,
-- POINT_VEC3.RoutePointAction.TurningPoint,
-- ToPatrolZoneSpeed,
-- true
-- )
--
-- PatrolRoute[#PatrolRoute+1] = CurrentRoutePoint
self:T2( PatrolRoute )
if self.PatrolGroup:IsNotInZone( self.PatrolZone ) then
--- Find a random 2D point in PatrolZone.
local ToPatrolZoneVec2 = self.PatrolZone:GetRandomVec2()
self:T2( ToPatrolZoneVec2 )
--- Define Speed and Altitude.
local ToPatrolZoneAltitude = math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude )
local ToPatrolZoneSpeed = self.PatrolMaxSpeed
self:T2( ToPatrolZoneSpeed )
--- Obtain a 3D @{Point} from the 2D point + altitude.
local ToPatrolZonePointVec3 = POINT_VEC3:New( ToPatrolZoneVec2.x, ToPatrolZoneAltitude, ToPatrolZoneVec2.y )
--- Create a route point of type air.
local ToPatrolZoneRoutePoint = ToPatrolZonePointVec3:RoutePointAir(
POINT_VEC3.RoutePointAltType.BARO,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
ToPatrolZoneSpeed,
true
)
PatrolRoute[#PatrolRoute+1] = ToPatrolZoneRoutePoint
end
--- Define a random point in the @{Zone}. The AI will fly to that point within the zone.
--- Find a random 2D point in PatrolZone.
local ToTargetVec2 = self.PatrolZone:GetRandomVec2()
self:T2( ToTargetVec2 )
--- Define Speed and Altitude.
local ToTargetAltitude = math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude )
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
self:T2( { self.PatrolMinSpeed, self.PatrolMaxSpeed, ToTargetSpeed } )
--- Obtain a 3D @{Point} from the 2D point + altitude.
local ToTargetPointVec3 = POINT_VEC3:New( ToTargetVec2.x, ToTargetAltitude, ToTargetVec2.y )
--- Create a route point of type air.
local ToTargetRoutePoint = ToTargetPointVec3:RoutePointAir(
POINT_VEC3.RoutePointAltType.BARO,
POINT_VEC3.RoutePointType.TurningPoint,
POINT_VEC3.RoutePointAction.TurningPoint,
ToTargetSpeed,
true
)
--ToTargetPointVec3:SmokeRed()
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 )
--- 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" )
--- NOW ROUTE THE GROUP!
self.PatrolGroup:WayPointExecute( 1 )
self:__Patrol( 30, self.PatrolGroup )
end
end
--- @param #AI_PATROLZONE self
function AI_PATROLZONE:_EnterPatrol( AIGroup )
self:F2()
if self.PatrolGroup and self.PatrolGroup:IsAlive() then
local Fuel = self.PatrolGroup:GetUnit(1):GetFuel()
if Fuel < self.PatrolFuelTresholdPercentage then
local OldPatrolGroup = self.PatrolGroup
local PatrolGroupTemplate = self.PatrolGroup: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 )
self:RTB( self.PatrolGroup )
else
self:__Patrol( 30, self.PatrolGroup ) -- Execute the Patrol event after 30 seconds.
end
end
end

View File

@ -230,9 +230,10 @@ function CONTROLLABLE:SetTask( DCSTask, WaitTime )
-- Controller.setTask( Controller, DCSTask )
if not WaitTime then
WaitTime = 1
Controller:setTask( DCSTask )
else
SCHEDULER:New( Controller, Controller.setTask, { DCSTask }, WaitTime )
end
SCHEDULER:New( Controller, Controller.setTask, { DCSTask }, WaitTime )
return self
end
@ -2152,7 +2153,7 @@ function CONTROLLABLE:TaskFunction( WayPoint, WayPointIndex, FunctionString, Fun
local DCSTask
local DCSScript = {}
DCSScript[#DCSScript+1] = "local MissionControllable = CONTROLLABLE:Find( ... ) "
DCSScript[#DCSScript+1] = "local MissionControllable = GROUP:Find( ... ) "
if FunctionArguments and #FunctionArguments > 0 then
DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable, " .. table.concat( FunctionArguments, "," ) .. ")"

View File

@ -673,19 +673,19 @@ function GROUP:GetMaxVelocity()
local DCSGroup = self:GetDCSObject()
if DCSGroup then
local MaxVelocity = 0
local GroupVelocityMax = 0
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
local Velocity = UnitData:getVelocity()
local VelocityTotal = math.abs( Velocity.x ) + math.abs( Velocity.y ) + math.abs( Velocity.z )
local UnitVelocityVec3 = UnitData:getVelocity()
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
if VelocityTotal < MaxVelocity then
MaxVelocity = VelocityTotal
if UnitVelocity > GroupVelocityMax then
GroupVelocityMax = UnitVelocity
end
end
return MaxVelocity
return GroupVelocityMax
end
return nil

View File

@ -34,8 +34,8 @@ Include.File( "Movement" )
Include.File( "Sead" )
Include.File( "Escort" )
Include.File( "MissileTrainer" )
Include.File( "PatrolZone" )
Include.File( "AIBalancer" )
Include.File( "AI_PatrolZone" )
--Include.File( "AIBalancer" )
Include.File( "AirbasePolice" )
Include.File( "Detection" )

View File

@ -45,6 +45,8 @@
--
-- Hereby the change log:
--
-- 2016-08-17: PATROLZONE:New( **PatrolSpawn,** PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed ) replaces PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
--
-- 2016-07-01: Initial class and API.
--
-- ===
@ -54,16 +56,17 @@
--
-- ### Contributions:
--
-- * DutchBaron: Testing.
-- * **DutchBaron**: Testing.
--
-- ### Authors:
--
-- * FlightControl: Design & Programming
-- * **FlightControl**: Design & Programming
--
--
-- @module PatrolZone
--- PATROLZONE class
-- @type PATROLZONE
-- @field Group#GROUP PatrolGroup The @{Group} patrolling.
@ -77,8 +80,11 @@ PATROLZONE = {
ClassName = "PATROLZONE",
}
--- Creates a new PATROLZONE object, taking a @{Group} object as a parameter. The GROUP needs to be alive.
-- @param #PATROLZONE self
-- @param Spawn#SPAWN PatrolSpawn The @{SPAWN} object to spawn new group objects when required due to the fuel treshold.
-- @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.
@ -88,13 +94,14 @@ PATROLZONE = {
-- @usage
-- -- Define a new 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.
-- PatrolZone = ZONE:New( 'PatrolZone' )
-- PatrolGroup = GROUP:FindByName( "Patrol Group" )
-- PatrolArea = PATROLZONE:New( PatrolGroup, PatrolZone, 3000, 6000, 600, 900 )
function PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
-- PatrolSpawn = SPAWN:New( "Patrol Group" )
-- PatrolArea = PATROLZONE:New( PatrolSpawn, PatrolZone, 3000, 6000, 600, 900 )
function PATROLZONE:New( PatrolSpawn, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
-- Inherits from BASE
local self = BASE:Inherit( self, BASE:New() )
self.PatrolSpawn = PatrolSpawn
self.PatrolZone = PatrolZone
self.PatrolFloorAltitude = PatrolFloorAltitude
self.PatrolCeilingAltitude = PatrolCeilingAltitude
@ -104,6 +111,8 @@ function PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude,
return self
end
--- Set the @{Group} to act as the Patroller.
-- @param #PATROLZONE self
-- @param Group#GROUP PatrolGroup The @{Group} patrolling.
@ -116,12 +125,13 @@ function PATROLZONE:SetGroup( PatrolGroup )
if not self.PatrolOutOfFuelMonitor then
self.PatrolOutOfFuelMonitor = SCHEDULER:New( nil, _MonitorOutOfFuelScheduled, { self }, 1, 120, 0 )
self.SpawnPatrolGroup = SPAWN:New( self.PatrolGroupTemplateName )
end
return self
end
--- Sets (modifies) the minimum and maximum speed of the patrol.
-- @param #PATROLZONE self
-- @param DCSTypes#Speed PatrolMinSpeed The minimum speed of the @{Group} in km/h.
@ -134,6 +144,8 @@ function PATROLZONE:SetSpeed( PatrolMinSpeed, PatrolMaxSpeed )
self.PatrolMaxSpeed = PatrolMaxSpeed
end
--- Sets the floor and ceiling altitude of the patrol.
-- @param #PATROLZONE self
-- @param DCSTypes#Altitude PatrolFloorAltitude The lowest altitude in meters where to execute the patrol.
@ -156,6 +168,8 @@ function _NewPatrolRoute( PatrolGroup )
PatrolZone:NewPatrolRoute()
end
--- Defines a new patrol route using the @{PatrolZone} parameters and settings.
-- @param #PATROLZONE self
-- @return #PATROLZONE self
@ -267,7 +281,6 @@ function PATROLZONE:ManageFuel( PatrolFuelTresholdPercentage, PatrolOutOfFuelOrb
if self.PatrolGroup then
self.PatrolOutOfFuelMonitor = SCHEDULER:New( self, self._MonitorOutOfFuelScheduled, {}, 1, 120, 0 )
self.SpawnPatrolGroup = SPAWN:New( self.PatrolGroupTemplateName )
end
return self
end
@ -287,7 +300,7 @@ function _MonitorOutOfFuelScheduled( self )
local TimedOrbitTask = OldPatrolGroup:TaskControlled( OrbitTask, OldPatrolGroup:TaskCondition(nil,nil,nil,nil,self.PatrolOutOfFuelOrbitTime,nil ) )
OldPatrolGroup:SetTask( TimedOrbitTask, 10 )
local NewPatrolGroup = self.SpawnPatrolGroup:Spawn()
local NewPatrolGroup = self.PatrolSpawn:Spawn()
self.PatrolGroup = NewPatrolGroup
self:NewPatrolRoute()
end

View File

@ -236,6 +236,7 @@ function POSITIONABLE:InAir()
return nil
end
--- Returns the POSITIONABLE velocity vector.
-- @param Positionable#POSITIONABLE self

View File

@ -56,7 +56,7 @@ SCHEDULER = {
-- @return #SCHEDULER self
function SCHEDULER:New( TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds )
local self = BASE:Inherit( self, BASE:New() )
self:F2( { TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds } )
self:F2( { StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds } )
self:Schedule( TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds )
@ -75,7 +75,8 @@ end
-- @param #number StopSeconds Specifies the amount of seconds when the scheduler will be stopped.
-- @return #SCHEDULER self
function SCHEDULER:Schedule( TimeEventObject, TimeEventFunction, TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds )
self:F2( { TimeEventFunctionArguments, StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds } )
self:F2( { StartSeconds, RepeatSecondsInterval, RandomizationFactor, StopSeconds } )
self:T3( { TimeEventFunctionArguments } )
self.TimeEventObject = TimeEventObject
self.TimeEventFunction = TimeEventFunction
@ -97,7 +98,7 @@ end
-- @param #SCHEDULER self
-- @return #SCHEDULER self
function SCHEDULER:Start()
self:F2( self.TimeEventObject )
self:F2()
if self.RepeatSecondsInterval ~= 0 then
self.Repeat = true
@ -107,7 +108,8 @@ function SCHEDULER:Start()
if self.ScheduleID then
timer.removeFunction( self.ScheduleID )
end
self.ScheduleID = timer.scheduleFunction( self._Scheduler, self, timer.getTime() + self.StartSeconds + .01 )
self:T( { self.StartSeconds } )
self.ScheduleID = timer.scheduleFunction( self._Scheduler, self, timer.getTime() + self.StartSeconds + .001 )
end
return self

View File

@ -182,11 +182,11 @@
--
-- ### Contributions:
--
-- * Aaron: Posed the idea for Group position randomization at SpawnInZone and make the Unit randomization separate from the Group randomization.
-- * **Aaron**: Posed the idea for Group position randomization at SpawnInZone and make the Unit randomization separate from the Group randomization.
--
-- ### Authors:
--
-- * FlightControl : Design & Programming
-- * **FlightControl**: Design & Programming
--
--
-- @module Spawn
@ -490,6 +490,10 @@ function SPAWN:InitCleanUp( SpawnCleanUpInterval )
self.SpawnCleanUpInterval = SpawnCleanUpInterval
self.SpawnCleanUpTimeStamps = {}
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup()
self:T( { "CleanUp Scheduler:", SpawnGroup } )
--self.CleanUpFunction = routines.scheduleFunction( self._SpawnCleanUpScheduler, { self }, timer.getTime() + 1, SpawnCleanUpInterval )
self.CleanUpScheduler = SCHEDULER:New( self, self._SpawnCleanUpScheduler, {}, 1, SpawnCleanUpInterval, 0.2 )
return self
@ -614,6 +618,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex )
else
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
self:T( SpawnTemplate.name )
if SpawnTemplate then
@ -642,7 +647,7 @@ function SPAWN:SpawnWithIndex( SpawnIndex )
if self.RepeatOnEngineShutDown then
_EVENTDISPATCHER:OnEngineShutDownForTemplate( SpawnTemplate, self._OnEngineShutDown, self )
end
self:T3( SpawnTemplate )
self:T3( SpawnTemplate.name )
self.SpawnGroups[self.SpawnIndex].Group = _DATABASE:Spawn( SpawnTemplate )
@ -1506,28 +1511,72 @@ function SPAWN:_Scheduler()
return true
end
--- Schedules the CleanUp of Groups
-- @param #SPAWN self
-- @return #boolean True = Continue Scheduler
function SPAWN:_SpawnCleanUpScheduler()
self:F( { "CleanUp Scheduler:", self.SpawnTemplatePrefix } )
local SpawnCursor
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup( SpawnCursor )
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup()
self:T( { "CleanUp Scheduler:", SpawnGroup } )
while SpawnGroup do
if SpawnGroup:AllOnGround() and SpawnGroup:GetMaxVelocity() < 1 then
if not self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] then
self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] = timer.getTime()
else
if self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] + self.SpawnCleanUpInterval < timer.getTime() then
self:T( { "CleanUp Scheduler:", "Cleaning:", SpawnGroup } )
SpawnGroup:Destroy()
end
end
else
self.SpawnCleanUpTimeStamps[SpawnGroup:GetName()] = nil
end
local SpawnUnits = SpawnGroup:GetUnits()
for UnitID, UnitData in pairs( SpawnUnits ) do
local SpawnUnit = UnitData -- Unit#UNIT
local SpawnUnitName = SpawnUnit:GetName()
self.SpawnCleanUpTimeStamps[SpawnUnitName] = self.SpawnCleanUpTimeStamps[SpawnUnitName] or {}
local Stamp = self.SpawnCleanUpTimeStamps[SpawnUnitName]
self:T( { SpawnUnitName, Stamp } )
if Stamp.Moved then
if SpawnUnit:InAir() == false then
if SpawnUnit:GetVelocityKMH() < 1 then
-- If the plane is not moving, and is on the ground, assign it with a timestamp...
if not Stamp.Time then
Stamp.Time = timer.getTime()
else
if Stamp.Time + self.SpawnCleanUpInterval < timer.getTime() then
self:T( { "CleanUp Scheduler:", "ReSpawning:", SpawnGroup:GetName() } )
self:ReSpawn( SpawnCursor )
Stamp.Moved = nil
Stamp.Time = nil
end
end
else
Stamp.Time = nil
end
else
Stamp.Moved = nil
Stamp.Time = nil
end
else
if SpawnUnit:InAir() == false and SpawnUnit:GetVelocityKMH() > 1 then
Stamp.Moved = true
else
-- If the plane did not move and on the runway for about 3 minutes, clean it.
if SpawnUnit:IsAboveRunway() and SpawnUnit:GetVelocityKMH() < 1 then
if not Stamp.Time then
Stamp.Time = timer.getTime()
end
if Stamp.Time + 180 < timer.getTime() then
self:T( { "CleanUp Scheduler:", "ReSpawning inactive group:", SpawnGroup:GetName() } )
self:ReSpawn( SpawnCursor )
Stamp.Moved = nil
Stamp.Time = nil
end
else
Stamp.Moved = nil
Stamp.Time = nil
end
end
end
end
SpawnGroup, SpawnCursor = self:GetNextAliveGroup( SpawnCursor )

View File

@ -18,6 +18,7 @@
--- STATEMACHINE class
-- @type STATEMACHINE
-- @extends Base#BASE
STATEMACHINE = {
ClassName = "STATEMACHINE",
}
@ -47,7 +48,10 @@ function STATEMACHINE:New( options )
for _, event in ipairs(options.events or {}) do
local name = event.name
local __name = "__" .. event.name
self[name] = self[name] or self:_create_transition(name)
self[__name] = self[__name] or self:_delayed_transition(name)
self:T( "Added methods: " .. name .. ", " .. __name )
self.events[name] = self.events[name] or { map = {} }
self:_add_to_map(self.events[name].map, event)
end
@ -95,56 +99,81 @@ function STATEMACHINE:_call_handler(handler, params)
end
end
function STATEMACHINE:_create_transition(name)
self:E( { name = name } )
return function(self, ...)
local can, to = self:can(name)
self:T( { name, can, to } )
function STATEMACHINE._handler( self, EventName, ... )
if can then
local from = self.current
local params = { self, name, from, to, ... }
self:F( EventName )
if self:_call_handler(self["onbefore" .. name], params) == false
or self:_call_handler(self["onleave" .. from], params) == false then
return false
end
local can, to = self:can(EventName)
self:T( { EventName, can, to } )
local ReturnValues = nil
self.current = to
local execute = true
local subtable = self:_gosub( to, name )
for _, sub in pairs( subtable ) do
self:F( "calling sub: " .. sub.event )
sub.fsm.fsmparent = self
sub.fsm.returnevents = sub.returnevents
sub.fsm[sub.event]( sub.fsm )
execute = true
end
local fsmparent, event = self:_isendstate( to )
if fsmparent and event then
self:F( { "end state: ", fsmparent, event } )
self:_call_handler(self["onenter" .. to] or self["on" .. to], params)
self:_call_handler(self["onafter" .. name] or self["on" .. name], params)
self:_call_handler(self["onstatechange"], params)
fsmparent[event]( fsmparent )
execute = false
end
if can then
local from = self.current
local params = { self, ..., EventName, from, to }
if execute then
self:F( { "execute: " .. to, name } )
self:_call_handler(self["onenter" .. to] or self["on" .. to], params)
self:_call_handler(self["onafter" .. name] or self["on" .. name], params)
self:_call_handler(self["onstatechange"], params)
end
return true
if self:_call_handler(self["onbefore" .. EventName], params) == false
or self:_call_handler(self["onleave" .. from], params) == false then
return false
end
return false
self.current = to
local execute = true
local subtable = self:_gosub( to, EventName )
for _, sub in pairs( subtable ) do
self:F2( "calling sub: " .. sub.event )
sub.fsm.fsmparent = self
sub.fsm.returnevents = sub.returnevents
sub.fsm[sub.event]( sub.fsm )
execute = true
end
local fsmparent, event = self:_isendstate( to )
if fsmparent and event then
self:F2( { "end state: ", fsmparent, event } )
self:_call_handler(self["onenter" .. to] or self["on" .. to], params)
self:_call_handler(self["onafter" .. EventName] or self["on" .. EventName], params)
self:_call_handler(self["onstatechange"], params)
fsmparent[event]( fsmparent )
execute = false
end
if execute then
self:T3( { onenter = "onenter" .. to, callback = self["onenter" .. to] } )
self:_call_handler(self["onenter" .. to] or self["on" .. to], params)
self:T3( { On = "OnBefore" .. to, callback = self["OnBefore" .. to] } )
if ( self:_call_handler(self["OnBefore" .. to], params ) ~= false ) then
self:T3( { onafter = "onafter" .. EventName, callback = self["onafter" .. EventName] } )
self:_call_handler(self["onafter" .. EventName] or self["on" .. EventName], params)
self:T3( { On = "OnAfter" .. to, callback = self["OnAfter" .. to] } )
ReturnValues = self:_call_handler(self["OnAfter" .. to], params )
end
self:_call_handler(self["onstatechange"], params)
end
return ReturnValues
end
return nil
end
function STATEMACHINE:_delayed_transition( EventName )
self:E( { EventName = EventName } )
return function( self, DelaySeconds, ... )
self:T( "Delayed Event: " .. EventName )
SCHEDULER:New( self, self._handler, { EventName, ... }, DelaySeconds )
end
end
function STATEMACHINE:_create_transition( EventName )
self:E( { Event = EventName } )
return function( self, ... ) return self._handler( self, EventName , ... ) end
end
function STATEMACHINE:_gosub( parentstate, parentevent )

View File

@ -0,0 +1,283 @@
--- This module contains the AIBALANCER class.
--
-- ===
--
-- 1) @{AIBalancer#AIBALANCER} class, extends @{Base#BASE}
-- =======================================================
-- The @{AIBalancer#AIBALANCER} class controls the dynamic spawning of AI GROUPS depending on a SET_CLIENT.
-- There will be as many AI GROUPS spawned as there at CLIENTS in SET_CLIENT not spawned.
-- The AIBalancer uses the @{PatrolZone#PATROLZONE} class to make AI patrol an zone until the fuel treshold is reached.
--
-- 1.1) AIBALANCER construction method:
-- ------------------------------------
-- Create a new AIBALANCER object with the @{#AIBALANCER.New} method:
--
-- * @{#AIBALANCER.New}: Creates a new AIBALANCER object.
--
-- 1.2) AIBALANCER returns AI to Airbases:
-- ---------------------------------------
-- You can configure to have the AI to return to:
--
-- * @{#AIBALANCER.ReturnToHomeAirbase}: Returns the AI to the home @{Airbase#AIRBASE}.
-- * @{#AIBALANCER.ReturnToNearestAirbases}: Returns the AI to the nearest friendly @{Airbase#AIRBASE}.
--
-- 1.3) AIBALANCER allows AI to patrol specific zones:
-- ---------------------------------------------------
-- Use @{AIBalancer#AIBALANCER.SetPatrolZone}() to specify a zone where the AI needs to patrol.
--
-- ===
--
-- **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:
--
-- 2016-08-17: SPAWN:**InitCleanUp**( SpawnCleanUpInterval ) replaces SPAWN:_CleanUp_( SpawnCleanUpInterval )
--
-- * Want to ensure that the methods starting with **Init** are the first called methods before any _Spawn_ method is called!
-- * This notation makes it now more clear which methods are initialization methods and which methods are Spawn enablement methods.
--
-- ===
--
-- AUTHORS and CONTRIBUTIONS
-- =========================
--
-- ### Contributions:
--
-- * **Dutch_Baron (James)**: Who you can search on the Eagle Dynamics Forums.
-- Working together with James has resulted in the creation of the AIBALANCER 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 AIBALANCER moose class.
--
-- ### Authors:
--
-- * FlightControl: Framework Design & Programming
--
-- @module AIBalancer
--- AIBALANCER class
-- @type AIBALANCER
-- @field Set#SET_CLIENT SetClient
-- @field Spawn#SPAWN SpawnAI
-- @field #boolean ToNearestAirbase
-- @field Set#SET_AIRBASE ReturnAirbaseSet
-- @field DCSTypes#Distance ReturnTresholdRange
-- @field #boolean ToHomeAirbase
-- @field PatrolZone#PATROLZONE PatrolZone
-- @extends Base#BASE
AIBALANCER = {
ClassName = "AIBALANCER",
PatrolZones = {},
AIGroups = {},
}
--- Creates a new AIBALANCER object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
-- @param #AIBALANCER self
-- @param SetClient A SET_CLIENT object that will contain the CLIENT objects to be monitored if they are alive or not (joined by a player).
-- @param SpawnAI A SPAWN object that will spawn the AI units required, balancing the SetClient.
-- @return #AIBALANCER self
function AIBALANCER:New( SetClient, SpawnAI )
-- Inherits from BASE
local self = BASE:Inherit( self, BASE:New() )
self.SetClient = SetClient
if type( SpawnAI ) == "table" then
if SpawnAI.ClassName and SpawnAI.ClassName == "SPAWN" then
self.SpawnAI = { SpawnAI }
else
local SpawnObjects = true
for SpawnObjectID, SpawnObject in pairs( SpawnAI ) do
if SpawnObject.ClassName and SpawnObject.ClassName == "SPAWN" then
self:E( SpawnObject.ClassName )
else
self:E( "other object" )
SpawnObjects = false
end
end
if SpawnObjects == true then
self.SpawnAI = SpawnAI
else
error( "No SPAWN object given in parameter SpawnAI, either as a single object or as a table of objects!" )
end
end
end
self.ToNearestAirbase = false
self.ReturnHomeAirbase = false
self.AIMonitorSchedule = SCHEDULER:New( self, self._ClientAliveMonitorScheduler, {}, 1, 10, 0 )
return self
end
--- Returns the AI to the nearest friendly @{Airbase#AIRBASE}.
-- @param #AIBALANCER self
-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}.
-- @param Set#SET_AIRBASE ReturnAirbaseSet The SET of @{Set#SET_AIRBASE}s to evaluate where to return to.
function AIBALANCER:ReturnToNearestAirbases( ReturnTresholdRange, ReturnAirbaseSet )
self.ToNearestAirbase = true
self.ReturnTresholdRange = ReturnTresholdRange
self.ReturnAirbaseSet = ReturnAirbaseSet
end
--- Returns the AI to the home @{Airbase#AIRBASE}.
-- @param #AIBALANCER self
-- @param DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Airbase#AIRBASE}.
function AIBALANCER:ReturnToHomeAirbase( ReturnTresholdRange )
self.ToHomeAirbase = true
self.ReturnTresholdRange = ReturnTresholdRange
end
--- Let the AI patrol a @{Zone} with a given Speed range and Altitude range.
-- @param #AIBALANCER self
-- @param PatrolZone#PATROLZONE PatrolZone The @{PatrolZone} where the AI needs to patrol.
-- @return PatrolZone#PATROLZONE self
function AIBALANCER:SetPatrolZone( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
self.PatrolZone = PATROLZONE:New(
self.SpawnAI,
PatrolZone,
PatrolFloorAltitude,
PatrolCeilingAltitude,
PatrolMinSpeed,
PatrolMaxSpeed
)
end
--- Get the @{PatrolZone} object assigned by the @{AIBalancer} object.
-- @param #AIBALANCER self
-- @return PatrolZone#PATROLZONE PatrolZone The @{PatrolZone} where the AI needs to patrol.
function AIBALANCER:GetPatrolZone()
return self.PatrolZone
end
--- @param #AIBALANCER self
function AIBALANCER:_ClientAliveMonitorScheduler()
self.SetClient:ForEachClient(
--- @param Client#CLIENT Client
function( Client )
local ClientAIAliveState = Client:GetState( self, 'AIAlive' )
self:T( ClientAIAliveState )
if Client:IsAlive() then
if ClientAIAliveState == true then
Client:SetState( self, 'AIAlive', false )
local AIGroup = self.AIGroups[Client.UnitName] -- Group#GROUP
-- local PatrolZone = Client:GetState( self, "PatrolZone" )
-- if PatrolZone then
-- PatrolZone = nil
-- Client:ClearState( self, "PatrolZone" )
-- end
if self.ToNearestAirbase == false and self.ToHomeAirbase == false then
AIGroup:Destroy()
else
-- We test if there is no other CLIENT within the self.ReturnTresholdRange of the first unit of the AI group.
-- If there is a CLIENT, the AI stays engaged and will not return.
-- If there is no CLIENT within the self.ReturnTresholdRange, then the unit will return to the Airbase return method selected.
local PlayerInRange = { Value = false }
local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetVec2(), self.ReturnTresholdRange )
self:E( RangeZone )
_DATABASE:ForEachPlayer(
--- @param Unit#UNIT RangeTestUnit
function( RangeTestUnit, RangeZone, AIGroup, PlayerInRange )
self:E( { PlayerInRange, RangeTestUnit.UnitName, RangeZone.ZoneName } )
if RangeTestUnit:IsInZone( RangeZone ) == true then
self:E( "in zone" )
if RangeTestUnit:GetCoalition() ~= AIGroup:GetCoalition() then
self:E( "in range" )
PlayerInRange.Value = true
end
end
end,
--- @param Zone#ZONE_RADIUS RangeZone
-- @param Group#GROUP AIGroup
function( RangeZone, AIGroup, PlayerInRange )
local AIGroupTemplate = AIGroup:GetTemplate()
if PlayerInRange.Value == false then
if self.ToHomeAirbase == true then
local WayPointCount = #AIGroupTemplate.route.points
local SwitchWayPointCommand = AIGroup:CommandSwitchWayPoint( 1, WayPointCount, 1 )
AIGroup:SetCommand( SwitchWayPointCommand )
AIGroup:MessageToRed( "Returning to home base ...", 30 )
else
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI.
--TODO: i need to rework the POINT_VEC2 thing.
local PointVec2 = POINT_VEC2:New( AIGroup:GetVec2().x, AIGroup:GetVec2().y )
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
self:T( ClosestAirbase.AirbaseName )
AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 )
local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase )
AIGroupTemplate.route = RTBRoute
AIGroup:Respawn( AIGroupTemplate )
end
end
end
, RangeZone, AIGroup, PlayerInRange
)
end
end
else
if not ClientAIAliveState or ClientAIAliveState == false then
Client:SetState( self, 'AIAlive', true )
-- OK, spawn a new group from the SpawnAI objects provided.
local SpawnAICount = #self.SpawnAI
local SpawnAIIndex = math.random( 1, SpawnAICount )
local AIGroup = self.SpawnAI[SpawnAIIndex]:Spawn()
AIGroup:E( "spawning new AIGroup" )
--TODO: need to rework UnitName thing ...
self.AIGroups[Client.UnitName] = AIGroup
--- Now test if the AIGroup needs to patrol a zone, otherwise let it follow its route...
if self.PatrolZone then
self.PatrolZones[#self.PatrolZones+1] = PATROLZONE:New(
self.PatrolZone.PatrolZone,
self.PatrolZone.PatrolFloorAltitude,
self.PatrolZone.PatrolCeilingAltitude,
self.PatrolZone.PatrolMinSpeed,
self.PatrolZone.PatrolMaxSpeed
)
if self.PatrolZone.PatrolManageFuel == true then
self.PatrolZones[#self.PatrolZones]:ManageFuel( self.PatrolZone.PatrolFuelTresholdPercentage, self.PatrolZone.PatrolOutOfFuelOrbitTime )
end
self.PatrolZones[#self.PatrolZones]:SetGroup( AIGroup )
--self.PatrolZones[#self.PatrolZones+1] = PatrolZone
--Client:SetState( self, "PatrolZone", PatrolZone )
end
end
end
end
)
return true
end

View File

@ -1,3 +1,12 @@
2016-08-17
- Making the PATROLZONE class work with a SPAWN object, instead of a GROUP object.
-- The SPAWN object is needed to make the FuelManagement logic work correctly. New planes need to be spawned when old planes are out of fuel.
-- Changed the PATROLZONE:New() method to work with a SPAWN object instead of a GROUP object.
- Making the AIBALANCER class work with the modified PATROLZONE class SPAWN object.
-- Added AIBALANCER:GetPatrolZone() method.
2016-08-15
- Removed the old classes and moved into an "Old" folder in the Moose/Development folder.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,32 @@
local US_PlanesClientSet = SET_CLIENT:New():FilterCountries( "USA" ):FilterCategories( "plane" ):FilterStart()
local US_PlanesSpawn1 = SPAWN:New( "AI US 1" )
local US_PlanesSpawn2 = SPAWN:New( "AI US 2" )
local US_AIBalancer = AIBALANCER:New( US_PlanesClientSet, { US_PlanesSpawn1, US_PlanesSpawn2 } )
local US_PlanesSpawn1 = SPAWN:New( "AI US 1" ):InitCleanUp( 90 )
local US_PlanesSpawn2 = SPAWN:New( "AI US 2" ):InitCleanUp( 90 )
local US_AIBalancer = AIBALANCER:New( US_PlanesClientSet )
US_AIBalancer:OnNewAI(
function( AIGroup )
AIGroup = US_PlanesSpawn1:Spawn()
local AIPatrolZone = AI_PATROLZONE:New( 3000, 6000, 900, 1100 )
AIPatrolZone:ManageFuel( 0.2, 180 )
AIGroup:SetTask( AIPatrolZone )
AIPatrolZone:OnRTB(
function( AIGroup )
AIGroup = US_PlanesSpawn1:Spawn()
end
)
end
)
local RU_PlanesClientSet = SET_CLIENT:New():FilterCountries( "RUSSIA" ):FilterCategories( "plane" ):FilterStart()
local RU_PlanesSpawn = SPAWN:New( "AI RU" )
local RU_PlanesSpawn = SPAWN:New( "AI RU" ):InitCleanUp( 90 )
local RU_AIBalancer = AIBALANCER:New( RU_PlanesClientSet, RU_PlanesSpawn )
local RU_AirbasesSet = SET_AIRBASE:New():FilterCoalitions("red"):FilterStart()

View File

@ -1,8 +1,80 @@
-- 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.
-- 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.
-- When the GROUP object that is assigned to Patrol has fuel below 20%, the GROUP object will orbit for 0 secondes, before returning to base.
--
-- The Patrol1 and Patrol2 object have 2 state transition functions defined, which customize the default behaviour of the RTB state.
-- When Patrol1 goes RTB, it will create a new GROUP object, that will be assigned to Patrol2.
-- When Patrol2 goes RTB, it will create a new GROUP object, that will be assgined to Patrol1.
--
-- In this way, the Patrol1 and Patrol2 objects are fluctuating the patrol pattern from PatrolZone1 and PatrolZone2 :-)
local PatrolZoneGroup = GROUP:FindByName( "Patrol Zone" )
local PatrolZone = ZONE_POLYGON:New( "PatrolZone", PatrolZoneGroup )
local PatrolGroup = GROUP:FindByName( "Patrol Group" )
local PatrolZoneGroup1 = GROUP:FindByName( "Patrol Zone 1" )
local PatrolZone1 = ZONE_POLYGON:New( "Patrol Zone 1", PatrolZoneGroup1 )
local Patrol = PATROLZONE:New( PatrolGroup, PatrolZone, 3000, 6000, 300, 600 )
Patrol:ManageFuel( 0.2, 60 )
local PatrolZoneGroup2 = GROUP:FindByName( "Patrol Zone 2" )
local PatrolZone2 = ZONE_POLYGON:New( "Patrol Zone 2", PatrolZoneGroup2 )
local PatrolSpawn = SPAWN:New( "Patrol Group" )
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 )
local Patrol2 = AI_PATROLZONE:New( PatrolZone2, 600, 1000, 300, 400 )
Patrol2:ManageFuel( 0.2, 0 )
--- State transition function for the AI\_PATROLZONE **Patrol1** object
-- @param #AI_PATROLZONE self
-- @param Group#GROUP AIGroup
-- @return #boolean If false is returned, then the OnAfter state transition function will not be called.
function Patrol1:OnBeforeRTB( AIGroup )
AIGroup:MessageToRed( "Returning to base", 20 )
end
--- State transition function for the AI\_PATROLZONE **Patrol1** object
-- @param AI_PatrolZone#AI_PATROLZONE self
-- @param Group#GROUP AIGroup
function Patrol1:OnAfterRTB( AIGroup )
local NewGroup = PatrolSpawn:Spawn()
Patrol2:SetGroup( NewGroup )
Patrol2:__Start( 1, NewGroup )
end
--- State transition function for the AI\_PATROLZONE **Patrol1** object
-- @param AI_PatrolZone#AI_PATROLZONE self
-- @param Group#GROUP AIGroup
function Patrol1:OnAfterPatrol( AIGroup )
AIGroup:MessageToRed( "Patrolling in zone " .. PatrolZone1:GetName() , 20 )
end
--- State transition function for the AI\_PATROLZONE **Patrol2** object
-- @param #AI_PATROLZONE self
-- @param Group#GROUP AIGroup
-- @return #boolean If false is returned, then the OnAfter state transition function will not be called.
function Patrol2:OnBeforeRTB( AIGroup )
AIGroup:MessageToRed( "Returning to base", 20 )
end
--- State transition function for the AI\_PATROLZONE **Patrol2** object
-- @param AI_PatrolZone#AI_PATROLZONE self
-- @param Group#GROUP AIGroup
function Patrol2:OnAfterRTB( AIGroup )
local NewGroup = PatrolSpawn:Spawn()
Patrol1:SetGroup( NewGroup )
Patrol1:__Start( 1, NewGroup )
end
--- State transition function for the AI\_PATROLZONE **Patrol2** object
-- @param AI_PatrolZone#AI_PATROLZONE self
-- @param Group#GROUP AIGroup
function Patrol2:OnAfterPatrol( AIGroup )
AIGroup:MessageToRed( "Patrolling in zone " .. PatrolZone2:GetName() , 20 )
end

View File

@ -0,0 +1,28 @@
-- This test will schedule the same function 2 times.
SpawnTest = SPAWN:New( "Test" )
TestZone = ZONE:New( "TestZone" )
local function MessageTest2()
SpawnTest:SpawnInZone( TestZone, true )
end
local function MessageTest1()
SpawnTest:SpawnInZone( TestZone, true )
-- The second after 10 seconds
SCHEDULER:New( nil, MessageTest2, {}, 5 )
-- The third after 15 seconds
SCHEDULER:New( nil, MessageTest2, {}, 10 )
end
-- The first after 5 seconds
SCHEDULER:New( nil, MessageTest1, {}, 5 )
-- The fourth after 20 seconds
SCHEDULER:New( nil, MessageTest1, {}, 20 )

View File

@ -0,0 +1,16 @@
-- This test will schedule the same function 2 times.
SpawnTest = SPAWN:New( "Test" )
TestZone = ZONE:New( "TestZone" )
local function MessageTest()
SpawnTest:SpawnInZone( TestZone, true )
end
-- The first after 5 seconds
TestScheduler1 = SCHEDULER:New( nil, MessageTest, {}, 5 )
-- The second after 10 seconds
TestScheduler2 = SCHEDULER:New( nil, MessageTest, {}, 10 )

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li>AIBalancer</li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>
@ -93,7 +94,8 @@
<h1>1) <a href="AIBalancer.html##(AIBALANCER)">AIBalancer#AIBALANCER</a> class, extends <a href="Base.html##(BASE)">Base#BASE</a></h1>
<p>The <a href="AIBalancer.html##(AIBALANCER)">AIBalancer#AIBALANCER</a> class controls the dynamic spawning of AI GROUPS depending on a SET<em>CLIENT.
There will be as many AI GROUPS spawned as there at CLIENTS in SET</em>CLIENT not spawned.</p>
There will be as many AI GROUPS spawned as there at CLIENTS in SET</em>CLIENT not spawned.
The AIBalancer uses the <a href="PatrolZone.html##(PATROLZONE)">PatrolZone#PATROLZONE</a> class to make AI patrol an zone until the fuel treshold is reached.</p>
<h2>1.1) AIBALANCER construction method:</h2>
<p>Create a new AIBALANCER object with the <a href="##(AIBALANCER).New">AIBALANCER.New</a> method:</p>
@ -115,13 +117,35 @@ There will be as many AI GROUPS spawned as there at CLIENTS in SET</em>CLIENT no
<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>2016-08-17: SPAWN:<strong>InitCleanUp</strong>( SpawnCleanUpInterval ) replaces SPAWN:<em>CleanUp</em>( SpawnCleanUpInterval )</p>
<ul>
<li>Want to ensure that the methods starting with <strong>Init</strong> are the first called methods before any <em>Spawn</em> method is called!</li>
<li>This notation makes it now more clear which methods are initialization methods and which methods are Spawn enablement methods.</li>
</ul>
<hr/>
<h1>AUTHORS and CONTRIBUTIONS</h1>
<h3>Contributions:</h3>
<ul>
<li><p><strong>Dutch_Baron (James)</strong> Who you can search on the Eagle Dynamics Forums. <br/>
<li><p><strong>Dutch_Baron (James)</strong>: Who you can search on the Eagle Dynamics Forums. <br/>
Working together with James has resulted in the creation of the AIBALANCER class. <br/>
James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)</p></li>
<li><p><strong>SNAFU</strong>
<li><p><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 AIBALANCER moose class.</p></li>
</ul>
@ -129,7 +153,7 @@ There will be as many AI GROUPS spawned as there at CLIENTS in SET</em>CLIENT no
<h3>Authors:</h3>
<ul>
<li>FlightControl - Framework Design &amp; Programming</li>
<li>FlightControl: Framework Design &amp; Programming</li>
</ul>
@ -154,6 +178,12 @@ There will be as many AI GROUPS spawned as there at CLIENTS in SET</em>CLIENT no
<td class="name" nowrap="nowrap"><a href="##(AIBALANCER).ClassName">AIBALANCER.ClassName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AIBALANCER).GetPatrolZone">AIBALANCER:GetPatrolZone()</a></td>
<td class="summary">
<p>Get the <a href="PatrolZone.html">PatrolZone</a> object assigned by the <a href="AIBalancer.html">AIBalancer</a> object.</p>
</td>
</tr>
<tr>
@ -205,7 +235,7 @@ There will be as many AI GROUPS spawned as there at CLIENTS in SET</em>CLIENT no
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AIBALANCER).SetPatrolZone">AIBALANCER:SetPatrolZone(PatrolZone)</a></td>
<td class="name" nowrap="nowrap"><a href="##(AIBALANCER).SetPatrolZone">AIBALANCER:SetPatrolZone(PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</a></td>
<td class="summary">
<p>Let the AI patrol a <a href="Zone.html">Zone</a> with a given Speed range and Altitude range.</p>
</td>
@ -284,6 +314,24 @@ There will be as many AI GROUPS spawned as there at CLIENTS in SET</em>CLIENT no
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AIBALANCER).GetPatrolZone" >
<strong>AIBALANCER:GetPatrolZone()</strong>
</a>
</dt>
<dd>
<p>Get the <a href="PatrolZone.html">PatrolZone</a> object assigned by the <a href="AIBalancer.html">AIBalancer</a> object.</p>
<h3>Return value</h3>
<p><em><a href="PatrolZone.html##(PATROLZONE)">PatrolZone#PATROLZONE</a>:</em>
PatrolZone The <a href="PatrolZone.html">PatrolZone</a> where the AI needs to patrol.</p>
</dd>
</dl>
<dl class="function">
@ -443,20 +491,40 @@ The SET of <a href="Set.html##(SET_AIRBASE)">Set#SET_AIRBASE</a>s to evaluate wh
<dt>
<a id="#(AIBALANCER).SetPatrolZone" >
<strong>AIBALANCER:SetPatrolZone(PatrolZone)</strong>
<strong>AIBALANCER:SetPatrolZone(PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</strong>
</a>
</dt>
<dd>
<p>Let the AI patrol a <a href="Zone.html">Zone</a> with a given Speed range and Altitude range.</p>
<h3>Parameter</h3>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="PatrolZone.html##(PATROLZONE)">PatrolZone#PATROLZONE</a> PatrolZone </em></code>:
The <a href="PatrolZone.html">PatrolZone</a> where the AI needs to patrol.</p>
</li>
<li>
<p><code><em> PatrolFloorAltitude </em></code>: </p>
</li>
<li>
<p><code><em> PatrolCeilingAltitude </em></code>: </p>
</li>
<li>
<p><code><em> PatrolMinSpeed </em></code>: </p>
</li>
<li>
<p><code><em> PatrolMaxSpeed </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>

View File

@ -0,0 +1,799 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<link rel="stylesheet" href="stylesheet.css" type="text/css"/>
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo"></div>
<div id="product_name"><big><b></b></big></div>
<div id="product_description"></div>
</div>
<div id="main">
<div id="navigation">
<h2>Modules</h2>
<ul><li>
<a href="index.html">index</a>
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li>AI_PatrolZone</li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>
<li><a href="Cargo.html">Cargo</a></li>
<li><a href="CleanUp.html">CleanUp</a></li>
<li><a href="Client.html">Client</a></li>
<li><a href="Controllable.html">Controllable</a></li>
<li><a href="DCSAirbase.html">DCSAirbase</a></li>
<li><a href="DCSCoalitionObject.html">DCSCoalitionObject</a></li>
<li><a href="DCSCommand.html">DCSCommand</a></li>
<li><a href="DCSController.html">DCSController</a></li>
<li><a href="DCSGroup.html">DCSGroup</a></li>
<li><a href="DCSObject.html">DCSObject</a></li>
<li><a href="DCSTask.html">DCSTask</a></li>
<li><a href="DCSTypes.html">DCSTypes</a></li>
<li><a href="DCSUnit.html">DCSUnit</a></li>
<li><a href="DCSWorld.html">DCSWorld</a></li>
<li><a href="DCScountry.html">DCScountry</a></li>
<li><a href="DCStimer.html">DCStimer</a></li>
<li><a href="DCStrigger.html">DCStrigger</a></li>
<li><a href="Database.html">Database</a></li>
<li><a href="Detection.html">Detection</a></li>
<li><a href="DetectionManager.html">DetectionManager</a></li>
<li><a href="Escort.html">Escort</a></li>
<li><a href="Event.html">Event</a></li>
<li><a href="Group.html">Group</a></li>
<li><a href="Identifiable.html">Identifiable</a></li>
<li><a href="MOVEMENT.html">MOVEMENT</a></li>
<li><a href="Menu.html">Menu</a></li>
<li><a href="Message.html">Message</a></li>
<li><a href="MissileTrainer.html">MissileTrainer</a></li>
<li><a href="Mission.html">Mission</a></li>
<li><a href="Object.html">Object</a></li>
<li><a href="PatrolZone.html">PatrolZone</a></li>
<li><a href="Point.html">Point</a></li>
<li><a href="Positionable.html">Positionable</a></li>
<li><a href="Process.html">Process</a></li>
<li><a href="Process_Destroy.html">Process_Destroy</a></li>
<li><a href="Process_JTAC.html">Process_JTAC</a></li>
<li><a href="Process_Pickup.html">Process_Pickup</a></li>
<li><a href="Process_Smoke.html">Process_Smoke</a></li>
<li><a href="Scheduler.html">Scheduler</a></li>
<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="Spawn.html">Spawn</a></li>
<li><a href="StateMachine.html">StateMachine</a></li>
<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_A2G.html">Task_A2G</a></li>
<li><a href="Task_Assign.html">Task_Assign</a></li>
<li><a href="Task_Client_Menu.html">Task_Client_Menu</a></li>
<li><a href="Task_PICKUP.html">Task_PICKUP</a></li>
<li><a href="Task_Route.html">Task_Route</a></li>
<li><a href="Task_SEAD.html">Task_SEAD</a></li>
<li><a href="Unit.html">Unit</a></li>
<li><a href="Utils.html">Utils</a></li>
<li><a href="Zone.html">Zone</a></li>
<li><a href="env.html">env</a></li>
<li><a href="land.html">land</a></li>
<li><a href="routines.html">routines</a></li>
</ul>
</div>
<div id="content">
<h1>Module <code>AI_PatrolZone</code></h1>
<p>This module contains the AI_PATROLZONE class.</p>
<hr/>
<h1>1) <a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a> class, extends <a href="StateMachine.html##(STATEMACHINE)">StateMachine#STATEMACHINE</a></h1>
<p>The <a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a> class implements the core functions to patrol a <a href="Zone.html">Zone</a> by an AIR <a href="Group.html">Group</a>.
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.
Upon arrival at the random 3D point, a new 3D random point will be selected within the patrol zone using the given limits.
This cycle will continue until a fuel treshold has been reached by the airplane.
When the fuel treshold has been reached, the airplane will fly towards the nearest friendly airbase and will land.</p>
<h2>1.1) AI_PATROLZONE constructor:</h2>
<ul>
<li><a href="##(AI_PATROLZONE).New">AI_PATROLZONE.New</a>(): Creates a new AI_PATROLZONE object.</li>
</ul>
<h2>1.2) AI_PATROLZONE state machine:</h2>
<p>The AI_PATROLZONE is a state machine: it manages the different events and states of the AIGroup it is controlling.</p>
<h3>1.2.1) AI_PATROLZONE Events:</h3>
<ul>
<li><a href="##(AI_PATROLZONE).Route">AI_PATROLZONE.Route</a>( AIGroup ): A new 3D route point is selected and the AIGroup will fly towards that point with the given speed.</li>
<li><a href="##(AI_PATROLZONE).Patrol">AI_PATROLZONE.Patrol</a>( AIGroup ): The AIGroup reports it is patrolling. This event is called every 30 seconds.</li>
<li><a href="##(AI_PATROLZONE).RTB">AI_PATROLZONE.RTB</a>( AIGroup ): The AIGroup will report return to base.</li>
<li><a href="##(AI_PATROLZONE).End">AI_PATROLZONE.End</a>( AIGroup ): The end of the AI_PATROLZONE process.</li>
<li><a href="##(AI_PATROLZONE).Dead">AI_PATROLZONE.Dead</a>( AIGroup ): The AIGroup is dead. The AI_PATROLZONE process will be ended.</li>
</ul>
<h3>1.2.2) AI_PATROLZONE States:</h3>
<ul>
<li><strong>Route</strong>: A new 3D route point is selected and the AIGroup will fly towards that point with the given speed.</li>
<li><strong>Patrol</strong>: The AIGroup is patrolling. This state is set every 30 seconds, so every 30 seconds, a state transition function can be used.</li>
<li><strong>RTB</strong>: The AIGroup reports it wants to return to the base.</li>
<li><strong>Dead</strong>: The AIGroup is dead ...</li>
<li><strong>End</strong>: The process has come to an end.</li>
</ul>
<h3>1.2.3) AI_PATROLZONE state transition functions:</h3>
<p>State transition functions can be set <strong>by the mission designer</strong> customizing or improving the behaviour of the state.
There are 2 moments when state transition functions will be called by the state machine:</p>
<ul>
<li><p><strong>Before</strong> the state transition.
The state transition function needs to start with the name <strong>OnBefore + the name of the state</strong>.
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!</p></li>
<li><p><strong>After</strong> the state transition.
The state transition function needs to start with the name <strong>OnAfter + the name of the state</strong>.
These state transition functions need to provide a return value, which is specified at the function description.</p></li>
</ul>
<p>An example how to manage a state transition for an AI_PATROLZONE object <strong>Patrol</strong> for the state <strong>RTB</strong>:</p>
<pre><code> local PatrolZoneGroup = GROUP:FindByName( "Patrol Zone" )
local PatrolZone = ZONE_POLYGON:New( "PatrolZone", PatrolZoneGroup )
local PatrolSpawn = SPAWN:New( "Patrol Group" )
local PatrolGroup = PatrolSpawn:Spawn()
local Patrol = AI_PATROLZONE:New( PatrolZone, 3000, 6000, 300, 600 )
Patrol:AddGroup( PatrolGroup )
Patrol:ManageFuel( 0.2, 60 )
</code></pre>
<p><strong>OnBefore</strong>RTB( AIGroup ) will be called by the AI_PATROLZONE object when the AIGroup reports RTB, but <strong>before</strong> the RTB default action is processed by the AI_PATROLZONE object.</p>
<pre><code> --- State transition function for the AI\_PATROLZONE **Patrol** object
-- @param #AI_PATROLZONE self
-- @param Group#GROUP 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 )
end
</code></pre>
<p><strong>OnAfter</strong>RTB( AIGroup ) will be called by the AI_PATROLZONE object when the AIGroup reports RTB, but <strong>after</strong> the RTB default action was processed by the AI_PATROLZONE object.</p>
<pre><code> --- 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.
function Patrol:OnAfterRTB( AIGroup )
return PatrolSpawn:Spawn()
end
</code></pre>
<h2>1.3) Modify the AI_PATROLZONE parameters:</h2>
<p>The following methods are available to modify the parameters of a AI_PATROLZONE object:</p>
<ul>
<li><a href="##(AI_PATROLZONE).SetGroup">AI_PATROLZONE.SetGroup</a>(): Set the AI Patrol Group.</li>
<li><a href="##(AI_PATROLZONE).SetSpeed">AI_PATROLZONE.SetSpeed</a>(): Set the patrol speed of the AI, for the next patrol.</li>
<li><a href="##(AI_PATROLZONE).SetAltitude">AI_PATROLZONE.SetAltitude</a>(): Set altitude of the AI, for the next patrol.</li>
</ul>
<h2>1.3) Manage the out of fuel in the AI_PATROLZONE:</h2>
<p>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.
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.
Use the method <a href="##(AI_PATROLZONE).ManageFuel">AI_PATROLZONE.ManageFuel</a>() to have this proces in place.</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>2016-08-17: AI_PATROLZONE:New( <strong>PatrolSpawn,</strong> PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed ) replaces AI_PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )</p>
<p>2016-07-01: Initial class and API.</p>
<hr/>
<h1>AUTHORS and CONTRIBUTIONS</h1>
<h3>Contributions:</h3>
<ul>
<li><strong>DutchBaron</strong>: Testing.</li>
</ul>
<h3>Authors:</h3>
<ul>
<li><strong>FlightControl</strong>: Design &amp; Programming</li>
</ul>
<h2>Global(s)</h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="#AI_PATROLZONE">AI_PATROLZONE</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="#_NewPatrolRoute">_NewPatrolRoute(PatrolGroup)</a></td>
<td class="summary">
</td>
</tr>
</table>
<h2><a id="#(AI_PATROLZONE)">Type <code>AI_PATROLZONE</code></a></h2>
<table class="function_list">
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).ClassName">AI_PATROLZONE.ClassName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).ManageFuel">AI_PATROLZONE:ManageFuel(PatrolFuelTresholdPercentage, PatrolOutOfFuelOrbitTime)</a></td>
<td class="summary">
<p>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.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).New">AI_PATROLZONE:New(PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</a></td>
<td class="summary">
<p>Creates a new AI_PATROLZONE object</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolCeilingAltitude">AI_PATROLZONE.PatrolCeilingAltitude</a></td>
<td class="summary">
<p>The highest altitude in meters where to execute the patrol.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolFloorAltitude">AI_PATROLZONE.PatrolFloorAltitude</a></td>
<td class="summary">
<p>The lowest altitude in meters where to execute the patrol.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolFuelTresholdPercentage">AI_PATROLZONE.PatrolFuelTresholdPercentage</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolGroup">AI_PATROLZONE.PatrolGroup</a></td>
<td class="summary">
<p>The <a href="Group.html">Group</a> patrolling.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolGroupTemplateName">AI_PATROLZONE.PatrolGroupTemplateName</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolManageFuel">AI_PATROLZONE.PatrolManageFuel</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolMaxSpeed">AI_PATROLZONE.PatrolMaxSpeed</a></td>
<td class="summary">
<p>The maximum speed of the <a href="Group.html">Group</a> in km/h.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolMinSpeed">AI_PATROLZONE.PatrolMinSpeed</a></td>
<td class="summary">
<p>The minimum speed of the <a href="Group.html">Group</a> in km/h.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolOutOfFuelOrbitTime">AI_PATROLZONE.PatrolOutOfFuelOrbitTime</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).PatrolZone">AI_PATROLZONE.PatrolZone</a></td>
<td class="summary">
<p>The <a href="Zone.html">Zone</a> where the patrol needs to be executed.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).SetAltitude">AI_PATROLZONE:SetAltitude(PatrolFloorAltitude, PatrolCeilingAltitude)</a></td>
<td class="summary">
<p>Sets the floor and ceiling altitude of the patrol.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).SetGroup">AI_PATROLZONE:SetGroup(PatrolGroup)</a></td>
<td class="summary">
<p>Set the <a href="Group.html">Group</a> to act as the Patroller.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE).SetSpeed">AI_PATROLZONE:SetSpeed(PatrolMinSpeed, PatrolMaxSpeed)</a></td>
<td class="summary">
<p>Sets (modifies) the minimum and maximum speed of the patrol.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE)._EnterPatrol">AI_PATROLZONE:_EnterPatrol(AIGroup)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(AI_PATROLZONE)._EnterRoute">AI_PATROLZONE:_EnterRoute(AIGroup)</a></td>
<td class="summary">
<p>Defines a new patrol route using the <a href="PatrolZone.html">PatrolZone</a> parameters and settings.</p>
</td>
</tr>
</table>
<h2>Global(s)</h2>
<dl class="function">
<dt>
<em><a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a></em>
<a id="AI_PATROLZONE" >
<strong>AI_PATROLZONE</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="_NewPatrolRoute" >
<strong>_NewPatrolRoute(PatrolGroup)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Group.html##(GROUP)">Group#GROUP</a> PatrolGroup </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<h2><a id="#(AI_PatrolZone)" >Type <code>AI_PatrolZone</code></a></h2>
<h2><a id="#(AI_PATROLZONE)" >Type <code>AI_PATROLZONE</code></a></h2>
<p>AI_PATROLZONE class</p>
<h3>Field(s)</h3>
<dl class="function">
<dt>
<em>#string</em>
<a id="#(AI_PATROLZONE).ClassName" >
<strong>AI_PATROLZONE.ClassName</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AI_PATROLZONE).ManageFuel" >
<strong>AI_PATROLZONE:ManageFuel(PatrolFuelTresholdPercentage, PatrolOutOfFuelOrbitTime)</strong>
</a>
</dt>
<dd>
<p>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.</p>
<p>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.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em>#number PatrolFuelTresholdPercentage </em></code>:
The treshold in percentage (between 0 and 1) when the PatrolGroup is considered to get out of fuel.</p>
</li>
<li>
<p><code><em>#number PatrolOutOfFuelOrbitTime </em></code>:
The amount of seconds the out of fuel PatrolGroup will orbit before returning to the base.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AI_PATROLZONE).New" >
<strong>AI_PATROLZONE:New(PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</strong>
</a>
</dt>
<dd>
<p>Creates a new AI_PATROLZONE object</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="Zone.html##(ZONE_BASE)">Zone#ZONE_BASE</a> PatrolZone </em></code>:
The <a href="Zone.html">Zone</a> where the patrol needs to be executed.</p>
</li>
<li>
<p><code><em><a href="DCSTypes.html##(Altitude)">DCSTypes#Altitude</a> PatrolFloorAltitude </em></code>:
The lowest altitude in meters where to execute the patrol.</p>
</li>
<li>
<p><code><em><a href="DCSTypes.html##(Altitude)">DCSTypes#Altitude</a> PatrolCeilingAltitude </em></code>:
The highest altitude in meters where to execute the patrol.</p>
</li>
<li>
<p><code><em><a href="DCSTypes.html##(Speed)">DCSTypes#Speed</a> PatrolMinSpeed </em></code>:
The minimum speed of the <a href="Group.html">Group</a> in km/h.</p>
</li>
<li>
<p><code><em><a href="DCSTypes.html##(Speed)">DCSTypes#Speed</a> PatrolMaxSpeed </em></code>:
The maximum speed of the <a href="Group.html">Group</a> in km/h.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a>:</em>
self</p>
<h3>Usage:</h3>
<pre class="example"><code>-- 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.
PatrolZone = ZONE:New( 'PatrolZone' )
PatrolSpawn = SPAWN:New( 'Patrol Group' )
PatrolArea = AI_PATROLZONE:New( PatrolZone, 3000, 6000, 600, 900 )</code></pre>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="DCSTypes.html##(Altitude)">DCSTypes#Altitude</a></em>
<a id="#(AI_PATROLZONE).PatrolCeilingAltitude" >
<strong>AI_PATROLZONE.PatrolCeilingAltitude</strong>
</a>
</dt>
<dd>
<p>The highest altitude in meters where to execute the patrol.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="DCSTypes.html##(Altitude)">DCSTypes#Altitude</a></em>
<a id="#(AI_PATROLZONE).PatrolFloorAltitude" >
<strong>AI_PATROLZONE.PatrolFloorAltitude</strong>
</a>
</dt>
<dd>
<p>The lowest altitude in meters where to execute the patrol.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(AI_PATROLZONE).PatrolFuelTresholdPercentage" >
<strong>AI_PATROLZONE.PatrolFuelTresholdPercentage</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="Group.html##(GROUP)">Group#GROUP</a></em>
<a id="#(AI_PATROLZONE).PatrolGroup" >
<strong>AI_PATROLZONE.PatrolGroup</strong>
</a>
</dt>
<dd>
<p>The <a href="Group.html">Group</a> patrolling.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(AI_PATROLZONE).PatrolGroupTemplateName" >
<strong>AI_PATROLZONE.PatrolGroupTemplateName</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em>#boolean</em>
<a id="#(AI_PATROLZONE).PatrolManageFuel" >
<strong>AI_PATROLZONE.PatrolManageFuel</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="DCSTypes.html##(Speed)">DCSTypes#Speed</a></em>
<a id="#(AI_PATROLZONE).PatrolMaxSpeed" >
<strong>AI_PATROLZONE.PatrolMaxSpeed</strong>
</a>
</dt>
<dd>
<p>The maximum speed of the <a href="Group.html">Group</a> in km/h.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="DCSTypes.html##(Speed)">DCSTypes#Speed</a></em>
<a id="#(AI_PATROLZONE).PatrolMinSpeed" >
<strong>AI_PATROLZONE.PatrolMinSpeed</strong>
</a>
</dt>
<dd>
<p>The minimum speed of the <a href="Group.html">Group</a> in km/h.</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(AI_PATROLZONE).PatrolOutOfFuelOrbitTime" >
<strong>AI_PATROLZONE.PatrolOutOfFuelOrbitTime</strong>
</a>
</dt>
<dd>
</dd>
</dl>
<dl class="function">
<dt>
<em><a href="Zone.html##(ZONE_BASE)">Zone#ZONE_BASE</a></em>
<a id="#(AI_PATROLZONE).PatrolZone" >
<strong>AI_PATROLZONE.PatrolZone</strong>
</a>
</dt>
<dd>
<p>The <a href="Zone.html">Zone</a> where the patrol needs to be executed.</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AI_PATROLZONE).SetAltitude" >
<strong>AI_PATROLZONE:SetAltitude(PatrolFloorAltitude, PatrolCeilingAltitude)</strong>
</a>
</dt>
<dd>
<p>Sets the floor and ceiling altitude of the patrol.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="DCSTypes.html##(Altitude)">DCSTypes#Altitude</a> PatrolFloorAltitude </em></code>:
The lowest altitude in meters where to execute the patrol.</p>
</li>
<li>
<p><code><em><a href="DCSTypes.html##(Altitude)">DCSTypes#Altitude</a> PatrolCeilingAltitude </em></code>:
The highest altitude in meters where to execute the patrol.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AI_PATROLZONE).SetGroup" >
<strong>AI_PATROLZONE:SetGroup(PatrolGroup)</strong>
</a>
</dt>
<dd>
<p>Set the <a href="Group.html">Group</a> to act as the Patroller.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em><a href="Group.html##(GROUP)">Group#GROUP</a> PatrolGroup </em></code>:
The <a href="Group.html">Group</a> patrolling.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AI_PATROLZONE).SetSpeed" >
<strong>AI_PATROLZONE:SetSpeed(PatrolMinSpeed, PatrolMaxSpeed)</strong>
</a>
</dt>
<dd>
<p>Sets (modifies) the minimum and maximum speed of the patrol.</p>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em><a href="DCSTypes.html##(Speed)">DCSTypes#Speed</a> PatrolMinSpeed </em></code>:
The minimum speed of the <a href="Group.html">Group</a> in km/h.</p>
</li>
<li>
<p><code><em><a href="DCSTypes.html##(Speed)">DCSTypes#Speed</a> PatrolMaxSpeed </em></code>:
The maximum speed of the <a href="Group.html">Group</a> in km/h.</p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AI_PATROLZONE)._EnterPatrol" >
<strong>AI_PATROLZONE:_EnterPatrol(AIGroup)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> AIGroup </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(AI_PATROLZONE)._EnterRoute" >
<strong>AI_PATROLZONE:_EnterRoute(AIGroup)</strong>
</a>
</dt>
<dd>
<p>Defines a new patrol route using the <a href="PatrolZone.html">PatrolZone</a> parameters and settings.</p>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> AIGroup </em></code>: </p>
</li>
</ul>
<h3>Return value</h3>
<p><em><a href="##(AI_PATROLZONE)">#AI_PATROLZONE</a>:</em>
self</p>
</dd>
</dl>
</div>
</div>
</body>
</html>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li>Airbase</li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li>AirbasePolice</li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li>Base</li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>
@ -1645,6 +1646,7 @@ The UNIT carrying the package.</p>
<dl class="function">
<dt>
<em></em>
<a id="#(CARGO_UNIT).CargoCarrier" >
<strong>CARGO_UNIT.CargoCarrier</strong>
</a>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>
@ -133,6 +134,8 @@ Use the method <a href="##(PATROLZONE).ManageFuel">PATROLZONE.ManageFuel</a>() t
<p>Hereby the change log:</p>
<p>2016-08-17: PATROLZONE:New( <strong>PatrolSpawn,</strong> PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed ) replaces PATROLZONE:New( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )</p>
<p>2016-07-01: Initial class and API.</p>
<hr/>
@ -142,13 +145,13 @@ Use the method <a href="##(PATROLZONE).ManageFuel">PATROLZONE.ManageFuel</a>() t
<h3>Contributions:</h3>
<ul>
<li>DutchBaron: Testing.</li>
<li><strong>DutchBaron</strong>: Testing.</li>
</ul>
<h3>Authors:</h3>
<ul>
<li>FlightControl: Design &amp; Programming</li>
<li><strong>FlightControl</strong>: Design &amp; Programming</li>
</ul>
@ -183,7 +186,7 @@ Use the method <a href="##(PATROLZONE).ManageFuel">PATROLZONE.ManageFuel</a>() t
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(PATROLZONE).New">PATROLZONE:New(PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</a></td>
<td class="name" nowrap="nowrap"><a href="##(PATROLZONE).New">PATROLZONE:New(PatrolSpawn, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</a></td>
<td class="summary">
<p>Creates a new PATROLZONE object, taking a <a href="Group.html">Group</a> object as a parameter.</p>
</td>
@ -276,12 +279,6 @@ Use the method <a href="##(PATROLZONE).ManageFuel">PATROLZONE.ManageFuel</a>() t
<td class="name" nowrap="nowrap"><a href="##(PATROLZONE).SetSpeed">PATROLZONE:SetSpeed(PatrolMinSpeed, PatrolMaxSpeed)</a></td>
<td class="summary">
<p>Sets (modifies) the minimum and maximum speed of the patrol.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(PATROLZONE).SpawnPatrolGroup">PATROLZONE.SpawnPatrolGroup</a></td>
<td class="summary">
</td>
</tr>
</table>
@ -385,7 +382,7 @@ self</p>
<dt>
<a id="#(PATROLZONE).New" >
<strong>PATROLZONE:New(PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</strong>
<strong>PATROLZONE:New(PatrolSpawn, PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed)</strong>
</a>
</dt>
<dd>
@ -399,6 +396,12 @@ self</p>
<ul>
<li>
<p><code><em><a href="Spawn.html##(SPAWN)">Spawn#SPAWN</a> PatrolSpawn </em></code>:
The <a href="SPAWN.html">SPAWN</a> object to spawn new group objects when required due to the fuel treshold.</p>
</li>
<li>
<p><code><em><a href="Zone.html##(ZONE_BASE)">Zone#ZONE_BASE</a> PatrolZone </em></code>:
The <a href="Zone.html">Zone</a> where the patrol needs to be executed.</p>
@ -436,8 +439,8 @@ self</p>
<h3>Usage:</h3>
<pre class="example"><code>-- Define a new 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.
PatrolZone = ZONE:New( 'PatrolZone' )
PatrolGroup = GROUP:FindByName( "Patrol Group" )
PatrolArea = PATROLZONE:New( PatrolGroup, PatrolZone, 3000, 6000, 600, 900 )</code></pre>
PatrolSpawn = SPAWN:New( "Patrol Group" )
PatrolArea = PATROLZONE:New( PatrolSpawn, PatrolZone, 3000, 6000, 600, 900 )</code></pre>
</dd>
</dl>
@ -704,20 +707,6 @@ The maximum speed of the <a href="Group.html">Group</a> in km/h.</p>
<p><em><a href="##(PATROLZONE)">#PATROLZONE</a>:</em>
self</p>
</dd>
</dl>
<dl class="function">
<dt>
<em></em>
<a id="#(PATROLZONE).SpawnPatrolGroup" >
<strong>PATROLZONE.SpawnPatrolGroup</strong>
</a>
</dt>
<dd>
</dd>
</dl>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>
@ -303,13 +304,13 @@ A coding example is provided at the description of the <a href="##(SPAWN).OnSpaw
<h3>Contributions:</h3>
<ul>
<li>Aaron: Posed the idea for Group position randomization at SpawnInZone and make the Unit randomization separate from the Group randomization.</li>
<li><strong>Aaron</strong>: Posed the idea for Group position randomization at SpawnInZone and make the Unit randomization separate from the Group randomization.</li>
</ul>
<h3>Authors:</h3>
<ul>
<li>FlightControl : Design &amp; Programming</li>
<li><strong>FlightControl</strong>: Design &amp; Programming</li>
</ul>
@ -856,7 +857,7 @@ A coding example is provided at the description of the <a href="##(SPAWN).OnSpaw
<tr>
<td class="name" nowrap="nowrap"><a href="##(SPAWN)._SpawnCleanUpScheduler">SPAWN:_SpawnCleanUpScheduler()</a></td>
<td class="summary">
<p>Schedules the CleanUp of Groups</p>
</td>
</tr>
<tr>
@ -1703,9 +1704,6 @@ The group that was spawned. You can use this group for further actions.</p>
<p> Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.</p>
</dd>
</dl>
<dl class="function">
@ -2500,7 +2498,7 @@ Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
<p> When the first Spawn executes, all the Groups need to be made visible before start.</p>
<p> Flag that indicates if all the Groups of the SpawnGroup need to be visible when Spawned.</p>
</dd>
</dl>
@ -3086,7 +3084,12 @@ self</p>
</dt>
<dd>
<p>Schedules the CleanUp of Groups</p>
<h3>Return value</h3>
<p><em>#boolean:</em>
True = Continue Scheduler</p>
</dd>
</dl>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>
@ -154,7 +155,13 @@ It is a fantastic development, this module.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(STATEMACHINE)._create_transition">STATEMACHINE:_create_transition(name)</a></td>
<td class="name" nowrap="nowrap"><a href="##(STATEMACHINE)._create_transition">STATEMACHINE:_create_transition(EventName)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(STATEMACHINE)._delayed_transition">STATEMACHINE:_delayed_transition(EventName)</a></td>
<td class="summary">
</td>
@ -163,6 +170,12 @@ It is a fantastic development, this module.</p>
<td class="name" nowrap="nowrap"><a href="##(STATEMACHINE)._gosub">STATEMACHINE:_gosub(parentstate, parentevent)</a></td>
<td class="summary">
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="##(STATEMACHINE)._handler">STATEMACHINE:_handler(EventName, ...)</a></td>
<td class="summary">
</td>
</tr>
<tr>
@ -426,7 +439,7 @@ It is a fantastic development, this module.</p>
<dt>
<a id="#(STATEMACHINE)._create_transition" >
<strong>STATEMACHINE:_create_transition(name)</strong>
<strong>STATEMACHINE:_create_transition(EventName)</strong>
</a>
</dt>
<dd>
@ -437,7 +450,28 @@ It is a fantastic development, this module.</p>
<ul>
<li>
<p><code><em> name </em></code>: </p>
<p><code><em> EventName </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(STATEMACHINE)._delayed_transition" >
<strong>STATEMACHINE:_delayed_transition(EventName)</strong>
</a>
</dt>
<dd>
<h3>Parameter</h3>
<ul>
<li>
<p><code><em> EventName </em></code>: </p>
</li>
</ul>
@ -472,6 +506,32 @@ It is a fantastic development, this module.</p>
<dl class="function">
<dt>
<a id="#(STATEMACHINE)._handler" >
<strong>STATEMACHINE:_handler(EventName, ...)</strong>
</a>
</dt>
<dd>
<h3>Parameters</h3>
<ul>
<li>
<p><code><em> EventName </em></code>: </p>
</li>
<li>
<p><code><em> ... </em></code>: </p>
</li>
</ul>
</dd>
</dl>
<dl class="function">
<dt>
<a id="#(STATEMACHINE)._isendstate" >
<strong>STATEMACHINE:_isendstate(state)</strong>
</a>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>
@ -89,6 +90,12 @@
<td class="name" nowrap="nowrap"><a href="AIBalancer.html">AIBalancer</a></td>
<td class="summary">
<p>This module contains the AIBALANCER class.</p>
</td>
</tr>
<tr>
<td class="name" nowrap="nowrap"><a href="AI_PatrolZone.html">AI_PatrolZone</a></td>
<td class="summary">
<p>This module contains the AI_PATROLZONE class.</p>
</td>
</tr>
<tr>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>

View File

@ -18,6 +18,7 @@
</li></ul>
<ul>
<li><a href="AIBalancer.html">AIBalancer</a></li>
<li><a href="AI_PatrolZone.html">AI_PatrolZone</a></li>
<li><a href="Airbase.html">Airbase</a></li>
<li><a href="AirbasePolice.html">AirbasePolice</a></li>
<li><a href="Base.html">Base</a></li>