diff --git a/Moose Development/Moose/AI/AI_CAP.lua b/Moose Development/Moose/AI/AI_CAP.lua index 497690e81..155b5284e 100644 --- a/Moose Development/Moose/AI/AI_CAP.lua +++ b/Moose Development/Moose/AI/AI_CAP.lua @@ -54,12 +54,15 @@ -- -- ### 1.2.2) AI_CAP_ZONE Events -- --- * **Start** ( Group ): Start the process. --- * **Route** ( Group ): Route the AI to a new random 3D point within the Patrol Zone. --- * **Engage** ( Group ): Let the AI engage the bogeys. --- * **RTB** ( Group ): Route the AI to the home base. --- * **Detect** ( Group ): The AI is detecting targets. --- * **Detected** ( Group ): The AI has detected new targets. +-- * **@{AI_Patrol#AI_PATROL_ZONE.Start}**: Start the process. +-- * **@{AI_Patrol#AI_PATROL_ZONE.Route}**: Route the AI to a new random 3D point within the Patrol Zone. +-- * **@{#AI_CAP_ZONE.Engage}**: Let the AI engage the bogeys. +-- * **@{#AI_CAP_ZONE.Abort}**: Aborts the engagement and return patrolling in the patrol zone. +-- * **@{AI_Patrol#AI_PATROL_ZONE.RTB}**: Route the AI to the home base. +-- * **@{AI_Patrol#AI_PATROL_ZONE.Detect}**: The AI is detecting targets. +-- * **@{AI_Patrol#AI_PATROL_ZONE.Detected}**: The AI has detected new targets. +-- * **@{#AI_CAP_ZONE.Destroy}**: The AI has destroyed a bogey @{Unit}. +-- * **@{#AI_CAP_ZONE.Destroyed}**: The AI has destroyed all bogeys @{Unit}s assigned in the CAS task. -- * **Status** ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB. -- -- ## 1.3) Set the Range of Engagement @@ -395,6 +398,18 @@ function AI_CAP_ZONE:onafterDetected( Controllable, From, Event, To ) end +--- @param #AI_CAP_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +function AI_CAP_ZONE:onafterAbort( Controllable, From, Event, To ) + Controllable:ClearTasks() + self:__Route( 1 ) +end + + + --- @param #AI_CAP_ZONE self -- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. diff --git a/Moose Development/Moose/AI/AI_CAS.lua b/Moose Development/Moose/AI/AI_CAS.lua index 8be2eac0b..16d870188 100644 --- a/Moose Development/Moose/AI/AI_CAS.lua +++ b/Moose Development/Moose/AI/AI_CAS.lua @@ -83,6 +83,7 @@ -- * **@{AI_Patrol#AI_PATROL_ZONE.Start}**: Start the process. -- * **@{AI_Patrol#AI_PATROL_ZONE.Route}**: Route the AI to a new random 3D point within the Patrol Zone. -- * **@{#AI_CAS_ZONE.Engage}**: Engage the AI to provide CAS in the Engage Zone, destroying any target it finds. +-- * **@{#AI_CAS_ZONE.Abort}**: Aborts the engagement and return patrolling in the patrol zone. -- * **@{AI_Patrol#AI_PATROL_ZONE.RTB}**: Route the AI to the home base. -- * **@{AI_Patrol#AI_PATROL_ZONE.Detect}**: The AI is detecting targets. -- * **@{AI_Patrol#AI_PATROL_ZONE.Detected}**: The AI has detected new targets. @@ -411,6 +412,15 @@ function AI_CAS_ZONE:onafterTarget( Controllable, From, Event, To ) end +--- @param #AI_CAS_ZONE self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. +-- @param #string From The From State string. +-- @param #string Event The Event string. +-- @param #string To The To State string. +function AI_CAS_ZONE:onafterAbort( Controllable, From, Event, To ) + Controllable:ClearTasks() + self:__Route( 1 ) +end --- @param #AI_CAS_ZONE self -- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM. diff --git a/Moose Development/Moose/Functional/Spawn.lua b/Moose Development/Moose/Functional/Spawn.lua index 85e2f9fbd..64d8855b1 100644 --- a/Moose Development/Moose/Functional/Spawn.lua +++ b/Moose Development/Moose/Functional/Spawn.lua @@ -44,12 +44,14 @@ -- -- A spawn object will behave differently based on the usage of **initialization** methods, which all start with the **Init** prefix: -- +-- * @{#SPAWN.InitKeepUnitNames}(): Keeps the unit names as defined within the mission editor, but note that anything after a # mark is ignored, and any spaces before and after the resulting name are removed. IMPORTANT! This method MUST be the first used after :New !!! -- * @{#SPAWN.InitLimit}(): Limits the amount of groups that can be alive at the same time and that can be dynamically spawned. -- * @{#SPAWN.InitRandomizeRoute}(): Randomize the routes of spawned groups, and for air groups also optionally the height. -- * @{#SPAWN.InitRandomizeTemplate}(): Randomize the group templates so that when a new group is spawned, a random group template is selected from one of the templates defined. -- * @{#SPAWN.InitUnControlled}(): Spawn plane groups uncontrolled. -- * @{#SPAWN.InitArray}(): Make groups visible before they are actually activated, and order these groups like a batallion in an array. -- * @{#SPAWN.InitRepeat}(): Re-spawn groups when they land at the home base. Similar methods are @{#SPAWN.InitRepeatOnLanding} and @{#SPAWN.InitRepeatOnEngineShutDown}. +-- * @{#SPAWN.InitRandomizePosition}(): Randomizes the position of @{Group}s that are spawned within a **radius band**, given an Outer and Inner radius, from the point that the spawn happens. -- * @{#SPAWN.InitRandomizeUnits}(): Randomizes the @{Unit}s in the @{Group} that is spawned within a **radius band**, given an Outer and Inner radius. -- * @{#SPAWN.InitRandomizeZones}(): Randomizes the spawning between a predefined list of @{Zone}s that are declared using this function. Each zone can be given a probability factor. -- * @{#SPAWN.InitAIOn}(): Turns the AI On when spawning the new @{Group} object. @@ -117,6 +119,9 @@ -- -- Hereby the change log: -- +-- 2017-03-14: SPAWN:**InitKeepUnitNames()** added. +-- 2017-03-14: SPAWN:**InitRandomizePosition( RandomizePosition, OuterRadious, InnerRadius )** added. +-- -- 2017-02-04: SPAWN:InitUnControlled( **UnControlled** ) replaces SPAWN:InitUnControlled(). -- -- 2017-01-24: SPAWN:**InitAIOnOff( AIOnOff )** added. @@ -214,12 +219,14 @@ function SPAWN:New( SpawnTemplatePrefix ) self.SpawnTemplate = self._GetTemplate( self, SpawnTemplatePrefix ) -- Contains the template structure for a Group Spawn from the Mission Editor. Note that this group must have lateActivation always on!!! self.Repeat = false -- Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning. self.UnControlled = false -- When working in UnControlled mode, all planes are Spawned in UnControlled mode before the scheduler starts. + self.SpawnInitLimit = false -- By default, no InitLimit self.SpawnMaxUnitsAlive = 0 -- The maximum amount of groups that can be alive of SpawnTemplatePrefix at the same time. self.SpawnMaxGroups = 0 -- The maximum amount of groups that can be spawned. self.SpawnRandomize = false -- Sets the randomization flag of new Spawned units to false. self.SpawnVisible = false -- Flag that indicates if all the Groups of the SpawnGroup need to be visible when Spawned. self.AIOnOff = true -- The AI is on by default when spawning a group. self.SpawnUnControlled = false + self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name. self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned. else @@ -253,12 +260,14 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix ) self.SpawnTemplate = self._GetTemplate( self, SpawnTemplatePrefix ) -- Contains the template structure for a Group Spawn from the Mission Editor. Note that this group must have lateActivation always on!!! self.Repeat = false -- Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning. self.UnControlled = false -- When working in UnControlled mode, all planes are Spawned in UnControlled mode before the scheduler starts. + self.SpawnInitLimit = false -- By default, no InitLimit self.SpawnMaxUnitsAlive = 0 -- The maximum amount of groups that can be alive of SpawnTemplatePrefix at the same time. self.SpawnMaxGroups = 0 -- The maximum amount of groups that can be spawned. self.SpawnRandomize = false -- Sets the randomization flag of new Spawned units to false. self.SpawnVisible = false -- Flag that indicates if all the Groups of the SpawnGroup need to be visible when Spawned. self.AIOnOff = true -- The AI is on by default when spawning a group. self.SpawnUnControlled = false + self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name. self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned. else @@ -287,6 +296,7 @@ end function SPAWN:InitLimit( SpawnMaxUnitsAlive, SpawnMaxGroups ) self:F( { self.SpawnTemplatePrefix, SpawnMaxUnitsAlive, SpawnMaxGroups } ) + self.SpawnInitLimit = true self.SpawnMaxUnitsAlive = SpawnMaxUnitsAlive -- The maximum amount of groups that can be alive of SpawnTemplatePrefix at the same time. self.SpawnMaxGroups = SpawnMaxGroups -- The maximum amount of groups that can be spawned. @@ -297,6 +307,20 @@ function SPAWN:InitLimit( SpawnMaxUnitsAlive, SpawnMaxGroups ) return self end +--- Keeps the unit names as defined within the mission editor, +-- but note that anything after a # mark is ignored, +-- and any spaces before and after the resulting name are removed. +-- IMPORTANT! This method MUST be the first used after :New !!! +-- @param #SPAWN self +-- @return #SPAWN self +function SPAWN:InitKeepUnitNames() + self:F( ) + + self.SpawnInitKeepUnitNames = true + + return self +end + --- Randomizes the defined route of the SpawnTemplatePrefix group in the ME. This is very useful to define extra variation of the behaviour of groups. -- @param #SPAWN self @@ -329,6 +353,27 @@ function SPAWN:InitRandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius, return self end +--- Randomizes the position of @{Group}s that are spawned within a **radius band**, given an Outer and Inner radius, from the point that the spawn happens. +-- @param #SPAWN self +-- @param #boolean RandomizePosition If true, SPAWN will perform the randomization of the @{Group}s position between a given outer and inner radius. +-- @param Dcs.DCSTypes#Distance OuterRadius (optional) The outer radius in meters where the new group will be spawned. +-- @param Dcs.DCSTypes#Distance InnerRadius (optional) The inner radius in meters where the new group will NOT be spawned. +-- @return #SPAWN +function SPAWN:InitRandomizePosition( RandomizePosition, OuterRadius, InnerRadius ) + self:F( { self.SpawnTemplatePrefix, RandomizePosition, OuterRadius, InnerRadius } ) + + self.SpawnRandomizePosition = RandomizePosition or false + self.SpawnRandomizePositionOuterRadius = OuterRadius or 0 + self.SpawnRandomizePositionInnerRadius = InnerRadius or 0 + + for GroupID = 1, self.SpawnMaxGroups do + self:_RandomizeRoute( GroupID ) + end + + return self +end + + --- Randomizes the UNITs that are spawned within a radius band given an Outer and Inner radius. -- @param #SPAWN self -- @param #boolean RandomizeUnits If true, SPAWN will perform the randomization of the @{UNIT}s position within the group between a given outer and inner radius. @@ -645,6 +690,20 @@ function SPAWN:SpawnWithIndex( SpawnIndex ) local PointVec3 = POINT_VEC3:New( SpawnTemplate.route.points[1].x, SpawnTemplate.route.points[1].alt, SpawnTemplate.route.points[1].y ) self:T( { "Current point of ", self.SpawnTemplatePrefix, PointVec3 } ) + + -- If RandomizePosition, then Randomize the formation in the zone band, keeping the template. + if self.SpawnRandomizePosition then + local RandomVec2 = PointVec3:GetRandomVec2InRadius( self.SpawnRandomizePositionOuterRadius, self.SpawnRandomizePositionInnerRadius ) + local CurrentX = SpawnTemplate.units[1].x + local CurrentY = SpawnTemplate.units[1].y + SpawnTemplate.x = RandomVec2.x + SpawnTemplate.y = RandomVec2.y + for UnitID = 1, #SpawnTemplate.units do + SpawnTemplate.units[UnitID].x = SpawnTemplate.units[UnitID].x + ( RandomVec2.x - CurrentX ) + SpawnTemplate.units[UnitID].y = SpawnTemplate.units[UnitID].y + ( RandomVec2.y - CurrentY ) + self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y ) + end + end -- If RandomizeUnits, then Randomize the formation at the start point. if self.SpawnRandomizeUnits then @@ -1088,7 +1147,8 @@ end function SPAWN:_GetPrefixFromDCSUnit( DCSUnit ) self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } ) - local DCSUnitName = ( DCSUnit and DCSUnit:getName() ) or nil + local DCSGroup = DCSUnit:getGroup() + local DCSUnitName = ( DCSGroup and DCSGroup:getName() ) or nil if DCSUnitName then local SpawnPrefix = string.match( DCSUnitName, ".*#" ) if SpawnPrefix then @@ -1142,6 +1202,7 @@ function SPAWN:_GetLastIndex() end --- Initalize the SpawnGroups collection. +-- @param #SPAWN self function SPAWN:_InitializeSpawnGroups( SpawnIndex ) self:F3( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } ) @@ -1245,11 +1306,20 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) SpawnTemplate.visible = false end - - for UnitID = 1, #SpawnTemplate.units do - SpawnTemplate.units[UnitID].name = string.format( SpawnTemplate.name .. '-%02d', UnitID ) - SpawnTemplate.units[UnitID].unitId = nil - end + if self.SpawnInitKeepUnitNames == false then + for UnitID = 1, #SpawnTemplate.units do + SpawnTemplate.units[UnitID].name = string.format( SpawnTemplate.name .. '-%02d', UnitID ) + SpawnTemplate.units[UnitID].unitId = nil + end + else + for UnitID = 1, #SpawnTemplate.units do + local UnitPrefix, Rest = string.match( SpawnTemplate.units[UnitID].name, "^([^#]+)#?" ):gsub( "^%s*(.-)%s*$", "%1" ) + self:T( { UnitPrefix, Rest } ) + + SpawnTemplate.units[UnitID].name = string.format( '%s#%03d-%02d', UnitPrefix, SpawnIndex, UnitID ) + SpawnTemplate.units[UnitID].unitId = nil + end + end self:T3( { "Template:", SpawnTemplate } ) return SpawnTemplate diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 3471d6d67..7b8af752a 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -222,6 +222,24 @@ end -- Tasks +--- Clear all tasks from the controllable. +-- @param #CONTROLLABLE self +-- @return #CONTROLLABLE +function CONTROLLABLE:ClearTasks() + self:F2() + + local DCSControllable = self:GetDCSObject() + + if DCSControllable then + local Controller = self:_GetController() + Controller:resetTask() + return self + end + + return nil +end + + --- Popping current Task from the controllable. -- @param #CONTROLLABLE self -- @return Wrapper.Controllable#CONTROLLABLE self diff --git a/Moose Test Missions/CAP - Combat Air Patrol/CAP-012 - CAP - Test Abort/CAP-012 - CAP - Test Abort.lua b/Moose Test Missions/CAP - Combat Air Patrol/CAP-012 - CAP - Test Abort/CAP-012 - CAP - Test Abort.lua new file mode 100644 index 000000000..b4f432c76 --- /dev/null +++ b/Moose Test Missions/CAP - Combat Air Patrol/CAP-012 - CAP - Test Abort/CAP-012 - CAP - Test Abort.lua @@ -0,0 +1,42 @@ +--- +-- Name: CAP-012 - CAP - Test Abort +-- Author: FlightControl +-- Date Created: 14 Mar 2017 +-- +-- # Situation: +-- +-- The Su-27 airplane will patrol in PatrolZone. +-- It will engage when it detects the airplane and when the A-10C is within the CapEngageZone. +-- It will abort the engagement after 1 minute and return to the patrol zone. +-- +-- # Test cases: +-- +-- 1. Observe the Su-27 patrolling. +-- 2. Observe that, when the A-10C is within the engage zone, it will engage. +-- 3. After engage, observe that the Su-27 returns to the PatrolZone. +-- 4. When it engages, it will abort the engagement after 1 minute. + + +local CapPlane = GROUP:FindByName( "Plane" ) + +local PatrolZone = ZONE:New( "Patrol Zone" ) + +local AICapZone = AI_CAP_ZONE:New( PatrolZone, 500, 1000, 500, 600 ) + +local EngageZoneGroup = GROUP:FindByName( "Engage Zone" ) + +local CapEngageZone = ZONE_POLYGON:New( "Engage Zone", EngageZoneGroup ) + +AICapZone:SetControllable( CapPlane ) +AICapZone:SetEngageZone( CapEngageZone ) -- Set the Engage Zone. The AI will only engage when the bogeys are within the CapEngageZone. + +AICapZone:__Start( 1 ) -- They should statup, and start patrolling in the PatrolZone. + +function AICapZone:OnAfterEngage(Controllable,From,Event,To) + AICapZone:__Abort( 60 ) +end + +function AICapZone:OnAfterAbort(Controllable,From,Event,To) + BASE:E("MISSION ABORTED! Returning to Patrol Zone!") + MESSAGE:New("MISSION ABORTED! Returning to Patrol Zone!",30,"ALERT!") +end \ No newline at end of file diff --git a/Moose Test Missions/CAP - Combat Air Patrol/CAP-012 - CAP - Test Abort/CAP-012 - CAP - Test Abort.miz b/Moose Test Missions/CAP - Combat Air Patrol/CAP-012 - CAP - Test Abort/CAP-012 - CAP - Test Abort.miz new file mode 100644 index 000000000..ba01dffb1 Binary files /dev/null and b/Moose Test Missions/CAP - Combat Air Patrol/CAP-012 - CAP - Test Abort/CAP-012 - CAP - Test Abort.miz differ diff --git a/Moose Test Missions/CAS - Close Air Support/CAS-004 - CAS in a Zone by Airplane Group - Test Abort/CAS-004 - CAS in a Zone by Airplane Group - Test Abort.lua b/Moose Test Missions/CAS - Close Air Support/CAS-004 - CAS in a Zone by Airplane Group - Test Abort/CAS-004 - CAS in a Zone by Airplane Group - Test Abort.lua new file mode 100644 index 000000000..052efd4ab --- /dev/null +++ b/Moose Test Missions/CAS - Close Air Support/CAS-004 - CAS in a Zone by Airplane Group - Test Abort/CAS-004 - CAS in a Zone by Airplane Group - Test Abort.lua @@ -0,0 +1,81 @@ +--- +-- Name: CAS-004 - CAS in a Zone by Airplane Group - Test Abort +-- Author: FlightControl +-- Date Created: 14 Mar 2017 +-- +-- # Situation: +-- +-- A group of 4 Su-25T at patrolling north of an engage zone for 1 minute. +-- After 10 minutes, the command center orders the Su-25T to engage the zone and execute a CAS. +-- After 12 minutes, the mission is aborted. +-- +-- # Test cases: +-- +-- 1. Observe that the Su-25T is patrolling in the patrol zone, until the engage command is given. +-- 2. The Su-25T are not detecting any target during the patrol. +-- 3. When the Su-25T is commanded to engage, the group will fly to the engage zone +-- 3.1. The approach speed to the engage zone is set to 350 km/h. +-- 3.2. The altitude to the engage zone and CAS execution is set to 4000 meters. +-- 4. Observe the mission being aborted. A message will be sent. +-- 5. The Su-25T will go back patrolling. + + + +-- Create a local variable (in this case called CASEngagementZone) and +-- using the ZONE function find the pre-defined zone called "Engagement Zone" +-- currently on the map and assign it to this variable +local CASEngagementZone = ZONE:New( "Engagement Zone" ) + +-- Create a local variable (in this case called CASPlane) and +-- using the GROUP function find the aircraft group called "Plane" and assign to this variable +local CASPlane = GROUP:FindByName( "Plane" ) + +-- Create a local Variable (in this cased called PatrolZone and +-- using the ZONE function find the pre-defined zone called "Patrol Zone" and assign it to this variable +local PatrolZone = ZONE:New( "Patrol Zone" ) + +-- Create and object (in this case called AICasZone) and +-- using the functions AI_CAS_ZONE assign the parameters that define this object +-- (in this case PatrolZone, 500, 1000, 500, 600, CASEngagementZone) +local AICasZone = AI_CAS_ZONE:New( PatrolZone, 500, 1000, 500, 600, CASEngagementZone ) + +-- Create an object (in this case called Targets) and +-- using the GROUP function find the group labeled "Targets" and assign it to this object +local Targets = GROUP:FindByName("Targets") + + +-- Tell the program to use the object (in this case called CASPlane) as the group to use in the CAS function +AICasZone:SetControllable( CASPlane ) + +-- Tell the group CASPlane to start the mission in 1 second. +AICasZone:__Start( 1 ) -- They should statup, and start patrolling in the PatrolZone. + +-- After 10 minutes, tell the group CASPlane to engage the targets located in the engagement zone called CASEngagement Zone. (600 is 600 seconds) +AICasZone:__Engage( 600, 350, 4000 ) -- Engage after 10 minutes with a speed of 350 km/h and an altitude of 4000 meters. + +-- After 12 minutes, tell the group CASPlane to abort the engagement. +AICasZone:__Abort( 720 ) -- Abort the engagement. + +-- Check every 60 seconds whether the Targets have been eliminated. +-- When the trigger completed has been fired, the Plane will go back to the Patrol Zone. +Check, CheckScheduleID = SCHEDULER:New(nil, + function() + if Targets:IsAlive() and Targets:GetSize() > 5 then + BASE:E( "Test Mission: " .. Targets:GetSize() .. " targets left to be destroyed.") + else + BASE:E( "Test Mission: The required targets are destroyed." ) + AICasZone:__Accomplish( 1 ) -- Now they should fly back to teh patrolzone and patrol. + end + end, {}, 20, 60, 0.2 ) + +function AICasZone:OnAfterAbort(Controllable,From,Event,To) + BASE:E( "MISSION ABORT! Back to patrol zone." ) + MESSAGE:New("Mission ABORTED! Back to the Patrol Zone!",30,"ALERT!"):ToAll() +end + +-- When the targets in the zone are destroyed, (see scheduled function), the planes will return home ... +function AICasZone:OnAfterAccomplish( Controllable, From, Event, To ) + BASE:E( "Test Mission: Sending the Su-25T back to base." ) + Check:Stop( CheckScheduleID ) + AICasZone:__RTB( 1 ) +end diff --git a/Moose Test Missions/CAS - Close Air Support/CAS-004 - CAS in a Zone by Airplane Group - Test Abort/CAS-004 - CAS in a Zone by Airplane Group - Test Abort.miz b/Moose Test Missions/CAS - Close Air Support/CAS-004 - CAS in a Zone by Airplane Group - Test Abort/CAS-004 - CAS in a Zone by Airplane Group - Test Abort.miz new file mode 100644 index 000000000..9582c7911 Binary files /dev/null and b/Moose Test Missions/CAS - Close Air Support/CAS-004 - CAS in a Zone by Airplane Group - Test Abort/CAS-004 - CAS in a Zone by Airplane Group - Test Abort.miz differ diff --git a/Moose Test Missions/SPA - Spawning/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names.lua b/Moose Test Missions/SPA - Spawning/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names.lua new file mode 100644 index 000000000..f3f1ad8d1 --- /dev/null +++ b/Moose Test Missions/SPA - Spawning/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names.lua @@ -0,0 +1,27 @@ +--- +-- Name: SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names +-- Author: FlightControl +-- Date Created: 14 Mar 2017 +-- +-- # Situation: +-- +-- At Gudauta spawn multiple ground vehicles, in a scheduled fashion. +-- +-- # Test cases: +-- +-- 1. Observe that the ground vehicles are spawned at the position declared within the mission editor. +-- 2. The vehicles should spawn according the scheduler parameters. +-- 3. There should not be more than 5 groups spawned. +-- 4. Observe the unit names, they should have the name as defined within the ME. + + + +-- Tests Gudauta +-- ------------- +Spawn_Vehicle_1 = SPAWN + :New( "Spawn Vehicle 1" ) + :InitKeepUnitNames() + :InitLimit( 5, 10 ) + :SpawnScheduled( 5, .5 ) + + diff --git a/Moose Test Missions/SPA - Spawning/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names.miz b/Moose Test Missions/SPA - Spawning/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names.miz new file mode 100644 index 000000000..85d9ddf3c Binary files /dev/null and b/Moose Test Missions/SPA - Spawning/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names/SPA-021 - Ground Ops - Scheduled Spawns Limited Keep Unit Names.miz differ diff --git a/Moose Test Missions/SPA - Spawning/SPA-350 - Spawn at Vec3 position RandomzePosition/SPA-350 - Spawn at Vec3 position RandomzePosition.lua b/Moose Test Missions/SPA - Spawning/SPA-350 - Spawn at Vec3 position RandomzePosition/SPA-350 - Spawn at Vec3 position RandomzePosition.lua new file mode 100644 index 000000000..e3ea49632 --- /dev/null +++ b/Moose Test Missions/SPA - Spawning/SPA-350 - Spawn at Vec3 position RandomzePosition/SPA-350 - Spawn at Vec3 position RandomzePosition.lua @@ -0,0 +1,73 @@ +--- +-- Name: SPA-350 - Spawn at Vec3 position RandomzePosition +-- Author: FlightControl +-- Date Created: 14 Mar 2017 +-- +-- # Situation: +-- +-- Ground troops, Airplanes, Helicopters and Ships are spawning from Vec3 points. +-- The API InitRandomizePosition is tested here, ensure that groups are replaced within a 900 to 1000 zone band at random positions. +-- +-- # Test cases: +-- +-- 1. Observe the random positioning of the groups. There should be no scattering of units. +-- + +local Iterations = 10 +local Iteration = 1 + +GroundZones = { "GroundZone1", "GroundZone2", "GroundZone3" } +GroundRandomizeZones = { "GroundRandomizeZone1", "GroundRandomizeZone2", "GroundRandomizeZone3" } +AirplaneZones = { "AirplaneZone1", "AirplaneZone2", "AirplaneZone3" } +HelicopterZones = { "HelicopterZone1", "HelicopterZone2", "HelicopterZone3" } +ShipZones = { "ShipZone1", "ShipZone2", "ShipZone3" } + +HeightLimit = 500 + +SpawnGrounds = SPAWN:New("Ground"):InitLimit( 20, 10 ):InitRandomizePosition( true , 1000, 900 ) +SpawnRandomizeGrounds = SPAWN:New("GroundRandomize"):InitLimit( 20, 10 ):InitRandomizePosition( true , 1000, 900 ) +SpawnAirplanes = SPAWN:New("Airplane"):InitLimit( 20, 10 ):InitRandomizePosition( true , 1000, 900 ) +SpawnHelicopters = SPAWN:New("Helicopter"):InitLimit( 20, 10 ):InitRandomizePosition( true , 1000, 900 ) +SpawnShips = SPAWN:New("Ship"):InitLimit( 20, 10 ):InitRandomizePosition( true , 1000, 900 ) + +--- Spawns these groups slowly. +SCHEDULER:New( nil, + + function( Interation, Iterations ) + do + -- Spawn Ground + local ZoneName = GroundZones[ math.random( 1, 3 ) ] + local SpawnVec3 = POINT_VEC3:NewFromVec3( ZONE:New( ZoneName ):GetVec3() ) + SpawnGrounds:SpawnFromVec3( SpawnVec3:GetVec3() ) + end + + do + -- Spawn Ground Randomize + local ZoneName = GroundRandomizeZones[ math.random( 1, 3 ) ] + local SpawnVec3 = POINT_VEC3:NewFromVec3( ZONE:New( ZoneName ):GetVec3() ) + SpawnRandomizeGrounds:SpawnFromVec3( SpawnVec3:GetVec3() ) + end + + do + -- Spawn Airplanes + local ZoneName = AirplaneZones[ math.random( 1, 3 ) ] + local SpawnVec3 = POINT_VEC3:NewFromVec3( ZONE:New( ZoneName ):GetVec3() ) + SpawnAirplanes:SpawnFromVec3( SpawnVec3:GetVec3() ) + end + + do + -- Spawn Helicopters + local ZoneName = HelicopterZones[ math.random( 1, 3 ) ] + local SpawnVec3 = POINT_VEC3:NewFromVec3( ZONE:New( ZoneName ):GetVec3() ) + SpawnHelicopters:SpawnFromVec3( SpawnVec3:GetVec3() ) + end + + do + -- Spawn Ships + local ZoneName = ShipZones[ math.random( 1, 3 ) ] + local SpawnVec3 = POINT_VEC3:NewFromVec3( ZONE:New( ZoneName ):GetVec3() ) + SpawnShips:SpawnFromVec3( SpawnVec3:GetVec3() ) + end + + end, {}, 0, 15, 0.5 +) diff --git a/Moose Test Missions/SPA - Spawning/SPA-350 - Spawn at Vec3 position RandomzePosition/SPA-350 - Spawn at Vec3 position RandomzePosition.miz b/Moose Test Missions/SPA - Spawning/SPA-350 - Spawn at Vec3 position RandomzePosition/SPA-350 - Spawn at Vec3 position RandomzePosition.miz new file mode 100644 index 000000000..6cf5ce6df Binary files /dev/null and b/Moose Test Missions/SPA - Spawning/SPA-350 - Spawn at Vec3 position RandomzePosition/SPA-350 - Spawn at Vec3 position RandomzePosition.miz differ diff --git a/docs/Documentation/AI_Cap.html b/docs/Documentation/AI_Cap.html index 7cc56e36f..3c943b3aa 100644 --- a/docs/Documentation/AI_Cap.html +++ b/docs/Documentation/AI_Cap.html @@ -135,12 +135,15 @@ When the fuel treshold has been reached, the airplane will fly towards the neare
Asynchronous Event Trigger for Event Fired.
+Wrapper.Controllable#CONTROLLABLE Controllable :
+The Controllable Object managed by the FSM.
#string From :
+The From State string.
#string Event :
+The Event string.
#string To :
+The To State string.
This table contains the targets detected during patrol.
-Clear all tasks from the controllable.
Clear all tasks from the controllable.
+ +A spawn object will behave differently based on the usage of initialization methods, which all start with the Init prefix:
CleanUp groups when they are still alive, but inactive.
+Keeps the unit names as defined within the mission editor, +but note that anything after a # mark is ignored, +and any spaces before and after the resulting name are removed.
Limits the Maximum amount of Units that can be alive at the same time, and the maximum amount of groups that can be spawned.
+Randomizes the position of Groups that are spawned within a radius band, given an Outer and Inner radius, from the point that the spawn happens.
Keeps the unit names as defined within the mission editor, +but note that anything after a # mark is ignored, +and any spaces before and after the resulting name are removed.
+ + +IMPORTANT! This method MUST be the first used after :New !!!
+ +#SPAWN: +self
+ +Randomizes the position of Groups that are spawned within a radius band, given an Outer and Inner radius, from the point that the spawn happens.
+ +#boolean RandomizePosition :
+If true, SPAWN will perform the randomization of the Groups position between a given outer and inner radius.
Dcs.DCSTypes#Distance OuterRadius :
+(optional) The outer radius in meters where the new group will be spawned.
Dcs.DCSTypes#Distance InnerRadius :
+(optional) The inner radius in meters where the new group will NOT be spawned.
By default, no InitLimit
+Sets the randomization flag of new Spawned units to false.
+ +