mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Documentation
This commit is contained in:
parent
081a79a277
commit
64c36c840b
@ -1,5 +1,5 @@
|
|||||||
--- BASE The base class for all the classes defined within MOOSE.
|
--- BASE The base class for all the classes defined within MOOSE.
|
||||||
-- @classmod BASE
|
-- @module BASE
|
||||||
-- @author Flightcontrol
|
-- @author Flightcontrol
|
||||||
|
|
||||||
Include.File( "Routines" )
|
Include.File( "Routines" )
|
||||||
@ -24,6 +24,10 @@ _TraceClass = {
|
|||||||
--CLEANUP = true,
|
--CLEANUP = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- The BASE Class
|
||||||
|
-- @type BASE
|
||||||
|
-- @field ClassName The name of the class.
|
||||||
|
-- @field ClassID The ID number of the class.
|
||||||
BASE = {
|
BASE = {
|
||||||
|
|
||||||
ClassName = "BASE",
|
ClassName = "BASE",
|
||||||
@ -31,9 +35,17 @@ BASE = {
|
|||||||
Events = {}
|
Events = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- The Formation Class
|
||||||
|
-- @type FORMATION
|
||||||
|
-- @field Cone A cone formation.
|
||||||
|
FORMATION = {
|
||||||
|
Cone = "Cone"
|
||||||
|
}
|
||||||
|
|
||||||
--- The base constructor. This is the top top class of all classed defined within the MOOSE.
|
--- The base constructor. This is the top top class of all classed defined within the MOOSE.
|
||||||
-- Any new class needs to be derived from this class for proper inheritance.
|
-- Any new class needs to be derived from this class for proper inheritance.
|
||||||
-- @treturn BASE
|
-- @param self
|
||||||
|
-- @return #BASE
|
||||||
-- @usage
|
-- @usage
|
||||||
-- function TASK:New()
|
-- function TASK:New()
|
||||||
-- trace.f(self.ClassName)
|
-- trace.f(self.ClassName)
|
||||||
|
|||||||
125
Moose/Group.lua
125
Moose/Group.lua
@ -1,6 +1,9 @@
|
|||||||
--- GROUP Classes
|
--- A GROUP class abstraction of a DCSGroup class.
|
||||||
|
-- The GROUP class will take an abstraction of the DCSGroup class, providing more methods that can be done with a GROUP.
|
||||||
|
--
|
||||||
|
--
|
||||||
-- @module GROUP
|
-- @module GROUP
|
||||||
-- @return #GROUP
|
-- @extends BASE#BASE
|
||||||
|
|
||||||
Include.File( "Routines" )
|
Include.File( "Routines" )
|
||||||
Include.File( "Base" )
|
Include.File( "Base" )
|
||||||
@ -9,13 +12,27 @@ Include.File( "Unit" )
|
|||||||
|
|
||||||
--- The GROUP class
|
--- The GROUP class
|
||||||
-- @type GROUP
|
-- @type GROUP
|
||||||
-- @field ClassName The name of the class.
|
-- @field #Group DCSGroup The DCS group class.
|
||||||
|
-- @field #string GroupName The name of the group.
|
||||||
|
-- @field #number GroupID the ID of the group.
|
||||||
|
-- @field #table Controller The controller of the group.
|
||||||
GROUP = {
|
GROUP = {
|
||||||
ClassName = "GROUP",
|
ClassName = "GROUP",
|
||||||
|
GroupName = "",
|
||||||
|
GroupID = 0,
|
||||||
|
Controller = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- A DCSGroup
|
||||||
|
-- @type Group
|
||||||
|
-- @field id_ The ID of the group in DCS
|
||||||
|
|
||||||
GROUPS = {}
|
GROUPS = {}
|
||||||
|
|
||||||
|
--- Create a new GROUP from a DCSGroup
|
||||||
|
-- @param self
|
||||||
|
-- @param #Group DCSGroup The DCS Group
|
||||||
|
-- @return #GROUP self
|
||||||
function GROUP:New( DCSGroup )
|
function GROUP:New( DCSGroup )
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:T( DCSGroup:getName() )
|
self:T( DCSGroup:getName() )
|
||||||
@ -29,6 +46,10 @@ function GROUP:New( DCSGroup )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Create a new GROUP from an existing DCSGroup in the mission.
|
||||||
|
-- @param self
|
||||||
|
-- @param GroupName The name of the DCS Group.
|
||||||
|
-- @return #GROUP self
|
||||||
function GROUP:NewFromName( GroupName )
|
function GROUP:NewFromName( GroupName )
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:T( GroupName )
|
self:T( GroupName )
|
||||||
@ -37,35 +58,52 @@ function GROUP:NewFromName( GroupName )
|
|||||||
if self.DCSGroup then
|
if self.DCSGroup then
|
||||||
self.GroupName = self.DCSGroup:getName()
|
self.GroupName = self.DCSGroup:getName()
|
||||||
self.GroupID = self.DCSGroup:getID()
|
self.GroupID = self.DCSGroup:getID()
|
||||||
|
self.Controller = DCSGroup:getController()
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the DCSGroup of the GROUP.
|
||||||
|
-- @param self
|
||||||
|
-- @return #Group The DCSGroup.
|
||||||
function GROUP:GetDCSGroup()
|
function GROUP:GetDCSGroup()
|
||||||
self:T( { self.GroupName } )
|
self:T( { self.GroupName } )
|
||||||
self.DCSGroup = Group.getByName( self.GroupName )
|
self.DCSGroup = Group.getByName( self.GroupName )
|
||||||
return self.DCSGroup
|
return self.DCSGroup
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Gets the DCS Unit of the GROUP.
|
||||||
|
-- @param self
|
||||||
|
-- @param #number UnitNumber The unit index to be returned from the GROUP.
|
||||||
|
-- @return #Unit The DCS Unit.
|
||||||
function GROUP:GetDCSUnit( UnitNumber )
|
function GROUP:GetDCSUnit( UnitNumber )
|
||||||
self:T( { self.GroupName, UnitNumber } )
|
self:T( { self.GroupName, UnitNumber } )
|
||||||
return self.DCSGroup:getUnit( UnitNumber )
|
return self.DCSGroup:getUnit( UnitNumber )
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Activates a GROUP.
|
||||||
|
-- @param self
|
||||||
function GROUP:Activate()
|
function GROUP:Activate()
|
||||||
self:T( { self.GroupName } )
|
self:T( { self.GroupName } )
|
||||||
trigger.action.activateGroup( self:GetDCSGroup() )
|
trigger.action.activateGroup( self:GetDCSGroup() )
|
||||||
return self:GetDCSGroup()
|
return self:GetDCSGroup()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the name of the GROUP.
|
||||||
|
-- @param self
|
||||||
|
-- @return #string The name of the GROUP.
|
||||||
function GROUP:GetName()
|
function GROUP:GetName()
|
||||||
self:T( self.GroupName )
|
self:T( self.GroupName )
|
||||||
|
|
||||||
return self.GroupName
|
return self.GroupName
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Gets the current Point of the GROUP in VEC2 format.
|
||||||
|
-- @return #Vec2 Current x and Y position of the group.
|
||||||
function GROUP:GetPoint()
|
function GROUP:GetPoint()
|
||||||
self:T( self.GroupName )
|
self:T( self.GroupName )
|
||||||
|
|
||||||
@ -74,7 +112,10 @@ function GROUP:GetPoint()
|
|||||||
return GroupPoint
|
return GroupPoint
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Destroy a GROUP
|
||||||
|
-- Note that this destroy method also raises a destroy event at run-time.
|
||||||
|
-- So all event listeners will catch the destroy event of this GROUP.
|
||||||
|
-- @param self
|
||||||
function GROUP:Destroy()
|
function GROUP:Destroy()
|
||||||
self:T( self.GroupName )
|
self:T( self.GroupName )
|
||||||
|
|
||||||
@ -87,13 +128,19 @@ end
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Gets the DCS Unit.
|
||||||
|
-- @param self
|
||||||
|
-- @param #number UnitNumber The number of the Unit to be returned.
|
||||||
|
-- @return #Unit The DCS Unit.
|
||||||
function GROUP:GetUnit( UnitNumber )
|
function GROUP:GetUnit( UnitNumber )
|
||||||
self:T( { self.GroupName, UnitNumber } )
|
self:T( { self.GroupName, UnitNumber } )
|
||||||
return UNIT:New( self.DCSGroup:getUnit( UnitNumber ) )
|
return UNIT:New( self.DCSGroup:getUnit( UnitNumber ) )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns if the group is of an air category.
|
||||||
|
-- If the group is a helicopter or a plane, then this method will return true, otherwise false.
|
||||||
|
-- @param self
|
||||||
|
-- @return #boolean Air category evaluation result.
|
||||||
function GROUP:IsAir()
|
function GROUP:IsAir()
|
||||||
self:T()
|
self:T()
|
||||||
|
|
||||||
@ -103,6 +150,10 @@ self:T()
|
|||||||
return IsAirResult
|
return IsAirResult
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns if the group is alive.
|
||||||
|
-- When the group exists at run-time, this method will return true, otherwise false.
|
||||||
|
-- @param self
|
||||||
|
-- @return #boolean Alive result.
|
||||||
function GROUP:IsAlive()
|
function GROUP:IsAlive()
|
||||||
self:T()
|
self:T()
|
||||||
|
|
||||||
@ -112,7 +163,10 @@ self:T()
|
|||||||
return IsAliveResult
|
return IsAliveResult
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns if all units of the group are on the ground or landed.
|
||||||
|
-- If all units of this group are on the ground, this function will return true, otherwise false.
|
||||||
|
-- @param self
|
||||||
|
-- @return #boolean All units on the ground result.
|
||||||
function GROUP:AllOnGround()
|
function GROUP:AllOnGround()
|
||||||
self:T()
|
self:T()
|
||||||
|
|
||||||
@ -128,9 +182,12 @@ self:T()
|
|||||||
return AllOnGroundResult
|
return AllOnGroundResult
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns the current maximum velocity of the group.
|
||||||
|
-- Each unit within the group gets evaluated, and the maximum velocity (= the unit which is going the fastest) is returned.
|
||||||
|
-- @param self
|
||||||
|
-- @return #number Maximum velocity found.
|
||||||
function GROUP:GetMaxVelocity()
|
function GROUP:GetMaxVelocity()
|
||||||
self:T()
|
self:T()
|
||||||
|
|
||||||
local MaxVelocity = 0
|
local MaxVelocity = 0
|
||||||
|
|
||||||
@ -148,13 +205,31 @@ self:T()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function GROUP:GetHeight()
|
--- Returns the current minimum height of the group.
|
||||||
self:T()
|
-- Each unit within the group gets evaluated, and the minimum height (= the unit which is the lowest elevated) is returned.
|
||||||
|
-- @param self
|
||||||
|
-- @return #number Minimum height found.
|
||||||
|
function GROUP:GetMinHeight()
|
||||||
|
self:T()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Returns the current maximum height of the group.
|
||||||
|
-- Each unit within the group gets evaluated, and the maximum height (= the unit which is the highest elevated) is returned.
|
||||||
|
-- @param self
|
||||||
|
-- @return #number Maximum height found.
|
||||||
|
function GROUP:GetMaxHeight()
|
||||||
|
self:T()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Land the group at a Vec2Point.
|
||||||
|
-- @param self
|
||||||
|
-- @param #Vec2 Point The point where to land.
|
||||||
|
-- @param #number Duration The duration in seconds to stay on the ground.
|
||||||
|
-- @return #GROUP self
|
||||||
function GROUP:Land( Point, Duration )
|
function GROUP:Land( Point, Duration )
|
||||||
trace.f( self.ClassName, { self.GroupName, Point, Duration } )
|
trace.f( self.ClassName, { self.GroupName, Point, Duration } )
|
||||||
|
|
||||||
@ -169,7 +244,12 @@ trace.f( self.ClassName, { self.GroupName, Point, Duration } )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Move the group to a Vec2 Point, wait for a defined duration and embark a group.
|
||||||
|
-- @param self
|
||||||
|
-- @param #Vec2 Point The point where to wait.
|
||||||
|
-- @param #number Duration The duration in seconds to wait.
|
||||||
|
-- @param EmbarkingGroup The group to be embarked.
|
||||||
|
-- @return #GROUP self
|
||||||
function GROUP:Embarking( Point, Duration, EmbarkingGroup )
|
function GROUP:Embarking( Point, Duration, EmbarkingGroup )
|
||||||
trace.f( self.ClassName, { self.GroupName, Point, Duration, EmbarkingGroup.DCSGroup } )
|
trace.f( self.ClassName, { self.GroupName, Point, Duration, EmbarkingGroup.DCSGroup } )
|
||||||
|
|
||||||
@ -194,7 +274,11 @@ trace.f( self.ClassName, { self.GroupName, Point, Duration, EmbarkingGroup.DCSGr
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Move to a defined Vec2 Point, and embark to a group when arrived within a defined Radius.
|
||||||
|
-- @param self
|
||||||
|
-- @param #Vec2 Point The point where to wait.
|
||||||
|
-- @param #number Radius The radius of the embarking zone around the Point.
|
||||||
|
-- @return #GROUP self
|
||||||
function GROUP:EmbarkToTransport( Point, Radius )
|
function GROUP:EmbarkToTransport( Point, Radius )
|
||||||
trace.f( self.ClassName, { self.GroupName, Point, Radius } )
|
trace.f( self.ClassName, { self.GroupName, Point, Radius } )
|
||||||
|
|
||||||
@ -211,6 +295,10 @@ trace.f( self.ClassName, { self.GroupName, Point, Radius } )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Make the group to follow a given route.
|
||||||
|
-- @param self
|
||||||
|
-- @param #table GoPoints A table of Route Points.
|
||||||
|
-- @return #GROUP self
|
||||||
function GROUP:Route( GoPoints )
|
function GROUP:Route( GoPoints )
|
||||||
self:T( GoPoints )
|
self:T( GoPoints )
|
||||||
|
|
||||||
@ -224,6 +312,15 @@ self:T( GoPoints )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Route the group to a given zone.
|
||||||
|
-- The group final destination point can be randomized.
|
||||||
|
-- A speed can be given in km/h.
|
||||||
|
-- A given formation can be given.
|
||||||
|
-- @param self
|
||||||
|
-- @param ZONE#ZONE Zone The zone where to route to.
|
||||||
|
-- @param #boolean Randomize Defines whether to target point gets randomized within the Zone.
|
||||||
|
-- @param #number Speed The speed.
|
||||||
|
-- @param BASE#FORMATION Formation The formation string.
|
||||||
function GROUP:RouteToZone( Zone, Randomize, Speed, Formation )
|
function GROUP:RouteToZone( Zone, Randomize, Speed, Formation )
|
||||||
self:T( Zone )
|
self:T( Zone )
|
||||||
|
|
||||||
|
|||||||
750
Moose/Spawn.lua
750
Moose/Spawn.lua
@ -1,23 +1,38 @@
|
|||||||
--- Dynamic spawning of groups and units.
|
--- Dynamic spawning of groups (and units).
|
||||||
-- SPAWN: The SPAWN module allows to spawn dynamically new groups, based on pre-defined initialization settings.
|
-- The SPAWN class allows to spawn dynamically new groups, based on pre-defined initialization settings, modifying the behaviour when groups are spawned.
|
||||||
-- =============================================================================================================
|
-- For each group to be spawned, within the mission editor, a group has to be created with the "late activation flag" set. We call this group the *"Spawn Template"* of the SPAWN object.
|
||||||
-- Spawned groups will follow the following naming convention when instantiated within the DCS World run-time environment:
|
-- A reference to this Spawn Template needs to be provided when constructing the SPAWN object, by indicating the name of the group within the mission editor in the constructor methods.
|
||||||
--
|
--
|
||||||
-- 1. Groups will have the name SpawnTemplatePrefix#ggg, where ggg is a counter from 0 to 999 for each new spawned Group.
|
-- Within the SPAWN object, there is an internal index that keeps track of which group from the internal group list was spawned.
|
||||||
-- 2. Units will have the name SpawnTemplatePrefix#ggg-uu, where uu is a counter from 0 to 99 for each new spawned Unit belonging to that Group.
|
-- When new groups get spawned by using the SPAWN functions (see below), it will be validated whether the Limits (@{#SPAWN.Limit}) of the SPAWN object are not reached.
|
||||||
|
-- When all is valid, a new group will be created by the spawning methods, and the internal index will be increased with 1.
|
||||||
|
--
|
||||||
|
-- Regarding the name of new spawned groups, a _SpawnPrefix_ will be assigned for each new group created.
|
||||||
|
-- If you want to have the Spawn Template name to be used as the _SpawnPrefix_ name, use the @{#SPAWN.New} constructor.
|
||||||
|
-- However, when the @{#SPAWN.NewWithAlias} constructor was used, the Alias name will define the _SpawnPrefix_ name.
|
||||||
|
-- Groups will follow the following naming structure when spawned at run-time:
|
||||||
|
--
|
||||||
|
-- 1. Spawned groups will have the name _SpawnPrefix_#ggg, where ggg is a counter from 0 to 999.
|
||||||
|
-- 2. Spawned units will have the name _SpawnPrefix_#ggg-uu, where uu is a counter from 0 to 99 for each new spawned unit belonging to the group.
|
||||||
--
|
--
|
||||||
-- Some additional notes that need to be remembered:
|
-- Some additional notes that need to be remembered:
|
||||||
--
|
--
|
||||||
-- * Templates are actually groups defined within the mission editor, with the flag "Late Activation" set. As such, these groups are never used within the mission, but are used by the @{#SPAWN} module.
|
-- * Templates are actually groups defined within the mission editor, with the flag "Late Activation" set. As such, these groups are never used within the mission, but are used by the @{#SPAWN} module.
|
||||||
-- * It is important to defined BEFORE you spawn new groups, a proper initialization of the SPAWN instance is done with the options you want to use.
|
-- * It is important to defined BEFORE you spawn new groups, a proper initialization of the SPAWN instance is done with the options you want to use.
|
||||||
-- * When designing a mission, NEVER name groups using a "#" within the name of the group Template(s), or the SPAWN module logic won't work anymore.
|
-- * When designing a mission, NEVER name groups using a "#" within the name of the group Spawn Template(s), or the SPAWN module logic won't work anymore.
|
||||||
--
|
--
|
||||||
-- 1. Construction:
|
-- 1. SPAWN object construction methods:
|
||||||
-- ----------------
|
-- -------------------------------------
|
||||||
-- Create a new @{SPAWN object with the @{#SPAWN.New} and the @{#SPAWN.NewWithAlias} methods.
|
-- Create a new SPAWN object with the @{#SPAWN.New} or the @{#SPAWN.NewWithAlias} methods:
|
||||||
|
--
|
||||||
|
-- * @{#SPAWN.New}: Creates a new SPAWN object taking the name of the group that functions as the Template.
|
||||||
--
|
--
|
||||||
-- 2. Initialization of the SPAWN object.
|
-- It is important to understand how the SPAWN class works internally. The SPAWN object created will contain internally a list of groups that will be spawned and that are already spawned.
|
||||||
-- ------------------
|
-- The initialization functions will modify this list of groups so that when a group gets spawned, ALL information is already prepared when spawning. This is done for performance reasons.
|
||||||
|
-- So in principle, the group list will contain all parameters and configurations after initialization, and when groups get actually spawned, this spawning can be done quickly and efficient.
|
||||||
|
--
|
||||||
|
-- 2. SPAWN object initialization methods:
|
||||||
|
-- ---------------------------------------
|
||||||
-- A spawn object will behave differently based on the usage of initialization methods:
|
-- A spawn object will behave differently based on the usage of initialization methods:
|
||||||
--
|
--
|
||||||
-- * @{#SPAWN.Limit}: Limits the amount of groups that can be alive at the same time and that can be dynamically spawned.
|
-- * @{#SPAWN.Limit}: Limits the amount of groups that can be alive at the same time and that can be dynamically spawned.
|
||||||
@ -27,31 +42,46 @@
|
|||||||
-- * @{#SPAWN.Array}: Make groups visible before they are actually activated, and order these groups like a batallion in an array.
|
-- * @{#SPAWN.Array}: Make groups visible before they are actually activated, and order these groups like a batallion in an array.
|
||||||
-- * @{#SPAWN.Repeat}: Re-spawn groups when they land at the home base. Similar functions are @{#SPAWN.RepeatOnLanding} and @{#SPAWN.RepeatOnEngineShutDown}.
|
-- * @{#SPAWN.Repeat}: Re-spawn groups when they land at the home base. Similar functions are @{#SPAWN.RepeatOnLanding} and @{#SPAWN.RepeatOnEngineShutDown}.
|
||||||
--
|
--
|
||||||
-- 2. Spawning groups
|
-- 2. SPAWN object spawning methods:
|
||||||
-- ------------------------------
|
-- ---------------------------------
|
||||||
-- Groups can be spawned at different times and methods:
|
-- Groups can be spawned at different times and methods:
|
||||||
--
|
--
|
||||||
-- * @{#SPAWN.Spawn}: Spawn one new group based on the last spawned index.
|
-- * @{#SPAWN.Spawn}: Spawn one new group based on the last spawned index.
|
||||||
-- * @{#SPAWN.ReSpawn}: Re-spawn a group based on a given index.
|
-- * @{#SPAWN.ReSpawn}: Re-spawn a group based on a given index.
|
||||||
-- * @{#SPAWN.SpawnScheduled}: Spawn groups at scheduled but randomized intervals. You can use @{#SPAWN.ScheduleStart} and @{#SPAWN.ScheduleStop} to start and stop the schedule respectively.
|
-- * @{#SPAWN.SpawnScheduled}: Spawn groups at scheduled but randomized intervals. You can use @{#SPAWN.SpawnScheduleStart} and @{#SPAWN.SpawnScheduleStop} to start and stop the schedule respectively.
|
||||||
|
-- * @{#SPAWN.SpawnFromUnit}: Spawn a new group taking the position of a @{UNIT}.
|
||||||
|
-- * @{#SPAWN.SpawnInZone}: Spawn a new group in a @{ZONE}.
|
||||||
|
--
|
||||||
|
-- Note that @{#SPAWN.Spawn} and @{#SPAWN.ReSpawn} return a @{GROUP#GROUP.New} object, that contains a reference to the DCSGroup object.
|
||||||
|
-- You can use the @{GROUP} object to do further actions with the DCSGroup.
|
||||||
|
--
|
||||||
|
-- 3. SPAWN object cleaning:
|
||||||
|
-- -------------------------
|
||||||
|
-- Sometimes, it will occur during a mission run-time, that ground or especially air objects get damaged, and will while being damged stop their activities, while remaining alive.
|
||||||
|
-- In such cases, the SPAWN object will just sit there and wait until that group gets destroyed, but most of the time it won't,
|
||||||
|
-- and it may occur that no new groups are or can be spawned as limits are reached.
|
||||||
|
-- To prevent this, a @{#SPAWN.CleanUp} initialization method has been defined that will silently monitor the status of each spawned group.
|
||||||
|
-- Once a group has a velocity = 0, and has been waiting for a defined interval, that group will be cleaned or removed from run-time.
|
||||||
|
-- There is a catch however :-) If a damaged group has returned to an airbase within the coalition, that group will not be considered as "lost"...
|
||||||
|
-- In such a case, when the inactive group is cleaned, a new group will Re-spawned automatically.
|
||||||
|
-- This models AI that has succesfully returned to their airbase, to restart their combat activities.
|
||||||
|
-- Check the @{#SPAWN.CleanUp} for further info.
|
||||||
--
|
--
|
||||||
-- @module SPAWN
|
-- @module SPAWN
|
||||||
-- @author FlightControl
|
-- @author FlightControl
|
||||||
|
|
||||||
|
|
||||||
---
|
|
||||||
-- @type SPAWN
|
|
||||||
-- @field ClassName Contains SPAWN
|
|
||||||
SPAWN = {
|
|
||||||
ClassName = "SPAWN",
|
|
||||||
}
|
|
||||||
|
|
||||||
Include.File( "Routines" )
|
Include.File( "Routines" )
|
||||||
Include.File( "Base" )
|
Include.File( "Base" )
|
||||||
Include.File( "Database" )
|
Include.File( "Database" )
|
||||||
Include.File( "Group" )
|
Include.File( "Group" )
|
||||||
Include.File( "Zone" )
|
Include.File( "Zone" )
|
||||||
|
|
||||||
|
--- SPAWN Class
|
||||||
|
-- @type SPAWN
|
||||||
|
-- @field ClassName
|
||||||
|
SPAWN = {
|
||||||
|
ClassName = "SPAWN",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -87,9 +117,9 @@ function SPAWN:New( SpawnTemplatePrefix )
|
|||||||
error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" )
|
error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" )
|
||||||
end
|
end
|
||||||
|
|
||||||
self.AddEvent( self, world.event.S_EVENT_BIRTH, self.OnBirth )
|
self.AddEvent( self, world.event.S_EVENT_BIRTH, self._OnBirth )
|
||||||
self.AddEvent( self, world.event.S_EVENT_DEAD, self.OnDeadOrCrash )
|
self.AddEvent( self, world.event.S_EVENT_DEAD, self._OnDeadOrCrash )
|
||||||
self.AddEvent( self, world.event.S_EVENT_CRASH, self.OnDeadOrCrash )
|
self.AddEvent( self, world.event.S_EVENT_CRASH, self._OnDeadOrCrash )
|
||||||
|
|
||||||
self.EnableEvents( self )
|
self.EnableEvents( self )
|
||||||
|
|
||||||
@ -130,9 +160,9 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
|
|||||||
error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" )
|
error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" )
|
||||||
end
|
end
|
||||||
|
|
||||||
self.AddEvent( self, world.event.S_EVENT_BIRTH, self.OnBirth )
|
self.AddEvent( self, world.event.S_EVENT_BIRTH, self._OnBirth )
|
||||||
self.AddEvent( self, world.event.S_EVENT_DEAD, self.OnDeadOrCrash )
|
self.AddEvent( self, world.event.S_EVENT_DEAD, self._OnDeadOrCrash )
|
||||||
self.AddEvent( self, world.event.S_EVENT_CRASH, self.OnDeadOrCrash )
|
self.AddEvent( self, world.event.S_EVENT_CRASH, self._OnDeadOrCrash )
|
||||||
|
|
||||||
self.EnableEvents( self )
|
self.EnableEvents( self )
|
||||||
|
|
||||||
@ -162,7 +192,7 @@ function SPAWN:Limit( SpawnMaxUnitsAlive, SpawnMaxGroups )
|
|||||||
self.SpawnMaxGroups = SpawnMaxGroups -- The maximum amount of groups that can be spawned.
|
self.SpawnMaxGroups = SpawnMaxGroups -- The maximum amount of groups that can be spawned.
|
||||||
|
|
||||||
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
for SpawnGroupID = 1, self.SpawnMaxGroups do
|
||||||
self:InitializeSpawnGroups( SpawnGroupID )
|
self:_InitializeSpawnGroups( SpawnGroupID )
|
||||||
end
|
end
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -198,29 +228,6 @@ function SPAWN:RandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Internal function randomizing the routes.
|
|
||||||
-- @param self
|
|
||||||
-- @param #number SpawnIndex The index of the group to be spawned.
|
|
||||||
-- @return #SPAWN
|
|
||||||
function SPAWN:_RandomizeRoute( SpawnIndex )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnRandomizeRoute, self.SpawnRandomizeRouteStartPoint, self.SpawnRandomizeRouteEndPoint, self.SpawnRandomizeRouteRadius } )
|
|
||||||
|
|
||||||
if self.SpawnRandomizeRoute then
|
|
||||||
local SpawnTemplate = self.SpawnGroups[SpawnIndex].SpawnTemplate
|
|
||||||
local RouteCount = #SpawnTemplate.route.points
|
|
||||||
|
|
||||||
for t = self.SpawnRandomizeRouteStartPoint + 1, ( RouteCount - self.SpawnRandomizeRouteEndPoint ) do
|
|
||||||
SpawnTemplate.route.points[t].x = SpawnTemplate.route.points[t].x + math.random( self.SpawnRandomizeRouteRadius * -1, self.SpawnRandomizeRouteRadius )
|
|
||||||
SpawnTemplate.route.points[t].y = SpawnTemplate.route.points[t].y + math.random( self.SpawnRandomizeRouteRadius * -1, self.SpawnRandomizeRouteRadius )
|
|
||||||
-- TODO: manage altitude for airborne units ...
|
|
||||||
SpawnTemplate.route.points[t].alt = nil
|
|
||||||
--SpawnGroup.route.points[t].alt_type = nil
|
|
||||||
self:T( 'SpawnTemplate.route.points[' .. t .. '].x = ' .. SpawnTemplate.route.points[t].x .. ', SpawnTemplate.route.points[' .. t .. '].y = ' .. SpawnTemplate.route.points[t].y )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
--- This function is rather complicated to understand. But I'll try to explain.
|
--- This function is rather complicated to understand. But I'll try to explain.
|
||||||
-- This function becomes useful when you need to spawn groups with random templates of groups defined within the mission editor,
|
-- This function becomes useful when you need to spawn groups with random templates of groups defined within the mission editor,
|
||||||
@ -255,20 +262,6 @@ function SPAWN:RandomizeTemplate( SpawnTemplatePrefixTable )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function SPAWN:_RandomizeTemplate( SpawnIndex )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, SpawnIndex } )
|
|
||||||
|
|
||||||
if self.SpawnRandomizeTemplate then
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix = self.SpawnTemplatePrefixTable[ math.random( 1, #self.SpawnTemplatePrefixTable ) ]
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate = self:_Prepare( self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix, SpawnIndex )
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.route = routines.utils.deepCopy( self.SpawnTemplate.route )
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.x = self.SpawnTemplate.x
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.y = self.SpawnTemplate.y
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -290,9 +283,9 @@ function SPAWN:Repeat()
|
|||||||
self.RepeatOnEngineShutDown = false
|
self.RepeatOnEngineShutDown = false
|
||||||
self.RepeatOnLanding = true
|
self.RepeatOnLanding = true
|
||||||
|
|
||||||
self:AddEvent( world.event.S_EVENT_LAND, self.OnLand )
|
self:AddEvent( world.event.S_EVENT_LAND, self._OnLand )
|
||||||
self:AddEvent( world.event.S_EVENT_TAKEOFF, self.OnTakeOff )
|
self:AddEvent( world.event.S_EVENT_TAKEOFF, self._OnTakeOff )
|
||||||
self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self.OnEngineShutDown )
|
self:AddEvent( world.event.S_EVENT_ENGINE_SHUTDOWN, self._OnEngineShutDown )
|
||||||
self:EnableEvents()
|
self:EnableEvents()
|
||||||
|
|
||||||
return self
|
return self
|
||||||
@ -397,80 +390,12 @@ function SPAWN:SpawnArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
function SPAWN:_TranslateRotate( SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, SpawnY, SpawnAngle )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, SpawnY, SpawnAngle } )
|
|
||||||
|
|
||||||
-- Translate
|
|
||||||
local TranslatedX = SpawnX
|
|
||||||
local TranslatedY = SpawnY
|
|
||||||
|
|
||||||
-- Rotate
|
|
||||||
-- From Wikipedia: https://en.wikipedia.org/wiki/Rotation_matrix#Common_rotations
|
|
||||||
-- x' = x \cos \theta - y \sin \theta\
|
|
||||||
-- y' = x \sin \theta + y \cos \theta\
|
|
||||||
local RotatedX = - TranslatedX * math.cos( math.rad( SpawnAngle ) )
|
|
||||||
+ TranslatedY * math.sin( math.rad( SpawnAngle ) )
|
|
||||||
local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) )
|
|
||||||
+ TranslatedY * math.cos( math.rad( SpawnAngle ) )
|
|
||||||
|
|
||||||
-- Assign
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.x = SpawnRootX - RotatedX
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.y = SpawnRootY + RotatedY
|
|
||||||
|
|
||||||
|
|
||||||
local SpawnUnitCount = table.getn( self.SpawnGroups[SpawnIndex].SpawnTemplate.units )
|
|
||||||
for u = 1, SpawnUnitCount do
|
|
||||||
|
|
||||||
-- Translate
|
|
||||||
local TranslatedX = SpawnX
|
|
||||||
local TranslatedY = SpawnY - 10 * ( u - 1 )
|
|
||||||
|
|
||||||
-- Rotate
|
|
||||||
local RotatedX = - TranslatedX * math.cos( math.rad( SpawnAngle ) )
|
|
||||||
+ TranslatedY * math.sin( math.rad( SpawnAngle ) )
|
|
||||||
local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) )
|
|
||||||
+ TranslatedY * math.cos( math.rad( SpawnAngle ) )
|
|
||||||
|
|
||||||
-- Assign
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].x = SpawnRootX - RotatedX
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].y = SpawnRootY + RotatedY
|
|
||||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].heading = math.rad( SpawnAngle )
|
|
||||||
end
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Get the next index of the groups to be spawned. This function is complicated, as it is used at several spaces.
|
|
||||||
function SPAWN:GetSpawnIndex( SpawnIndex )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxUnitsAlive, self.AliveUnits, #self.SpawnTemplate.units } )
|
|
||||||
|
|
||||||
|
|
||||||
if ( self.SpawnMaxGroups == 0 ) or ( SpawnIndex <= self.SpawnMaxGroups ) then
|
|
||||||
if ( self.SpawnMaxUnitsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxUnitsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
|
|
||||||
if SpawnIndex and SpawnIndex >= self.SpawnCount + 1 then
|
|
||||||
self.SpawnCount = self.SpawnCount + 1
|
|
||||||
SpawnIndex = self.SpawnCount
|
|
||||||
end
|
|
||||||
self.SpawnIndex = SpawnIndex
|
|
||||||
if not self.SpawnGroups[self.SpawnIndex] then
|
|
||||||
self:InitializeSpawnGroups( self.SpawnIndex )
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return self.SpawnIndex
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Will re-spawn a group based on a given index.
|
--- Will re-spawn a group based on a given index.
|
||||||
-- Note: Uses @{DATABASE} module defined in MOOSE.
|
-- Note: Uses @{DATABASE} module defined in MOOSE.
|
||||||
-- @param self
|
-- @param self
|
||||||
-- @return #GROUP The group that was spawned. You can use this group for further actions.
|
-- @return GROUP#GROUP The group that was spawned. You can use this group for further actions.
|
||||||
function SPAWN:Spawn()
|
function SPAWN:Spawn()
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnIndex } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnIndex } )
|
||||||
|
|
||||||
@ -481,7 +406,7 @@ end
|
|||||||
-- Note: Uses @{DATABASE} module defined in MOOSE.
|
-- Note: Uses @{DATABASE} module defined in MOOSE.
|
||||||
-- @param self
|
-- @param self
|
||||||
-- @param #string SpawnIndex The index of the group to be spawned.
|
-- @param #string SpawnIndex The index of the group to be spawned.
|
||||||
-- @return #GROUP The group that was spawned. You can use this group for further actions.
|
-- @return GROUP#GROUP The group that was spawned. You can use this group for further actions.
|
||||||
function SPAWN:ReSpawn( SpawnIndex )
|
function SPAWN:ReSpawn( SpawnIndex )
|
||||||
self:T( { self.SpawnTemplatePrefix, SpawnIndex } )
|
self:T( { self.SpawnTemplatePrefix, SpawnIndex } )
|
||||||
|
|
||||||
@ -499,11 +424,11 @@ end
|
|||||||
|
|
||||||
--- Will spawn a group with a specified index number.
|
--- Will spawn a group with a specified index number.
|
||||||
-- Uses @{DATABASE} global object defined in MOOSE.
|
-- Uses @{DATABASE} global object defined in MOOSE.
|
||||||
-- @return #GROUP The group that was spawned. You can use this group for further actions.
|
-- @return GROUP#GROUP The group that was spawned. You can use this group for further actions.
|
||||||
function SPAWN:SpawnWithIndex( SpawnIndex )
|
function SPAWN:SpawnWithIndex( SpawnIndex )
|
||||||
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups } )
|
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups } )
|
||||||
|
|
||||||
if self:GetSpawnIndex( SpawnIndex ) then
|
if self:_GetSpawnIndex( SpawnIndex ) then
|
||||||
|
|
||||||
if self.SpawnGroups[self.SpawnIndex].Visible then
|
if self.SpawnGroups[self.SpawnIndex].Visible then
|
||||||
self.SpawnGroups[self.SpawnIndex].Group:Activate()
|
self.SpawnGroups[self.SpawnIndex].Group:Activate()
|
||||||
@ -552,7 +477,7 @@ function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation )
|
|||||||
if SpawnTime ~= nil and SpawnTimeVariation ~= nil then
|
if SpawnTime ~= nil and SpawnTimeVariation ~= nil then
|
||||||
self.SpawnLowTimer = SpawnTime - SpawnTime / 2 * SpawnTimeVariation
|
self.SpawnLowTimer = SpawnTime - SpawnTime / 2 * SpawnTimeVariation
|
||||||
self.SpawnHighTimer = SpawnTime + SpawnTime / 2 * SpawnTimeVariation
|
self.SpawnHighTimer = SpawnTime + SpawnTime / 2 * SpawnTimeVariation
|
||||||
self:ScheduleStart()
|
self:SpawnScheduleStart()
|
||||||
end
|
end
|
||||||
|
|
||||||
self:T( { self.SpawnLowTimer, self.SpawnHighTimer } )
|
self:T( { self.SpawnLowTimer, self.SpawnHighTimer } )
|
||||||
@ -564,7 +489,7 @@ end
|
|||||||
|
|
||||||
--- Will start the spawning scheduler.
|
--- Will start the spawning scheduler.
|
||||||
-- Note: This function is called automatically when @{#SPAWN.Scheduled} is called.
|
-- Note: This function is called automatically when @{#SPAWN.Scheduled} is called.
|
||||||
function SPAWN:ScheduleStart()
|
function SPAWN:SpawnScheduleStart()
|
||||||
self:T( { self.SpawnTemplatePrefix } )
|
self:T( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
--local ClientUnit = #AlivePlayerUnits()
|
--local ClientUnit = #AlivePlayerUnits()
|
||||||
@ -581,12 +506,146 @@ function SPAWN:ScheduleStart()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Will stop the scheduled spawning scheduler.
|
--- Will stop the scheduled spawning scheduler.
|
||||||
function SPAWN:ScheduleStop()
|
function SPAWN:SpawnScheduleStop()
|
||||||
self:T( { self.SpawnTemplatePrefix } )
|
self:T( { self.SpawnTemplatePrefix } )
|
||||||
|
|
||||||
self.SpawnIsScheduled = false
|
self.SpawnIsScheduled = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Will spawn a group from a hosting unit. This function is mostly advisable to be used if you want to simulate spawning from air units, like helicopters, which are dropping infantry into a defined Landing Zone.
|
||||||
|
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
||||||
|
-- You can use the returned group to further define the route to be followed.
|
||||||
|
-- @param self
|
||||||
|
-- @param #UNIT HostUnit The air or ground unit dropping or unloading the group.
|
||||||
|
-- @param #number OuterRadius The outer radius in meters where the new group will be spawned.
|
||||||
|
-- @param #number InnerRadius The inner radius in meters where the new group will NOT be spawned.
|
||||||
|
-- @param #number SpawnIndex (Optional) The index which group to spawn within the given zone.
|
||||||
|
-- @return GROUP#GROUP that was spawned.
|
||||||
|
-- @return #nil Nothing was spawned.
|
||||||
|
function SPAWN:SpawnFromUnit( HostUnit, OuterRadius, InnerRadius, SpawnIndex )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, HostUnit, OuterRadius, InnerRadius, SpawnIndex } )
|
||||||
|
|
||||||
|
if HostUnit and HostUnit:IsAlive() then -- and HostUnit:getUnit(1):inAir() == false then
|
||||||
|
|
||||||
|
if SpawnIndex then
|
||||||
|
else
|
||||||
|
SpawnIndex = self.SpawnIndex + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:_GetSpawnIndex( SpawnIndex ) then
|
||||||
|
|
||||||
|
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
||||||
|
|
||||||
|
if SpawnTemplate then
|
||||||
|
|
||||||
|
local UnitPoint = HostUnit:GetPoint()
|
||||||
|
--for PointID, Point in pairs( SpawnTemplate.route.points ) do
|
||||||
|
--Point.x = UnitPoint.x
|
||||||
|
--Point.y = UnitPoint.y
|
||||||
|
--Point.alt = nil
|
||||||
|
--Point.alt_type = nil
|
||||||
|
--end
|
||||||
|
|
||||||
|
SpawnTemplate.route.points = nil
|
||||||
|
SpawnTemplate.route.points = {}
|
||||||
|
SpawnTemplate.route.points[1] = {}
|
||||||
|
SpawnTemplate.route.points[1].x = UnitPoint.x
|
||||||
|
SpawnTemplate.route.points[1].y = UnitPoint.y
|
||||||
|
|
||||||
|
if not InnerRadius then
|
||||||
|
InnerRadius = 10
|
||||||
|
end
|
||||||
|
|
||||||
|
if not OuterRadius then
|
||||||
|
OuterRadius = 50
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Apply SpawnFormation
|
||||||
|
for UnitID = 1, #SpawnTemplate.units do
|
||||||
|
if InnerRadius == 0 then
|
||||||
|
SpawnTemplate.units[UnitID].x = UnitPoint.x
|
||||||
|
SpawnTemplate.units[UnitID].y = UnitPoint.y
|
||||||
|
else
|
||||||
|
local CirclePos = routines.getRandPointInCircle( UnitPoint, InnerRadius+1, InnerRadius )
|
||||||
|
SpawnTemplate.units[UnitID].x = CirclePos.x
|
||||||
|
SpawnTemplate.units[UnitID].y = CirclePos.y
|
||||||
|
end
|
||||||
|
self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
|
end
|
||||||
|
|
||||||
|
local SpawnPos = routines.getRandPointInCircle( UnitPoint, InnerRadius+1, InnerRadius )
|
||||||
|
local Point = {}
|
||||||
|
Point.type = "Turning Point"
|
||||||
|
Point.x = SpawnPos.x
|
||||||
|
Point.y = SpawnPos.y
|
||||||
|
Point.action = "Cone"
|
||||||
|
Point.speed = 5
|
||||||
|
|
||||||
|
table.insert( SpawnTemplate.route.points, 2, Point )
|
||||||
|
|
||||||
|
return self:SpawnWithIndex( self.SpawnIndex )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Will spawn a Group within a given @{ZONE}.
|
||||||
|
-- @param self
|
||||||
|
-- @param #ZONE Zone The zone where the group is to be spawned.
|
||||||
|
-- @param #number SpawnIndex (Optional) The index which group to spawn within the given zone.
|
||||||
|
-- @return GROUP#GROUP that was spawned.
|
||||||
|
-- @return #nil when nothing was spawned.
|
||||||
|
function SPAWN:SpawnInZone( Zone, SpawnIndex )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, Zone, SpawnIndex } )
|
||||||
|
|
||||||
|
if Zone then
|
||||||
|
|
||||||
|
if SpawnIndex then
|
||||||
|
else
|
||||||
|
SpawnIndex = self.SpawnIndex + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if self:_GetSpawnIndex( SpawnIndex ) then
|
||||||
|
|
||||||
|
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
||||||
|
|
||||||
|
if SpawnTemplate then
|
||||||
|
|
||||||
|
local ZonePoint = Zone:GetPoint()
|
||||||
|
|
||||||
|
SpawnTemplate.route.points = nil
|
||||||
|
SpawnTemplate.route.points = {}
|
||||||
|
SpawnTemplate.route.points[1] = {}
|
||||||
|
SpawnTemplate.route.points[1].x = ZonePoint.x
|
||||||
|
SpawnTemplate.route.points[1].y = ZonePoint.y
|
||||||
|
|
||||||
|
-- Apply SpawnFormation
|
||||||
|
for UnitID = 1, #SpawnTemplate.units do
|
||||||
|
SpawnTemplate.units[UnitID].x = ZonePoint.x
|
||||||
|
SpawnTemplate.units[UnitID].y = ZonePoint.y
|
||||||
|
self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||||
|
end
|
||||||
|
|
||||||
|
local SpawnPos = Zone:GetRandomPoint()
|
||||||
|
local Point = {}
|
||||||
|
Point.type = "Turning Point"
|
||||||
|
Point.x = SpawnPos.x
|
||||||
|
Point.y = SpawnPos.y
|
||||||
|
Point.action = "Cone"
|
||||||
|
Point.speed = 5
|
||||||
|
|
||||||
|
table.insert( SpawnTemplate.route.points, 2, Point )
|
||||||
|
|
||||||
|
return self:SpawnWithIndex( self.SpawnIndex )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Will spawn a plane group in uncontrolled mode...
|
--- Will spawn a plane group in uncontrolled mode...
|
||||||
@ -605,140 +664,6 @@ function SPAWN:UnControlled()
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Will spawn a group from a hosting unit. This function is mostly advisable to be used if you want to simulate spawning from air units, like helicopters, which are dropping infantry into a defined Landing Zone.
|
|
||||||
-- Note that each point in the route assigned to the spawning group is reset to the point of the spawn.
|
|
||||||
-- You can use the returned group to further define the route to be followed.
|
|
||||||
-- @param self
|
|
||||||
-- @param #UNIT HostUnit The air or ground unit dropping or unloading the group.
|
|
||||||
-- @param #number OuterRadius The outer radius in meters where the new group will be spawned.
|
|
||||||
-- @param #number InnerRadius The inner radius in meters where the new group will NOT be spawned.
|
|
||||||
-- @param #number SpawnIndex (Optional) The index which group to spawn within the given zone.
|
|
||||||
-- @return #GROUP that was spawned.
|
|
||||||
-- @return #nil Nothing was spawned.
|
|
||||||
function SPAWN:SpawnFromUnit( HostUnit, OuterRadius, InnerRadius, SpawnIndex )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, HostUnit, OuterRadius, InnerRadius, SpawnIndex } )
|
|
||||||
|
|
||||||
if HostUnit and HostUnit:IsAlive() then -- and HostUnit:getUnit(1):inAir() == false then
|
|
||||||
|
|
||||||
if SpawnIndex then
|
|
||||||
else
|
|
||||||
SpawnIndex = self.SpawnIndex + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if self:GetSpawnIndex( SpawnIndex ) then
|
|
||||||
|
|
||||||
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
|
||||||
|
|
||||||
if SpawnTemplate then
|
|
||||||
|
|
||||||
local UnitPoint = HostUnit:GetPoint()
|
|
||||||
--for PointID, Point in pairs( SpawnTemplate.route.points ) do
|
|
||||||
--Point.x = UnitPoint.x
|
|
||||||
--Point.y = UnitPoint.y
|
|
||||||
--Point.alt = nil
|
|
||||||
--Point.alt_type = nil
|
|
||||||
--end
|
|
||||||
|
|
||||||
SpawnTemplate.route.points = nil
|
|
||||||
SpawnTemplate.route.points = {}
|
|
||||||
SpawnTemplate.route.points[1] = {}
|
|
||||||
SpawnTemplate.route.points[1].x = UnitPoint.x
|
|
||||||
SpawnTemplate.route.points[1].y = UnitPoint.y
|
|
||||||
|
|
||||||
if not InnerRadius then
|
|
||||||
InnerRadius = 10
|
|
||||||
end
|
|
||||||
|
|
||||||
if not OuterRadius then
|
|
||||||
OuterRadius = 50
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Apply SpawnFormation
|
|
||||||
for UnitID = 1, #SpawnTemplate.units do
|
|
||||||
if InnerRadius == 0 then
|
|
||||||
SpawnTemplate.units[UnitID].x = UnitPoint.x
|
|
||||||
SpawnTemplate.units[UnitID].y = UnitPoint.y
|
|
||||||
else
|
|
||||||
local CirclePos = routines.getRandPointInCircle( UnitPoint, InnerRadius+1, InnerRadius )
|
|
||||||
SpawnTemplate.units[UnitID].x = CirclePos.x
|
|
||||||
SpawnTemplate.units[UnitID].y = CirclePos.y
|
|
||||||
end
|
|
||||||
self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
|
||||||
end
|
|
||||||
|
|
||||||
local SpawnPos = routines.getRandPointInCircle( UnitPoint, InnerRadius+1, InnerRadius )
|
|
||||||
local Point = {}
|
|
||||||
Point.type = "Turning Point"
|
|
||||||
Point.x = SpawnPos.x
|
|
||||||
Point.y = SpawnPos.y
|
|
||||||
Point.action = "Cone"
|
|
||||||
Point.speed = 5
|
|
||||||
|
|
||||||
table.insert( SpawnTemplate.route.points, 2, Point )
|
|
||||||
|
|
||||||
return self:SpawnWithIndex( self.SpawnIndex )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Will spawn a Group within a given @{ZONE}.
|
|
||||||
-- @param self
|
|
||||||
-- @param #ZONE Zone The zone where the group is to be spawned.
|
|
||||||
-- @param #number SpawnIndex (Optional) The index which group to spawn within the given zone.
|
|
||||||
-- @return #GROUP that was spawned.
|
|
||||||
-- @return #nil when nothing was spawned.
|
|
||||||
function SPAWN:SpawnInZone( Zone, SpawnIndex )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, Zone, SpawnIndex } )
|
|
||||||
|
|
||||||
if Zone then
|
|
||||||
|
|
||||||
if SpawnIndex then
|
|
||||||
else
|
|
||||||
SpawnIndex = self.SpawnIndex + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if self:GetSpawnIndex( SpawnIndex ) then
|
|
||||||
|
|
||||||
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
|
|
||||||
|
|
||||||
if SpawnTemplate then
|
|
||||||
|
|
||||||
local ZonePoint = Zone:GetPoint()
|
|
||||||
|
|
||||||
SpawnTemplate.route.points = nil
|
|
||||||
SpawnTemplate.route.points = {}
|
|
||||||
SpawnTemplate.route.points[1] = {}
|
|
||||||
SpawnTemplate.route.points[1].x = ZonePoint.x
|
|
||||||
SpawnTemplate.route.points[1].y = ZonePoint.y
|
|
||||||
|
|
||||||
-- Apply SpawnFormation
|
|
||||||
for UnitID = 1, #SpawnTemplate.units do
|
|
||||||
SpawnTemplate.units[UnitID].x = ZonePoint.x
|
|
||||||
SpawnTemplate.units[UnitID].y = ZonePoint.y
|
|
||||||
self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
|
||||||
end
|
|
||||||
|
|
||||||
local SpawnPos = Zone:GetRandomPoint()
|
|
||||||
local Point = {}
|
|
||||||
Point.type = "Turning Point"
|
|
||||||
Point.x = SpawnPos.x
|
|
||||||
Point.y = SpawnPos.y
|
|
||||||
Point.action = "Cone"
|
|
||||||
Point.speed = 5
|
|
||||||
|
|
||||||
table.insert( SpawnTemplate.route.points, 2, Point )
|
|
||||||
|
|
||||||
return self:SpawnWithIndex( self.SpawnIndex )
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Will return the SpawnGroupName either with with a specific count number or without any count.
|
--- Will return the SpawnGroupName either with with a specific count number or without any count.
|
||||||
-- @param self
|
-- @param self
|
||||||
@ -763,13 +688,71 @@ function SPAWN:SpawnGroupName( SpawnIndex )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Find the first alive group.
|
||||||
|
-- @param self
|
||||||
|
-- @param #number SpawnCursor A number holding the index from where to find the first group from.
|
||||||
|
-- @return GROUP#GROUP, #number The group found, the new index where the group was found.
|
||||||
|
-- @return #nil, #nil When no group is found, #nil is returned.
|
||||||
|
function SPAWN:GetFirstAliveGroup( SpawnCursor )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnCursor } )
|
||||||
|
|
||||||
|
for SpawnIndex = 1, self.SpawnCount do
|
||||||
|
local SpawnGroup = self:GetGroupFromIndex( SpawnIndex )
|
||||||
|
if SpawnGroup and SpawnGroup:IsAlive() then
|
||||||
|
SpawnCursor = SpawnIndex
|
||||||
|
return SpawnGroup, SpawnCursor
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Find the next alive group.
|
||||||
|
-- @param self
|
||||||
|
-- @param #number SpawnCursor A number holding the last found previous index.
|
||||||
|
-- @return GROUP#GROUP, #number The group found, the new index where the group was found.
|
||||||
|
-- @return #nil, #nil When no group is found, #nil is returned.
|
||||||
|
function SPAWN:GetNextAliveGroup( SpawnCursor )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnCursor } )
|
||||||
|
|
||||||
|
SpawnCursor = SpawnCursor + 1
|
||||||
|
for SpawnIndex = SpawnCursor, self.SpawnCount do
|
||||||
|
local SpawnGroup = self:GetGroupFromIndex( SpawnIndex )
|
||||||
|
if SpawnGroup and SpawnGroup:IsAlive() then
|
||||||
|
SpawnCursor = SpawnIndex
|
||||||
|
return SpawnGroup, SpawnCursor
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find the last alive group during runtime.
|
||||||
|
function SPAWN:GetLastAliveGroup()
|
||||||
|
self:T( { self.SpawnTemplatePrefixself.SpawnAliasPrefix } )
|
||||||
|
|
||||||
|
self.SpawnIndex = self:_GetLastIndex()
|
||||||
|
for SpawnIndex = self.SpawnIndex, 1, -1 do
|
||||||
|
local SpawnGroup = self:GetGroupFromIndex( SpawnIndex )
|
||||||
|
if SpawnGroup and SpawnGroup:IsAlive() then
|
||||||
|
self.SpawnIndex = SpawnIndex
|
||||||
|
return SpawnGroup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.SpawnIndex = nil
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Get the group from an index.
|
--- Get the group from an index.
|
||||||
-- Returns the group from the SpawnGroups list.
|
-- Returns the group from the SpawnGroups list.
|
||||||
-- If no index is given, it will return the first group in the list.
|
-- If no index is given, it will return the first group in the list.
|
||||||
-- @param self
|
-- @param self
|
||||||
-- @param #number SpawnIndex The index of the group to return.
|
-- @param #number SpawnIndex The index of the group to return.
|
||||||
-- @return #GROUP
|
-- @return GROUP#GROUP
|
||||||
function SPAWN:GetGroupFromIndex( SpawnIndex )
|
function SPAWN:GetGroupFromIndex( SpawnIndex )
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } )
|
||||||
|
|
||||||
@ -789,7 +772,7 @@ end
|
|||||||
-- @param DCSUnit The DCS unit to be searched.
|
-- @param DCSUnit The DCS unit to be searched.
|
||||||
-- @return #string The prefix
|
-- @return #string The prefix
|
||||||
-- @return #nil Nothing found
|
-- @return #nil Nothing found
|
||||||
function SPAWN:GetGroupIndexFromDCSUnit( DCSUnit )
|
function SPAWN:_GetGroupIndexFromDCSUnit( DCSUnit )
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
|
||||||
|
|
||||||
if DCSUnit and DCSUnit:getName() then
|
if DCSUnit and DCSUnit:getName() then
|
||||||
@ -813,7 +796,7 @@ end
|
|||||||
-- @param DCSUnit The DCS unit to be searched.
|
-- @param DCSUnit The DCS unit to be searched.
|
||||||
-- @return #string The prefix
|
-- @return #string The prefix
|
||||||
-- @return #nil Nothing found
|
-- @return #nil Nothing found
|
||||||
function SPAWN:GetPrefixFromDCSUnit( DCSUnit )
|
function SPAWN:_GetPrefixFromDCSUnit( DCSUnit )
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
|
||||||
|
|
||||||
if DCSUnit and DCSUnit:getName() then
|
if DCSUnit and DCSUnit:getName() then
|
||||||
@ -829,14 +812,14 @@ function SPAWN:GetPrefixFromDCSUnit( DCSUnit )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Return the group within the SpawnGroups collection with input a DCSUnit.
|
--- Return the group within the SpawnGroups collection with input a DCSUnit.
|
||||||
function SPAWN:GetGroupFromDCSUnit( DCSUnit )
|
function SPAWN:_GetGroupFromDCSUnit( DCSUnit )
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
|
||||||
|
|
||||||
if DCSUnit then
|
if DCSUnit then
|
||||||
local SpawnPrefix = self:GetPrefixFromDCSUnit( DCSUnit )
|
local SpawnPrefix = self:_GetPrefixFromDCSUnit( DCSUnit )
|
||||||
|
|
||||||
if self.SpawnTemplatePrefix == SpawnPrefix or ( self.SpawnAliasPrefix and self.SpawnAliasPrefix == SpawnPrefix ) then
|
if self.SpawnTemplatePrefix == SpawnPrefix or ( self.SpawnAliasPrefix and self.SpawnAliasPrefix == SpawnPrefix ) then
|
||||||
local SpawnGroupIndex = self:GetGroupIndexFromDCSUnit( DCSUnit )
|
local SpawnGroupIndex = self:_GetGroupIndexFromDCSUnit( DCSUnit )
|
||||||
local SpawnGroup = self.SpawnGroups[SpawnGroupIndex].Group
|
local SpawnGroup = self.SpawnGroups[SpawnGroupIndex].Group
|
||||||
self:T( SpawnGroup )
|
self:T( SpawnGroup )
|
||||||
return SpawnGroup
|
return SpawnGroup
|
||||||
@ -849,7 +832,7 @@ end
|
|||||||
|
|
||||||
--- Get the index from a given group.
|
--- Get the index from a given group.
|
||||||
-- The function will search the name of the group for a #, and will return the number behind the #-mark.
|
-- The function will search the name of the group for a #, and will return the number behind the #-mark.
|
||||||
function SPAWN:GetGroupIndexFromGroup( SpawnGroup )
|
function SPAWN:_GetGroupIndexFromGroup( SpawnGroup )
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } )
|
||||||
|
|
||||||
local IndexString = string.match( SpawnGroup:GetName(), "#.*$" ):sub( 2 )
|
local IndexString = string.match( SpawnGroup:GetName(), "#.*$" ):sub( 2 )
|
||||||
@ -861,14 +844,14 @@ function SPAWN:GetGroupIndexFromGroup( SpawnGroup )
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Return the last maximum index that can be used.
|
--- Return the last maximum index that can be used.
|
||||||
function SPAWN:GetLastIndex()
|
function SPAWN:_GetLastIndex()
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
|
||||||
|
|
||||||
return self.SpawnMaxGroups
|
return self.SpawnMaxGroups
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Initalize the SpawnGroups collection.
|
--- Initalize the SpawnGroups collection.
|
||||||
function SPAWN:InitializeSpawnGroups( SpawnIndex )
|
function SPAWN:_InitializeSpawnGroups( SpawnIndex )
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } )
|
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } )
|
||||||
|
|
||||||
if not self.SpawnGroups[SpawnIndex] then
|
if not self.SpawnGroups[SpawnIndex] then
|
||||||
@ -891,63 +874,6 @@ function SPAWN:InitializeSpawnGroups( SpawnIndex )
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Find the first alive group.
|
|
||||||
-- @param self
|
|
||||||
-- @param #number SpawnCursor A number holding the index from where to find the first group from.
|
|
||||||
-- @return #GROUP, #number The group found, the new index where the group was found.
|
|
||||||
-- @return #nil, #nil When no group is found, #nil is returned.
|
|
||||||
function SPAWN:GetFirstAliveGroup( SpawnCursor )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnCursor } )
|
|
||||||
|
|
||||||
for SpawnIndex = 1, self.SpawnCount do
|
|
||||||
local SpawnGroup = self:GetGroupFromIndex( SpawnIndex )
|
|
||||||
if SpawnGroup and SpawnGroup:IsAlive() then
|
|
||||||
SpawnCursor = SpawnIndex
|
|
||||||
return SpawnGroup, SpawnCursor
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Find the next alive group.
|
|
||||||
-- @param self
|
|
||||||
-- @param #number SpawnCursor A number holding the last found previous index.
|
|
||||||
-- @return #GROUP, #number The group found, the new index where the group was found.
|
|
||||||
-- @return #nil, #nil When no group is found, #nil is returned.
|
|
||||||
function SPAWN:GetNextAliveGroup( SpawnCursor )
|
|
||||||
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnCursor } )
|
|
||||||
|
|
||||||
SpawnCursor = SpawnCursor + 1
|
|
||||||
for SpawnIndex = SpawnCursor, self.SpawnCount do
|
|
||||||
local SpawnGroup = self:GetGroupFromIndex( SpawnIndex )
|
|
||||||
if SpawnGroup and SpawnGroup:IsAlive() then
|
|
||||||
SpawnCursor = SpawnIndex
|
|
||||||
return SpawnGroup, SpawnCursor
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Find the last alive group during runtime.
|
|
||||||
function SPAWN:GetLastAliveGroup()
|
|
||||||
self:T( { self.SpawnTemplatePrefixself.SpawnAliasPrefix } )
|
|
||||||
|
|
||||||
self.SpawnIndex = self:GetLastIndex()
|
|
||||||
for SpawnIndex = self.SpawnIndex, 1, -1 do
|
|
||||||
local SpawnGroup = self:GetGroupFromIndex( SpawnIndex )
|
|
||||||
if SpawnGroup and SpawnGroup:IsAlive() then
|
|
||||||
self.SpawnIndex = SpawnIndex
|
|
||||||
return SpawnGroup
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
self.SpawnIndex = nil
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Gets the CategoryID of the Group with the given SpawnPrefix
|
--- Gets the CategoryID of the Group with the given SpawnPrefix
|
||||||
function SPAWN:_GetGroupCategoryID( SpawnPrefix )
|
function SPAWN:_GetGroupCategoryID( SpawnPrefix )
|
||||||
@ -1036,14 +962,120 @@ function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex )
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Internal function randomizing the routes.
|
||||||
|
-- @param self
|
||||||
|
-- @param #number SpawnIndex The index of the group to be spawned.
|
||||||
|
-- @return #SPAWN
|
||||||
|
function SPAWN:_RandomizeRoute( SpawnIndex )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnRandomizeRoute, self.SpawnRandomizeRouteStartPoint, self.SpawnRandomizeRouteEndPoint, self.SpawnRandomizeRouteRadius } )
|
||||||
|
|
||||||
|
if self.SpawnRandomizeRoute then
|
||||||
|
local SpawnTemplate = self.SpawnGroups[SpawnIndex].SpawnTemplate
|
||||||
|
local RouteCount = #SpawnTemplate.route.points
|
||||||
|
|
||||||
|
for t = self.SpawnRandomizeRouteStartPoint + 1, ( RouteCount - self.SpawnRandomizeRouteEndPoint ) do
|
||||||
|
SpawnTemplate.route.points[t].x = SpawnTemplate.route.points[t].x + math.random( self.SpawnRandomizeRouteRadius * -1, self.SpawnRandomizeRouteRadius )
|
||||||
|
SpawnTemplate.route.points[t].y = SpawnTemplate.route.points[t].y + math.random( self.SpawnRandomizeRouteRadius * -1, self.SpawnRandomizeRouteRadius )
|
||||||
|
-- TODO: manage altitude for airborne units ...
|
||||||
|
SpawnTemplate.route.points[t].alt = nil
|
||||||
|
--SpawnGroup.route.points[t].alt_type = nil
|
||||||
|
self:T( 'SpawnTemplate.route.points[' .. t .. '].x = ' .. SpawnTemplate.route.points[t].x .. ', SpawnTemplate.route.points[' .. t .. '].y = ' .. SpawnTemplate.route.points[t].y )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function SPAWN:_RandomizeTemplate( SpawnIndex )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, SpawnIndex } )
|
||||||
|
|
||||||
|
if self.SpawnRandomizeTemplate then
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix = self.SpawnTemplatePrefixTable[ math.random( 1, #self.SpawnTemplatePrefixTable ) ]
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate = self:_Prepare( self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix, SpawnIndex )
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.route = routines.utils.deepCopy( self.SpawnTemplate.route )
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.x = self.SpawnTemplate.x
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.y = self.SpawnTemplate.y
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function SPAWN:_TranslateRotate( SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, SpawnY, SpawnAngle )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, SpawnY, SpawnAngle } )
|
||||||
|
|
||||||
|
-- Translate
|
||||||
|
local TranslatedX = SpawnX
|
||||||
|
local TranslatedY = SpawnY
|
||||||
|
|
||||||
|
-- Rotate
|
||||||
|
-- From Wikipedia: https://en.wikipedia.org/wiki/Rotation_matrix#Common_rotations
|
||||||
|
-- x' = x \cos \theta - y \sin \theta\
|
||||||
|
-- y' = x \sin \theta + y \cos \theta\
|
||||||
|
local RotatedX = - TranslatedX * math.cos( math.rad( SpawnAngle ) )
|
||||||
|
+ TranslatedY * math.sin( math.rad( SpawnAngle ) )
|
||||||
|
local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) )
|
||||||
|
+ TranslatedY * math.cos( math.rad( SpawnAngle ) )
|
||||||
|
|
||||||
|
-- Assign
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.x = SpawnRootX - RotatedX
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.y = SpawnRootY + RotatedY
|
||||||
|
|
||||||
|
|
||||||
|
local SpawnUnitCount = table.getn( self.SpawnGroups[SpawnIndex].SpawnTemplate.units )
|
||||||
|
for u = 1, SpawnUnitCount do
|
||||||
|
|
||||||
|
-- Translate
|
||||||
|
local TranslatedX = SpawnX
|
||||||
|
local TranslatedY = SpawnY - 10 * ( u - 1 )
|
||||||
|
|
||||||
|
-- Rotate
|
||||||
|
local RotatedX = - TranslatedX * math.cos( math.rad( SpawnAngle ) )
|
||||||
|
+ TranslatedY * math.sin( math.rad( SpawnAngle ) )
|
||||||
|
local RotatedY = TranslatedX * math.sin( math.rad( SpawnAngle ) )
|
||||||
|
+ TranslatedY * math.cos( math.rad( SpawnAngle ) )
|
||||||
|
|
||||||
|
-- Assign
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].x = SpawnRootX - RotatedX
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].y = SpawnRootY + RotatedY
|
||||||
|
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[u].heading = math.rad( SpawnAngle )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get the next index of the groups to be spawned. This function is complicated, as it is used at several spaces.
|
||||||
|
function SPAWN:_GetSpawnIndex( SpawnIndex )
|
||||||
|
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxUnitsAlive, self.AliveUnits, #self.SpawnTemplate.units } )
|
||||||
|
|
||||||
|
|
||||||
|
if ( self.SpawnMaxGroups == 0 ) or ( SpawnIndex <= self.SpawnMaxGroups ) then
|
||||||
|
if ( self.SpawnMaxUnitsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxUnitsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
|
||||||
|
if SpawnIndex and SpawnIndex >= self.SpawnCount + 1 then
|
||||||
|
self.SpawnCount = self.SpawnCount + 1
|
||||||
|
SpawnIndex = self.SpawnCount
|
||||||
|
end
|
||||||
|
self.SpawnIndex = SpawnIndex
|
||||||
|
if not self.SpawnGroups[self.SpawnIndex] then
|
||||||
|
self:_InitializeSpawnGroups( self.SpawnIndex )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return self.SpawnIndex
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- TODO Need to delete this... _Database does this now ...
|
-- TODO Need to delete this... _Database does this now ...
|
||||||
function SPAWN:OnBirth( event )
|
function SPAWN:_OnBirth( event )
|
||||||
|
|
||||||
if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
|
if timer.getTime0() < timer.getAbsTime() then -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
local EventPrefix = self:GetPrefixFromDCSUnit( event.initiator )
|
local EventPrefix = self:_GetPrefixFromDCSUnit( event.initiator )
|
||||||
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
|
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
|
||||||
self:T( { "Birth event: " .. event.initiator:getName(), event } )
|
self:T( { "Birth event: " .. event.initiator:getName(), event } )
|
||||||
--MessageToAll( "Mission command: unit " .. SpawnTemplatePrefix .. " spawned." , 5, EventPrefix .. '/Event')
|
--MessageToAll( "Mission command: unit " .. SpawnTemplatePrefix .. " spawned." , 5, EventPrefix .. '/Event')
|
||||||
@ -1057,11 +1089,11 @@ end
|
|||||||
|
|
||||||
--- Obscolete
|
--- Obscolete
|
||||||
-- @todo Need to delete this... _Database does this now ...
|
-- @todo Need to delete this... _Database does this now ...
|
||||||
function SPAWN:OnDeadOrCrash( event )
|
function SPAWN:_OnDeadOrCrash( event )
|
||||||
|
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
local EventPrefix = self:GetPrefixFromDCSUnit( event.initiator )
|
local EventPrefix = self:_GetPrefixFromDCSUnit( event.initiator )
|
||||||
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
|
if EventPrefix == self.SpawnTemplatePrefix or ( self.SpawnAliasPrefix and EventPrefix == self.SpawnAliasPrefix ) then
|
||||||
self:T( { "Dead event: " .. event.initiator:getName(), event } )
|
self:T( { "Dead event: " .. event.initiator:getName(), event } )
|
||||||
-- local DestroyedUnit = Unit.getByName( EventPrefix )
|
-- local DestroyedUnit = Unit.getByName( EventPrefix )
|
||||||
@ -1077,10 +1109,10 @@ end
|
|||||||
--- Will detect AIR Units taking off... When the event takes place, the spawned Group is registered as airborne...
|
--- Will detect AIR Units taking off... When the event takes place, the spawned Group is registered as airborne...
|
||||||
-- This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.
|
-- This is needed to ensure that Re-SPAWNing only is done for landed AIR Groups.
|
||||||
-- @todo Need to test for AIR Groups only...
|
-- @todo Need to test for AIR Groups only...
|
||||||
function SPAWN:OnTakeOff( event )
|
function SPAWN:_OnTakeOff( event )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
local SpawnGroup = self:GetGroupFromDCSUnit( event.initiator )
|
local SpawnGroup = self:_GetGroupFromDCSUnit( event.initiator )
|
||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
self:T( { "TakeOff event: " .. event.initiator:getName(), event } )
|
self:T( { "TakeOff event: " .. event.initiator:getName(), event } )
|
||||||
self:T( "self.Landed = false" )
|
self:T( "self.Landed = false" )
|
||||||
@ -1092,16 +1124,16 @@ end
|
|||||||
--- Will detect AIR Units landing... When the event takes place, the spawned Group is registered as landed.
|
--- Will detect AIR Units landing... When the event takes place, the spawned Group is registered as landed.
|
||||||
-- This is needed to ensure that Re-SPAWNing is only done for landed AIR Groups.
|
-- This is needed to ensure that Re-SPAWNing is only done for landed AIR Groups.
|
||||||
-- @todo Need to test for AIR Groups only...
|
-- @todo Need to test for AIR Groups only...
|
||||||
function SPAWN:OnLand( event )
|
function SPAWN:_OnLand( event )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
local SpawnGroup = self:GetGroupFromDCSUnit( event.initiator )
|
local SpawnGroup = self:_GetGroupFromDCSUnit( event.initiator )
|
||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
self:T( { "Landed event:" .. event.initiator:getName(), event } )
|
self:T( { "Landed event:" .. event.initiator:getName(), event } )
|
||||||
self.Landed = true
|
self.Landed = true
|
||||||
self:T( "self.Landed = true" )
|
self:T( "self.Landed = true" )
|
||||||
if self.Landed and self.RepeatOnLanding then
|
if self.Landed and self.RepeatOnLanding then
|
||||||
local SpawnGroupIndex = self:GetGroupIndexFromGroup( SpawnGroup )
|
local SpawnGroupIndex = self:_GetGroupIndexFromGroup( SpawnGroup )
|
||||||
self:T( { "Landed:", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
self:T( { "Landed:", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
||||||
self:ReSpawn( SpawnGroupIndex )
|
self:ReSpawn( SpawnGroupIndex )
|
||||||
end
|
end
|
||||||
@ -1112,17 +1144,17 @@ end
|
|||||||
--- Will detect AIR Units shutting down their engines ...
|
--- Will detect AIR Units shutting down their engines ...
|
||||||
-- When the event takes place, and the method @{RepeatOnEngineShutDown} was called, the spawned Group will Re-SPAWN.
|
-- When the event takes place, and the method @{RepeatOnEngineShutDown} was called, the spawned Group will Re-SPAWN.
|
||||||
-- But only when the Unit was registered to have landed.
|
-- But only when the Unit was registered to have landed.
|
||||||
-- @see OnTakeOff
|
-- @see _OnTakeOff
|
||||||
-- @see OnLand
|
-- @see _OnLand
|
||||||
-- @todo Need to test for AIR Groups only...
|
-- @todo Need to test for AIR Groups only...
|
||||||
function SPAWN:OnEngineShutDown( event )
|
function SPAWN:_OnLand( event )
|
||||||
|
|
||||||
if event.initiator and event.initiator:getName() then
|
if event.initiator and event.initiator:getName() then
|
||||||
local SpawnGroup = self:GetGroupFromDCSUnit( event.initiator )
|
local SpawnGroup = self:_GetGroupFromDCSUnit( event.initiator )
|
||||||
if SpawnGroup then
|
if SpawnGroup then
|
||||||
self:T( { "EngineShutDown event: " .. event.initiator:getName(), event } )
|
self:T( { "EngineShutDown event: " .. event.initiator:getName(), event } )
|
||||||
if self.Landed and self.RepeatOnEngineShutDown then
|
if self.Landed and self.RepeatOnEngineShutDown then
|
||||||
local SpawnGroupIndex = self:GetGroupIndexFromGroup( SpawnGroup )
|
local SpawnGroupIndex = self:_GetGroupIndexFromGroup( SpawnGroup )
|
||||||
self:T( { "EngineShutDown: ", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
self:T( { "EngineShutDown: ", "ReSpawn:", SpawnGroup:GetName(), SpawnGroupIndex } )
|
||||||
self:ReSpawn( SpawnGroupIndex )
|
self:ReSpawn( SpawnGroupIndex )
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user