Rework of SPAWN. Finished for release

This commit is contained in:
svenvandevelde 2016-03-11 12:17:29 +01:00
parent 0468462add
commit 9e9e75271c
15 changed files with 10876 additions and 441 deletions

View File

@ -0,0 +1,31 @@
rem Generate Moose_Embedded.lua
copy Trace.lua ^
+ Routines.lua ^
+ Base.lua ^
+ Menu.lua ^
+ Group.lua ^
+ Unit.lua ^
+ Zone.lua ^
+ Database.lua ^
+ Cargo.lua ^
+ Client.lua ^
+ Message.lua ^
+ Stage.lua ^
+ Task.lua ^
+ GoHomeTask.lua ^
+ DestroyBaseTask.lua ^
+ DestroyGroupsTask.lua ^
+ DestroyRadarsTask.lua ^
+ DestroyUnitTypesTask.lua ^
+ PickupTask.lua ^
+ DeployTask.lua ^
+ NoTask.lua ^
+ RouteTask.lua ^
+ Mission.lua ^
+ CleanUp.lua ^
+ Spawn.lua ^
+ Movement.lua ^
+ Sead.lua ^
Moose_Embedded.lua

View File

@ -20,4 +20,4 @@ env.info( "Include.MissionPath = " .. Include.MissionPath)
Include.Files = {} Include.Files = {}
env.info("Loaded MOOSE Include Engine") env.info("Loaded MOOSE Include Engine")

View File

@ -1,159 +0,0 @@
local base = _G
local MOOSE_Version = "0.1.1.1"
env.info("Loading MOOSE " .. base.timer.getAbsTime() )
function script_path()
local str = debug.getinfo(2, "S").source
return str:match("(.*/)"):sub(1,-2):gsub("\\","/")
end
Include = {}
Include.ProgramPath = "Scripts/Moose/Moose/"
Include.MissionPath = script_path()
env.info( "Include.ProgramPath = " .. Include.ProgramPath)
env.info( "Include.MissionPath = " .. Include.MissionPath)
Include.Files = {}
Include.FileIn = function(fileName, table)
-- env.info( fileName )
local chunk, errMsg = base.loadfile(fileName)
if chunk ~= nil then
env.info( "chunk assigned " )
env.info( Include.oneLineSerialize( chunk ) )
base.setfenv(chunk, table)
chunk()
if table.MOOSE_Version then
env.info( table.MOOSE_Version )
end
return chunk
else
return nil, errMsg
end
end
Include.MisFiles = {}
Include.FileName = function( num )
local hexstr = '0123456789ABCDEF'
local s = ''
while num > 0 do
local mod = math.fmod(num, 16)
s = string.sub(hexstr, mod+1, mod+1) .. s
num = math.floor(num / 16)
end
if s == '' then s = '0' end
-- env.info( string.format( "~mis" .. "%8s", "00000000" .. s ) )
return string.format( "~mis" .. "%s", string.sub( "00000000" .. s, -8 ) )
end
Include.ScanFiles = function()
local i = 0
while i <= 32767 do
local FileName = Include.FileName( i )
local FileChunk = {}
local FileChunk = Include.FileIn( Include.MissionPath .. FileName, FileChunk )
if FileChunk then
end
i = i + 1
end
end
Include.File = function( IncludeFile )
if not Include.Files[ IncludeFile ] then
Include.Files[IncludeFile] = IncludeFile
env.info( "Include:" .. IncludeFile .. " from " .. Include.ProgramPath )
local f = base.loadfile( Include.ProgramPath .. IncludeFile .. ".lua" )
if f == nil then
env.info( "Include:" .. IncludeFile .. " from " .. Include.MissionPath )
local f = base.loadfile( Include.MissionPath .. IncludeFile .. ".lua" )
if f == nil then
error ("Could not load MOOSE file " .. IncludeFile .. ".lua" )
else
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.MissionPath )
return f()
end
else
env.info( "Include:" .. IncludeFile .. " loaded from " .. Include.ProgramPath )
return f()
end
end
end
--porting in Slmod's "safestring" basic serialize
Include.basicSerialize = function(s)
if s == nil then
return "\"\""
else
if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'table') or (type(s) == 'userdata') ) then
return tostring(s)
elseif type(s) == 'string' then
s = string.format('%q', s)
return s
end
end
end
-- porting in Slmod's serialize_slmod2
Include.oneLineSerialize = function(tbl) -- serialization of a table all on a single line, no comments, made to replace old get_table_string function
if type(tbl) == 'table' then --function only works for tables!
local tbl_str = {}
tbl_str[#tbl_str + 1] = '{'
for ind,val in pairs(tbl) do -- serialize its fields
if type(ind) == "number" then
tbl_str[#tbl_str + 1] = '['
tbl_str[#tbl_str + 1] = tostring(ind)
tbl_str[#tbl_str + 1] = ']='
else --must be a string
tbl_str[#tbl_str + 1] = '['
tbl_str[#tbl_str + 1] = Include.basicSerialize(ind)
tbl_str[#tbl_str + 1] = ']='
end
if ((type(val) == 'number') or (type(val) == 'boolean')) then
tbl_str[#tbl_str + 1] = tostring(val)
tbl_str[#tbl_str + 1] = ','
elseif type(val) == 'string' then
tbl_str[#tbl_str + 1] = Include.basicSerialize(val)
tbl_str[#tbl_str + 1] = ','
elseif type(val) == 'nil' then -- won't ever happen, right?
tbl_str[#tbl_str + 1] = 'nil,'
elseif type(val) == 'table' then
if ind == "__index" then
tbl_str[#tbl_str + 1] = "__index"
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
else
tbl_str[#tbl_str + 1] = Include.oneLineSerialize(val)
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
end
elseif type(val) == 'function' then
tbl_str[#tbl_str + 1] = "function " .. tostring(ind)
tbl_str[#tbl_str + 1] = ',' --I think this is right, I just added it
else
env.info('unable to serialize value type ' .. Include.basicSerialize(type(val)) .. ' at index ' .. tostring(ind))
env.info( debug.traceback() )
end
end
tbl_str[#tbl_str + 1] = '}'
return table.concat(tbl_str)
else
return tostring(tbl)
end
end
Include.ScanFiles( )
Include.File( "Database" )
env.info("Loaded MOOSE Include Engine")

View File

@ -6,13 +6,21 @@ Include.File( "Routines" )
_TraceOn = true _TraceOn = true
_TraceClass = { _TraceClass = {
DATABASE = true, --DATABASE = true,
--SEAD = true, --SEAD = true,
--DESTROYBASETASK = true, --DESTROYBASETASK = true,
--MOVEMENT = true, --MOVEMENT = true,
SPAWN = true, SPAWN = true,
STAGE = true,
ZONE = true,
GROUP = true, GROUP = true,
--UNIT = true, UNIT = true,
--CLIENT = true,
--CARGO = true,
CARGO_GROUP = true,
--CARGO_PACKAGE = true,
--CARGO_SLINGLOAD = true,
CARGO_ZONE = true,
} }
BASE = { BASE = {

View File

@ -40,7 +40,6 @@ self:T( { CargoZoneName, CargoHostName } )
if CargoHostName then if CargoHostName then
self.CargoHostName = CargoHostName self.CargoHostName = CargoHostName
self.CargoHostSpawn = SPAWN:New( CargoHostName )
end end
self:T( self.CargoZone ) self:T( self.CargoZone )
@ -49,33 +48,35 @@ self:T( { CargoZoneName, CargoHostName } )
end end
function CARGO_ZONE:Spawn() function CARGO_ZONE:Spawn()
self:T( CargoHostSpawn ) self:T( self.CargoHostName )
if self.CargoHostSpawn then if self.CargoHostSpawn then
local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex():GetDCSGroup() local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex()
if CargoHostGroup then if CargoHostGroup and CargoHostGroup:IsAlive() then
if not CargoHostGroup:isExist() then
self.CargoHostSpawn:ReSpawn(1)
end
else else
self.CargoHostSpawn:ReSpawn(1) self.CargoHostSpawn:ReSpawn( 1 )
end end
else
self:T( "Initialize CargoHostSpawn" )
self.CargoHostSpawn = SPAWN:New( self.CargoHostName )
self.CargoHostSpawn:ReSpawn( 1 )
end end
return self return self
end end
function CARGO_ZONE:GetHostUnit() function CARGO_ZONE:GetHostUnit()
self:T( self )
if self.CargoHostName then if self.CargoHostName then
-- A Host has been given, signal the host -- A Host has been given, signal the host
local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex():GetDCSGroup() local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex()
local CargoHostUnit local CargoHostUnit
if CargoHostGroup == nil then if CargoHostGroup and CargoHostGroup:IsAlive() then
CargoHostUnit = StaticObject.getByName( self.CargoHostName ) CargoHostUnit = CargoHostGroup:GetUnit(1)
else else
CargoHostUnit = CargoHostGroup:getUnits()[1] CargoHostUnit = StaticObject.getByName( self.CargoHostName )
end end
return CargoHostUnit return CargoHostUnit
@ -129,7 +130,7 @@ self:T()
if SignalUnit then if SignalUnit then
self:T( 'Signalling Unit' ) self:T( 'Signalling Unit' )
local SignalVehiclePos = SignalUnit:getPosition().p local SignalVehiclePos = SignalUnit:GetPositionVec3()
SignalVehiclePos.y = SignalVehiclePos.y + 2 SignalVehiclePos.y = SignalVehiclePos.y + 2
if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then if self.SignalType.ID == CARGO_ZONE.SIGNAL.TYPE.SMOKE.ID then
@ -251,11 +252,16 @@ end
function CARGO_ZONE:GetCargoHostUnit() function CARGO_ZONE:GetCargoHostUnit()
self:T() self:T( self )
local CargoHostUnit = self.CargoHostSpawn:GetGroupFromIndex(1):GetUnit(1) if self.CargoHostSpawn then
if CargoHostUnit and CargoHostUnit:IsAlive() then local CargoHostGroup = self.CargoHostSpawn:GetGroupFromIndex(1)
return CargoHostUnit if CargoHostGroup and CargoHostGroup:IsAlive() then
local CargoHostUnit = CargoHostGroup:GetUnit(1)
if CargoHostUnit and CargoHostUnit:IsAlive() then
return CargoHostUnit
end
end
end end
return nil return nil
@ -451,7 +457,7 @@ CARGO_GROUP = {
function CARGO_GROUP:New( CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) function CARGO_GROUP:New( CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) )
self:T( { CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone } ) self:T( { CargoType, CargoName, CargoWeight, CargoGroupTemplate, CargoZone } )
self.CargoSpawn = SPAWN:New( CargoGroupTemplate ) self.CargoSpawn = SPAWN:NewWithAlias( CargoGroupTemplate, CargoName )
self.CargoZone = CargoZone self.CargoZone = CargoZone
CARGOS[self.CargoName] = self CARGOS[self.CargoName] = self
@ -647,7 +653,7 @@ CARGO_PACKAGE = {
function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoClient ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) ) function CARGO_PACKAGE:New( CargoType, CargoName, CargoWeight, CargoClient ) local self = BASE:Inherit( self, CARGO:New( CargoType, CargoName, CargoWeight ) )
self:T( { CargoType, CargoName, CargoWeight, CargoClient.ClientName } ) self:T( { CargoType, CargoName, CargoWeight, CargoClient } )
self.CargoClient = CargoClient self.CargoClient = CargoClient
@ -659,16 +665,16 @@ end
function CARGO_PACKAGE:Spawn() function CARGO_PACKAGE:Spawn()
self:T() self:T( self )
-- this needs to be checked thoroughly -- this needs to be checked thoroughly
local CargoClientInitGroup = self.CargoClient:ClientGroup() local CargoClientGroup = self.CargoClient:ClientGroup()
if not CargoClientInitGroup then if not CargoClientGroup then
if not self.CargoClientInitGroupSpawn then if not self.CargoClientSpawn then
self.CargoClientInitGroupSpawn = SPAWN:New( self.CargoClient:GetClientGroupName() ) self.CargoClientSpawn = SPAWN:New( self.CargoClient:GetClientGroupName() )
end end
self.CargoClientInitGroupSpawn:ReSpawn( 1 ) self.CargoClientSpawn:ReSpawn( 1 )
end end
local SpawnCargo = true local SpawnCargo = true

View File

@ -31,14 +31,17 @@ function GROUP:NewFromName( GroupName )
self:T( GroupName ) self:T( GroupName )
self.DCSGroup = Group.getByName( GroupName ) self.DCSGroup = Group.getByName( GroupName )
self.GroupName = self.DCSGroup:getName() if self.DCSGroup then
self.GroupID = self.DCSGroup:getID() self.GroupName = self.DCSGroup:getName()
self.GroupID = self.DCSGroup:getID()
end
return self return self
end end
function GROUP:GetDCSGroup() function GROUP:GetDCSGroup()
self:T( { self.GroupName } ) self:T( { self.GroupName } )
self.DCSGroup = Group.getByName( self.GroupName )
return self.DCSGroup return self.DCSGroup
end end

View File

@ -0,0 +1,31 @@
rem Generate Moose_Embedded.lua
copy Trace.lua ^
+ Routines.lua ^
+ Base.lua ^
+ Menu.lua ^
+ Group.lua ^
+ Unit.lua ^
+ Zone.lua ^
+ Database.lua ^
+ Cargo.lua ^
+ Client.lua ^
+ Message.lua ^
+ Stage.lua ^
+ Task.lua ^
+ GoHomeTask.lua ^
+ DestroyBaseTask.lua ^
+ DestroyGroupsTask.lua ^
+ DestroyRadarsTask.lua ^
+ DestroyUnitTypesTask.lua ^
+ PickupTask.lua ^
+ DeployTask.lua ^
+ NoTask.lua ^
+ RouteTask.lua ^
+ Mission.lua ^
+ CleanUp.lua ^
+ Spawn.lua ^
+ Movement.lua ^
+ Sead.lua ^
Moose_Embedded.lua

10379
Moose/Moose_Embedded.lua Normal file

File diff suppressed because it is too large Load Diff

View File

@ -132,5 +132,3 @@ self:T( { event } )
end end
end end
end end

View File

@ -20,44 +20,78 @@ SPAWN = {
--- Creates the main object to spawn a Group defined in the DCS ME. --- Creates the main object to spawn a Group defined in the DCS ME.
-- Spawned Groups and Units will follow the following naming convention within the DCS World run-time environment: -- Spawned Groups and Units will follow the following naming convention within the DCS World run-time environment:
-- Groups will have the name SpawnPrefix#ggg, where ggg is a counter from 0 to 999 for each new spawned Group. -- Groups will have the name SpawnTemplatePrefix#ggg, where ggg is a counter from 0 to 999 for each new spawned Group.
-- Units will have the name SpawnPrefix#ggg-uu, where uu is a counter from 0 to 99 for each new spawned Unit belonging to that Group. -- 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.
-- @tparam string SpawnPrefix is the name of the Group in the ME that defines the Template. That Group must have the flag "Late Activation" set. Note that this SpawnPrefix name should not contain any # character. -- @tparam string SpawnTemplatePrefix is the name of the Group in the ME that defines the Template. That Group must have the flag "Late Activation" set. Note that this SpawnTemplatePrefix name should not contain any # character.
-- @treturn SPAWN -- @treturn SPAWN
-- @usage -- @usage
-- -- NATO helicopters engaging in the battle field. -- -- NATO helicopters engaging in the battle field.
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ) -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' )
function SPAWN:New( SpawnPrefix ) function SPAWN:New( SpawnTemplatePrefix )
local self = BASE:Inherit( self, BASE:New() ) local self = BASE:Inherit( self, BASE:New() )
self:T( SpawnPrefix) self:T( { SpawnTemplatePrefix } )
local TemplateGroup = Group.getByName( SpawnPrefix ) local TemplateGroup = Group.getByName( SpawnTemplatePrefix )
if TemplateGroup then if TemplateGroup then
self.SpawnPrefix = SpawnPrefix self.SpawnTemplatePrefix = SpawnTemplatePrefix
self.SpawnIndex = 0 self.SpawnIndex = 0
self.SpawnCount = 0 -- The internal counter of the amount of spawning the has happened since SpawnStart. self.SpawnCount = 0 -- The internal counter of the amount of spawning the has happened since SpawnStart.
self.AliveUnits = 0 -- Contains the counter how many units are currently alive self.AliveUnits = 0 -- Contains the counter how many units are currently alive
self.SpawnIsScheduled = false -- Reflects if the spawning for this SpawnPrefix is going to be scheduled or not. self.SpawnIsScheduled = false -- Reflects if the spawning for this SpawnTemplatePrefix is going to be scheduled or not.
self.SpawnTemplate = self._GetTemplate( self, SpawnPrefix ) -- Contains the template structure for a Group Spawn from the Mission Editor. Note that this group must have lateActivation always on!!! 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.SpawnRepeat = false -- Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning. self.SpawnRepeat = 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.UnControlled = false -- When working in UnControlled mode, all planes are Spawned in UnControlled mode before the scheduler starts.
self.SpawnMaxGroupsAlive = 0 -- The maximum amount of groups that can be alive of SpawnPrefix at the same time. self.SpawnMaxGroupsAlive = 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.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.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.SpawnVisible = false -- Flag that indicates if all the Groups of the SpawnGroup need to be visible when Spawned.
self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned. self.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned.
self.SpawnGroups[1] = {}
self.SpawnGroups[1].Visible = false
self.SpawnGroups[1].Spawned = false
self.SpawnGroups[1].UnControlled = false
self.SpawnGroups[1].Spawned = false
self.SpawnGroups[1].SpawnTime = 0
self.SpawnGroups[1].SpawnPrefix = self.SpawnPrefix
self.SpawnGroups[1].SpawnTemplate = self:_Prepare( self.SpawnPrefix, 1 )
else else
error( "SPAWN:New: There is no group declared in the mission editor with SpawnPrefix = '" .. SpawnPrefix .. "'" ) error( "SPAWN:New: There is no group declared in the mission editor with SpawnTemplatePrefix = '" .. SpawnTemplatePrefix .. "'" )
end
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_CRASH, self.OnDeadOrCrash )
self.EnableEvents( self )
return self
end
--- Creates the main object to spawn a Group defined in the DCS ME.
-- Spawned Groups and Units will follow the following naming convention within the DCS World run-time environment:
-- Groups will have the name SpawnTemplatePrefix#ggg, where ggg is a counter from 0 to 999 for each new spawned Group.
-- 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.
-- @tparam string SpawnTemplatePrefix is the name of the Group in the ME that defines the Template. That Group must have the flag "Late Activation" set. Note that this SpawnTemplatePrefix name should not contain any # character.
-- @treturn SPAWN
-- @usage
-- -- NATO helicopters engaging in the battle field.
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' )
function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
local self = BASE:Inherit( self, BASE:New() )
self:T( { SpawnTemplatePrefix, SpawnAliasPrefix } )
local TemplateGroup = Group.getByName( SpawnTemplatePrefix )
if TemplateGroup then
self.SpawnTemplatePrefix = SpawnTemplatePrefix
self.SpawnAliasPrefix = SpawnAliasPrefix
self.SpawnIndex = 0
self.SpawnCount = 0 -- The internal counter of the amount of spawning the has happened since SpawnStart.
self.AliveUnits = 0 -- Contains the counter how many units are currently alive
self.SpawnIsScheduled = false -- Reflects if the spawning for this SpawnTemplatePrefix is going to be scheduled or not.
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.SpawnRepeat = 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.SpawnMaxGroupsAlive = 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.SpawnGroups = {} -- Array containing the descriptions of each Group to be Spawned.
else
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 )
@ -71,21 +105,13 @@ end
function SPAWN:Limit( SpawnMaxGroupsAlive, SpawnMaxGroups ) function SPAWN:Limit( SpawnMaxGroupsAlive, SpawnMaxGroups )
self:T( { SpawnMaxGroupsAlive, SpawnMaxGroups } ) self:T( { self.SpawnTemplatePrefix, SpawnMaxGroupsAlive, SpawnMaxGroups } )
self.SpawnMaxGroupsAlive = SpawnMaxGroupsAlive -- The maximum amount of groups that can be alive of SpawnPrefix at the same time. self.SpawnMaxGroupsAlive = SpawnMaxGroupsAlive -- 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. 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.SpawnGroups[SpawnGroupID] = {} self:InitializeSpawnGroups( SpawnGroupID )
self.SpawnGroups[SpawnGroupID].Visible = false
self.SpawnGroups[SpawnGroupID].Spawned = false
self.SpawnGroups[SpawnGroupID].UnControlled = false
self.SpawnGroups[SpawnGroupID].Spawned = false
self.SpawnGroups[SpawnGroupID].SpawnTime = 0
self.SpawnGroups[SpawnGroupID].SpawnPrefix = self.SpawnPrefix
self.SpawnGroups[SpawnGroupID].SpawnTemplate = self:_Prepare( self.SpawnPrefix, SpawnGroupID )
end end
return self return self
@ -105,16 +131,31 @@ end
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):RandomizeRoute( 2, 2, 2000 ) -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):RandomizeRoute( 2, 2, 2000 )
function SPAWN:RandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius ) function SPAWN:RandomizeRoute( SpawnStartPoint, SpawnEndPoint, SpawnRadius )
self:T( { SpawnStartPoint, SpawnEndPoint, SpawnRadius } ) self:T( { self.SpawnTemplatePrefix, SpawnStartPoint, SpawnEndPoint, SpawnRadius } )
self.SpawnRandomizeRoute = true
self.SpawnRandomizeRouteStartPoint = SpawnStartPoint
self.SpawnRandomizeRouteEndPoint = SpawnEndPoint
self.SpawnRandomizeRouteRadius = SpawnRadius
for GroupID = 1, self.SpawnMaxGroups do for GroupID = 1, self.SpawnMaxGroups do
self:_RandomizeRoute( GroupID )
local SpawnTemplate = self.SpawnGroups[GroupID].SpawnTemplate end
return self
end
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 local RouteCount = #SpawnTemplate.route.points
for t = SpawnStartPoint + 1, ( RouteCount - SpawnEndPoint ) do for t = self.SpawnRandomizeRouteStartPoint + 1, ( RouteCount - self.SpawnRandomizeRouteEndPoint ) do
SpawnTemplate.route.points[t].x = SpawnTemplate.route.points[t].x + math.random( SpawnRadius * -1, SpawnRadius ) 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( SpawnRadius * -1, SpawnRadius ) 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 SpawnTemplate.route.points[t].alt = nil
--SpawnGroup.route.points[t].alt_type = 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 ) self:T( 'SpawnTemplate.route.points[' .. t .. '].x = ' .. SpawnTemplate.route.points[t].x .. ', SpawnTemplate.route.points[' .. t .. '].y = ' .. SpawnTemplate.route.points[t].y )
@ -125,14 +166,14 @@ self:T( { SpawnStartPoint, SpawnEndPoint, SpawnRadius } )
end 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 random types of Groups defined within the ME, but they all need to follow the same Template route and have the same SpawnPrefix name, then this method becomes very useful. -- This function becomes useful when you need to SPAWN random types of Groups defined within the ME, but they all need to follow the same Template route and have the same SpawnTemplatePrefix name, then this method becomes very useful.
-- @tparam table{string,...} SpawnPrefixTable is a table with the names of the Groups defined within the ME (with late activatio on), from which on a new SPAWN of SpawnPrefix (the main Group name), a NEW Group will be choosen as the Group to be SPAWNed. -- @tparam table{string,...} SpawnTemplatePrefixTable is a table with the names of the Groups defined within the ME (with late activatio on), from which on a new SPAWN of SpawnTemplatePrefix (the main Group name), a NEW Group will be choosen as the Group to be SPAWNed.
-- In other words, this method randomizes between a defined set of Groups the Group to be SPAWNed for each new SPAWN. -- In other words, this method randomizes between a defined set of Groups the Group to be SPAWNed for each new SPAWN.
-- @treturn SPAWN -- @treturn SPAWN
-- @usage -- @usage
-- -- NATO Tank Platoons invading Gori. -- -- NATO Tank Platoons invading Gori.
-- -- Choose between 13 different 'US Tank Platoon' configurations for each new SPAWN the Group to be SPAWNed for the -- -- Choose between 13 different 'US Tank Platoon' configurations for each new SPAWN the Group to be SPAWNed for the
-- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SpawnPrefixes. -- -- 'US Tank Platoon Left', 'US Tank Platoon Middle' and 'US Tank Platoon Right' SpawnTemplatePrefixes.
-- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and -- -- Each new SPAWN will randomize the route, with a defined time interval of 200 seconds with 40% time variation (randomization) and
-- -- with a limit set of maximum 12 Units alive simulteneously and 150 Groups to be SPAWNed during the whole mission. -- -- with a limit set of maximum 12 Units alive simulteneously and 150 Groups to be SPAWNed during the whole mission.
-- Spawn_US_Platoon = { 'US Tank Platoon 1', 'US Tank Platoon 2', 'US Tank Platoon 3', 'US Tank Platoon 4', 'US Tank Platoon 5', -- Spawn_US_Platoon = { 'US Tank Platoon 1', 'US Tank Platoon 2', 'US Tank Platoon 3', 'US Tank Platoon 4', 'US Tank Platoon 5',
@ -142,23 +183,36 @@ end
-- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):Limit( 12, 150 ):Schedule( 200, 0.4 ):RandomizeTemplate( Spawn_US_Platoon ):RandomizeRoute( 3, 3, 2000 ) -- Spawn_US_Platoon_Middle = SPAWN:New( 'US Tank Platoon Middle' ):Limit( 12, 150 ):Schedule( 200, 0.4 ):RandomizeTemplate( Spawn_US_Platoon ):RandomizeRoute( 3, 3, 2000 )
-- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):Limit( 12, 150 ):Schedule( 200, 0.4 ):RandomizeTemplate( Spawn_US_Platoon ):RandomizeRoute( 3, 3, 2000 ) -- Spawn_US_Platoon_Right = SPAWN:New( 'US Tank Platoon Right' ):Limit( 12, 150 ):Schedule( 200, 0.4 ):RandomizeTemplate( Spawn_US_Platoon ):RandomizeRoute( 3, 3, 2000 )
function SPAWN:RandomizeTemplate( SpawnPrefixTable ) function SPAWN:RandomizeTemplate( SpawnTemplatePrefixTable )
self:T( { SpawnPrefix, SpawnPrefixTable } ) self:T( { self.SpawnTemplatePrefix, SpawnTemplatePrefixTable } )
self.SpawnPrefixTable = SpawnPrefixTable self.SpawnTemplatePrefixTable = SpawnTemplatePrefixTable
self.SpawnRandomizeTemplate = true
for SpawnGroupID = 1, self.SpawnMaxGroups do for SpawnGroupID = 1, self.SpawnMaxGroups do
self.SpawnGroups[SpawnGroupID].SpawnPrefix = self.SpawnPrefixTable[ math.random( 1, #SpawnPrefixTable ) ] self:_RandomizeTemplate( SpawnGroupID )
self.SpawnGroups[SpawnGroupID].SpawnTemplate = self:_Prepare( self.SpawnGroups[SpawnGroupID].SpawnPrefix, SpawnGroupID )
self.SpawnGroups[SpawnGroupID].SpawnTemplate.route = routines.utils.deepCopy( self.SpawnTemplate.route )
self.SpawnGroups[SpawnGroupID].SpawnTemplate.x = self.SpawnTemplate.x
self.SpawnGroups[SpawnGroupID].SpawnTemplate.y = self.SpawnTemplate.y
end end
return self return self
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
--- When a Group got SPAWNed, it has a life within the DCSRTE. For planes and helicopters, when these Units go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the DCSRTE. --- When a Group got SPAWNed, it has a life within the DCSRTE. For planes and helicopters, when these Units go home and land on their home airbases and farps, they normally would taxi to the parking spot, shut-down their engines and wait forever until the Group is removed by the DCSRTE.
-- This function is used to Re-Spawn automatically (so no extra call is needed anymore) the same Group after it landed. This will enable a SPAWNed group to be Re-SPAWNed after it lands, until it is destroyed... -- This function is used to Re-Spawn automatically (so no extra call is needed anymore) the same Group after it landed. This will enable a SPAWNed group to be Re-SPAWNed after it lands, until it is destroyed...
@ -170,7 +224,7 @@ end
-- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown() -- SpawnRU_SU34 = SPAWN:New( 'TF1 RU Su-34 Krymsk@AI - Attack Ships' ):Schedule( 2, 3, 1800, 0.4 ):SpawnUncontrolled():RandomizeRoute( 1, 1, 3000 ):RepeatOnEngineShutDown()
function SPAWN:Repeat() function SPAWN:Repeat()
self:T() self:T( { self.SpawnTemplatePrefix } )
self.SpawnRepeat = true self.SpawnRepeat = true
self.RepeatOnEngineShutDown = false self.RepeatOnEngineShutDown = false
@ -189,7 +243,7 @@ end
-- @see Repeat -- @see Repeat
function SPAWN:RepeatOnLanding() function SPAWN:RepeatOnLanding()
self:T() self:T( { self.SpawnTemplatePrefix } )
self:Repeat() self:Repeat()
self.RepeatOnEngineShutDown = false self.RepeatOnEngineShutDown = false
@ -203,7 +257,7 @@ end
-- @see Repeat -- @see Repeat
function SPAWN:RepeatOnEngineShutDown() function SPAWN:RepeatOnEngineShutDown()
self:T() self:T( { self.SpawnTemplatePrefix } )
self:Repeat() self:Repeat()
self.RepeatOnEngineShutDown = true self.RepeatOnEngineShutDown = true
@ -213,7 +267,7 @@ self:T()
end end
function SPAWN:CleanUp( SpawnCleanUpInterval ) function SPAWN:CleanUp( SpawnCleanUpInterval )
self:T() self:T( { self.SpawnTemplatePrefix, SpawnCleanUpInterval } )
self.SpawnCleanUpInterval = SpawnCleanUpInterval self.SpawnCleanUpInterval = SpawnCleanUpInterval
self.SpawnCleanUpTimeStamps = {} self.SpawnCleanUpTimeStamps = {}
@ -237,7 +291,7 @@ end
-- Spawn_BE_Ground = SPAWN:New( 'BE Ground' ):Limit( 2, 24 ):Visible( ZONE:New( "Start" ), 90, "Diamond", 10, 100, 50 ) -- Spawn_BE_Ground = SPAWN:New( 'BE Ground' ):Limit( 2, 24 ):Visible( ZONE:New( "Start" ), 90, "Diamond", 10, 100, 50 )
function SPAWN:SpawnArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY ) function SPAWN:SpawnArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY )
self:T( { SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY } ) self:T( { self.SpawnTemplatePrefix, SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY } )
self.SpawnVisible = true -- When the first Spawn executes, all the Groups need to be made visible before start. self.SpawnVisible = true -- When the first Spawn executes, all the Groups need to be made visible before start.
@ -263,41 +317,7 @@ self:T( { SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY } )
local SpawnRootX = self.SpawnGroups[SpawnGroupID].SpawnTemplate.x local SpawnRootX = self.SpawnGroups[SpawnGroupID].SpawnTemplate.x
local SpawnRootY = self.SpawnGroups[SpawnGroupID].SpawnTemplate.y local SpawnRootY = self.SpawnGroups[SpawnGroupID].SpawnTemplate.y
-- Translate self:_TranslateRotate( SpawnGroupID, SpawnRootX, SpawnRootY, SpawnX, SpawnY, SpawnAngle )
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[SpawnGroupID].SpawnTemplate.x = SpawnRootX - RotatedX
self.SpawnGroups[SpawnGroupID].SpawnTemplate.y = SpawnRootY + RotatedY
local SpawnUnitCount = table.getn( self.SpawnGroups[SpawnGroupID].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[SpawnGroupID].SpawnTemplate.units[u].x = SpawnRootX - RotatedX
self.SpawnGroups[SpawnGroupID].SpawnTemplate.units[u].y = SpawnRootY + RotatedY
end
self.SpawnGroups[SpawnGroupID].SpawnTemplate.lateActivation = true self.SpawnGroups[SpawnGroupID].SpawnTemplate.lateActivation = true
self.SpawnGroups[SpawnGroupID].SpawnTemplate.visible = true self.SpawnGroups[SpawnGroupID].SpawnTemplate.visible = true
@ -312,13 +332,76 @@ self:T( { 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
function SPAWN:GetSpawnIndex( SpawnIndex )
self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxGroupsAlive, self.AliveUnits, #self.SpawnTemplate.units } )
if ( self.SpawnMaxGroups == 0 ) or ( SpawnIndex <= self.SpawnMaxGroups ) then
if ( self.SpawnMaxGroupsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxGroupsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
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 SPAWN a Group whenever you want to do this. --- Will SPAWN a Group whenever you want to do this.
-- Note that the configuration with the above functions will apply when calling this method: Maxima, Randomization of routes, Scheduler, ... -- Note that the configuration with the above functions will apply when calling this method: Maxima, Randomization of routes, Scheduler, ...
-- Uses @{DATABASE} global object defined in MOOSE. -- Uses @{DATABASE} global object defined in MOOSE.
-- @treturn SPAWN -- @treturn SPAWN
function SPAWN:Spawn() function SPAWN:Spawn()
self:T( { self.SpawnPrefix } ) self:T( { self.SpawnTemplatePrefix, self.SpawnIndex } )
return self:SpawnWithIndex( self.SpawnIndex + 1 ) return self:SpawnWithIndex( self.SpawnIndex + 1 )
end end
@ -329,16 +412,16 @@ end
-- @treturn SPAWN -- @treturn SPAWN
-- Uses _Database global object defined in MOOSE. -- Uses _Database global object defined in MOOSE.
function SPAWN:ReSpawn( SpawnIndex ) function SPAWN:ReSpawn( SpawnIndex )
self:T( { SpawnIndex } ) self:T( { self.SpawnTemplatePrefix, SpawnIndex } )
local DCSGroup = self:GetGroupFromIndex( SpawnIndex ):GetDCSGroup()
if DCSGroup then
DCSGroup:destroy()
end
if not SpawnIndex then if not SpawnIndex then
SpawnIndex = 1 SpawnIndex = 1
end end
--local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ):GetDCSGroup()
--if SpawnGroup then
--DCSGroup:destroy()
--end
return self:SpawnWithIndex( SpawnIndex ) return self:SpawnWithIndex( SpawnIndex )
end end
@ -348,25 +431,26 @@ end
-- Uses @{DATABASE} global object defined in MOOSE. -- Uses @{DATABASE} global object defined in MOOSE.
-- @treturn GROUP The @{GROUP} that was spawned. You can use this group for further actions. -- @treturn 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.SpawnPrefix, SpawnIndex, self.SpawnMaxGroups } ) self:T( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups } )
if self.SpawnMaxGroups == 0 or SpawnIndex <= self.SpawnMaxGroups then if self:GetSpawnIndex( SpawnIndex ) then
if self.SpawnGroups[SpawnIndex].Visible then if self.SpawnGroups[self.SpawnIndex].Visible then
self.SpawnGroups[SpawnIndex].Group:Activate() self.SpawnGroups[self.SpawnIndex].Group:Activate()
else else
self.SpawnGroups[SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[SpawnIndex].SpawnTemplate ) self.SpawnGroups[self.SpawnIndex].Group = _Database:Spawn( self.SpawnGroups[self.SpawnIndex].SpawnTemplate )
--if self.SpawnRepeat then --if self.SpawnRepeat then
-- _Database:SetStatusGroup( SpawnTemplate.name, "ReSpawn" ) -- _Database:SetStatusGroup( SpawnTemplate.name, "ReSpawn" )
--end --end
end end
self.SpawnGroups[SpawnIndex].Spawned = true
self.SpawnIndex = SpawnIndex self.SpawnGroups[self.SpawnIndex].Spawned = true
return self.SpawnGroups[self.SpawnIndex].Group
else else
env.info( "No more Groups to Spawn" ) env.info( "No more Groups to Spawn" )
end end
return self.SpawnGroups[SpawnIndex].Group return nil
end end
--- SPAWNs a new Group within varying time intervals. This is useful if you want to have continuity within your missions of certain (AI) Groups to be present (alive) within your missions. --- SPAWNs a new Group within varying time intervals. This is useful if you want to have continuity within your missions of certain (AI) Groups to be present (alive) within your missions.
@ -384,10 +468,10 @@ end
-- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 ) -- Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation ) function SPAWN:SpawnScheduled( SpawnTime, SpawnTimeVariation )
self:T( { SpawnTime, SpawnTimeVariation } ) self:T( { SpawnTime, SpawnTimeVariation } )
self.SpawnCurrentTimer = 0 -- The internal timer counter to trigger a scheduled spawning of SpawnPrefix. self.SpawnCurrentTimer = 0 -- The internal timer counter to trigger a scheduled spawning of SpawnTemplatePrefix.
self.SpawnSetTimer = 0 -- The internal timer value when a scheduled spawning of SpawnPrefix occurs. self.SpawnSetTimer = 0 -- The internal timer value when a scheduled spawning of SpawnTemplatePrefix occurs.
self.AliveFactor = 1 -- self.AliveFactor = 1 --
self.SpawnLowTimer = 0 self.SpawnLowTimer = 0
self.SpawnHighTimer = 0 self.SpawnHighTimer = 0
@ -406,7 +490,7 @@ end
--- Will start the SPAWNing timers. --- Will start the SPAWNing timers.
-- This function is called automatically when @{Schedule} is called. -- This function is called automatically when @{Schedule} is called.
function SPAWN:ScheduleStart() function SPAWN:ScheduleStart()
self:T() self:T( { self.SpawnTemplatePrefix } )
--local ClientUnit = #AlivePlayerUnits() --local ClientUnit = #AlivePlayerUnits()
@ -423,15 +507,16 @@ end
--- Will stop the scheduled SPAWNing activity. --- Will stop the scheduled SPAWNing activity.
function SPAWN:ScheduleStop() function SPAWN:ScheduleStop()
self:T() self:T( { self.SpawnTemplatePrefix } )
self.SpawnIsScheduled = false self.SpawnIsScheduled = false
end end
--- Limits the Maximum amount of Units to be alive, and the maximum amount of Groups to be SPAWNed within the DCS World run-time environment. --- Limits the Maximum amount of Units to be alive, and the maximum amount of Groups to be SPAWNed within the DCS World run-time environment.
-- Note that this method is exceptionally important to balance the amount of Units alive within the DCSRTE and the performance of the mission. Depending on the machine etc, a mission can only process a maximum amount of units. -- Note that this method is exceptionally important to balance the amount of Units alive within the DCSRTE and the performance of the mission. Depending on the machine etc, a mission can only process a maximum amount of units.
-- If the time interval must be short, but there should not be more Units or Groups alive than a maximum amount of units, then this function should be used... -- If the time interval must be short, but there should not be more Units or Groups alive than a maximum amount of units, then this function should be used...
-- @tparam number SpawnMaxGroupsAlive is the Maximum amount of Units to be alive. When there are more Units alive in the DCSRTE of SpawnPrefix, then no new SPAWN will happen of the Group, until some of these Units will be destroyed. -- @tparam number SpawnMaxGroupsAlive is the Maximum amount of Units to be alive. When there are more Units alive in the DCSRTE of SpawnTemplatePrefix, then no new SPAWN will happen of the Group, until some of these Units will be destroyed.
-- @tparam number SpawnMaxGroups is the Maximum amount of Groups that can be SPAWNed from SpawnPrefix. When there are more Groups alive in the DCSRTE of SpawnPrefix, then no more SPAWNs will happen of the Group. This parameter is useful to define a maximum amount of airplanes, ground troops, helicopters, ships etc within a supply area. -- @tparam number SpawnMaxGroups is the Maximum amount of Groups that can be SPAWNed from SpawnTemplatePrefix. When there are more Groups alive in the DCSRTE of SpawnTemplatePrefix, then no more SPAWNs will happen of the Group. This parameter is useful to define a maximum amount of airplanes, ground troops, helicopters, ships etc within a supply area.
-- This parameter accepts the value 0, which expresses no Group count limits. -- This parameter accepts the value 0, which expresses no Group count limits.
-- @treturn SPAWN -- @treturn SPAWN
-- @usage -- @usage
@ -445,9 +530,9 @@ end
--- Will SPAWN a Group whenever you want to do this, but for AIR Groups only to be applied, and will SPAWN the Group in Uncontrolled mode... This will be similar to the Uncontrolled flag setting in the ME. --- Will SPAWN a Group whenever you want to do this, but for AIR Groups only to be applied, and will SPAWN the Group in Uncontrolled mode... This will be similar to the Uncontrolled flag setting in the ME.
-- @treturn SPAWN -- @treturn SPAWN
function SPAWN:UnControlled() function SPAWN:UnControlled()
self:T() self:T( { self.SpawnTemplatePrefix } )
self.UnControlled = true self.SpawnUnControlled = true
for SpawnGroupID = 1, self.SpawnMaxGroups do for SpawnGroupID = 1, self.SpawnMaxGroups do
self.SpawnGroups[SpawnGroupID].UnControlled = true self.SpawnGroups[SpawnGroupID].UnControlled = true
@ -464,65 +549,62 @@ end
-- @treturn GROUP Spawned. -- @treturn GROUP Spawned.
-- @treturn nil when nothing was spawned. -- @treturn nil when nothing was spawned.
function SPAWN:SpawnFromUnit( HostUnit, OuterRadius, InnerRadius ) function SPAWN:SpawnFromUnit( HostUnit, OuterRadius, InnerRadius )
self:T( { HostUnit, SpawnFormation, self.SpawnIndex } ) self:T( { self.SpawnTemplatePrefix, HostUnit, SpawnFormation } )
if HostUnit and HostUnit:IsAlive() then -- and HostUnit:getUnit(1):inAir() == false then if HostUnit and HostUnit:IsAlive() then -- and HostUnit:getUnit(1):inAir() == false then
self.SpawnIndex = self.SpawnIndex + 1 if self:GetSpawnIndex( self.SpawnIndex + 1 ) then
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
if SpawnTemplate then if SpawnTemplate then
if ( self.SpawnMaxGroups == 0 ) or ( self.SpawnCount <= self.SpawnMaxGroups ) then
if ( self.SpawnMaxGroupsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxGroupsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
local UnitPoint = HostUnit:GetPoint() local UnitPoint = HostUnit:GetPoint()
--for PointID, Point in pairs( SpawnTemplate.route.points ) do --for PointID, Point in pairs( SpawnTemplate.route.points ) do
--Point.x = UnitPoint.x --Point.x = UnitPoint.x
--Point.y = UnitPoint.y --Point.y = UnitPoint.y
--Point.alt = nil --Point.alt = nil
--Point.alt_type = nil --Point.alt_type = nil
--end --end
SpawnTemplate.route.points = nil SpawnTemplate.route.points = nil
SpawnTemplate.route.points = {} SpawnTemplate.route.points = {}
SpawnTemplate.route.points[1] = {} SpawnTemplate.route.points[1] = {}
SpawnTemplate.route.points[1].x = UnitPoint.x SpawnTemplate.route.points[1].x = UnitPoint.x
SpawnTemplate.route.points[1].y = UnitPoint.y SpawnTemplate.route.points[1].y = UnitPoint.y
if not InnerRadius then if not InnerRadius then
InnerRadius = 10 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
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 end
end end
@ -535,45 +617,42 @@ end
-- @treturn GROUP that was spawned. -- @treturn GROUP that was spawned.
-- @treturn nil when nothing as spawned. -- @treturn nil when nothing as spawned.
function SPAWN:SpawnInZone( Zone ) function SPAWN:SpawnInZone( Zone )
self:T( Zone ) self:T( { self.SpawnTemplatePrefix, Zone } )
if Zone then if Zone then
if self:GetSpawnIndex( self.SpawnIndex + 1) then
self.SpawnIndex = self.SpawnIndex + 1 local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
local SpawnTemplate = self.SpawnGroups[self.SpawnIndex].SpawnTemplate
if SpawnTemplate then
if SpawnTemplate then local ZonePoint = Zone:GetPoint()
if ( self.SpawnMaxGroups == 0 ) or ( self.SpawnCount <= self.SpawnMaxGroups ) then
if ( self.SpawnMaxGroupsAlive == 0 ) or ( self.AliveUnits < self.SpawnMaxGroupsAlive * #self.SpawnTemplate.units ) or self.UnControlled then
local ZonePoint = Zone:GetPoint() SpawnTemplate.route.points = nil
SpawnTemplate.route.points = {}
SpawnTemplate.route.points = nil SpawnTemplate.route.points[1] = {}
SpawnTemplate.route.points = {} SpawnTemplate.route.points[1].x = ZonePoint.x
SpawnTemplate.route.points[1] = {} SpawnTemplate.route.points[1].y = ZonePoint.y
SpawnTemplate.route.points[1].x = ZonePoint.x
SpawnTemplate.route.points[1].y = ZonePoint.y -- Apply SpawnFormation
for UnitID = 1, #SpawnTemplate.units do
-- Apply SpawnFormation SpawnTemplate.units[UnitID].x = ZonePoint.x
for UnitID = 1, #SpawnTemplate.units do SpawnTemplate.units[UnitID].y = ZonePoint.y
SpawnTemplate.units[UnitID].x = ZonePoint.x self:T( 'SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
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
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 end
end end
@ -586,20 +665,26 @@ end
-- @tparam number SpawnIndex is the number of the Group that is to be SPAWNed. -- @tparam number SpawnIndex is the number of the Group that is to be SPAWNed.
-- @treturn string SpawnGroupName -- @treturn string SpawnGroupName
function SPAWN:SpawnGroupName( SpawnIndex ) function SPAWN:SpawnGroupName( SpawnIndex )
self:T( { self.SpawnPrefix, SpawnIndex } ) self:T( { self.SpawnTemplatePrefix, SpawnIndex } )
local SpawnPrefix = self.SpawnTemplatePrefix
if self.SpawnAliasPrefix then
SpawnPrefix = self.SpawnAliasPrefix
end
if SpawnIndex then if SpawnIndex then
self:T( string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) ) local SpawnName = string.format( '%s#%03d', SpawnPrefix, SpawnIndex )
return string.format( '%s#%03d', self.SpawnPrefix, SpawnIndex ) self:T( SpawnName )
return SpawnName
else else
self:T( self.SpawnPrefix ) self:T( SpawnPrefix )
return self.SpawnPrefix return SpawnPrefix
end end
end end
function SPAWN:GetGroupFromIndex( SpawnIndex ) function SPAWN:GetGroupFromIndex( SpawnIndex )
self:T( { SpawnIndex } ) self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } )
if SpawnIndex then if SpawnIndex then
local SpawnGroup = self.SpawnGroups[SpawnIndex].Group local SpawnGroup = self.SpawnGroups[SpawnIndex].Group
@ -610,10 +695,10 @@ function SPAWN:GetGroupFromIndex( SpawnIndex )
end end
end end
function SPAWN:GetGroupIndexFromDCSUnit( Unit ) function SPAWN:GetGroupIndexFromDCSUnit( DCSUnit )
self:T() self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
local IndexString = string.match( Unit:getName(), "#.*-" ):sub( 2, -2 ) local IndexString = string.match( DCSUnit:getName(), "#.*-" ):sub( 2, -2 )
self:T( IndexString ) self:T( IndexString )
if IndexString then if IndexString then
@ -625,13 +710,21 @@ function SPAWN:GetGroupIndexFromDCSUnit( Unit )
return nil return nil
end end
function SPAWN:GetGroupFromDCSUnit( DCSUnit ) function SPAWN:GetPrefixFromDCSUnit( DCSUnit )
self:T() self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
local SpawnPrefix = string.match( DCSUnit:getName(), ".*#" ):sub( 1, -2 ) local SpawnPrefix = string.match( DCSUnit:getName(), ".*#" ):sub( 1, -2 )
self:T( SpawnPrefix ) self:T( SpawnPrefix )
return SpawnPrefix
end
function SPAWN:GetGroupFromDCSUnit( DCSUnit )
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, DCSUnit } )
if self.SpawnPrefix == SpawnPrefix then local SpawnPrefix = self:GetPrefixFromDCSUnit( DCSUnit )
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 )
@ -641,8 +734,10 @@ function SPAWN:GetGroupFromDCSUnit( DCSUnit )
return nil return nil
end end
function SPAWN:GetIndexFromGroup( SpawnGroup )
self:T( { self.SpawnPrefix, SpawnGroup } ) --TODO: Rename to GetGroupIndexFromGroup
function SPAWN:GetGroupIndexFromGroup( SpawnGroup )
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnGroup } )
local IndexString = string.match( SpawnGroup:GetName(), "#.*$" ):sub( 2 ) local IndexString = string.match( SpawnGroup:GetName(), "#.*$" ):sub( 2 )
local Index = tonumber( IndexString ) local Index = tonumber( IndexString )
@ -653,14 +748,38 @@ function SPAWN:GetIndexFromGroup( SpawnGroup )
end end
function SPAWN:GetLastIndex() function SPAWN:GetLastIndex()
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
return self.SpawnCount return self.SpawnMaxGroups
end
function SPAWN:InitializeSpawnGroups( SpawnIndex )
self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } )
if not self.SpawnGroups[SpawnIndex] then
self.SpawnGroups[SpawnIndex] = {}
self.SpawnGroups[SpawnIndex].Visible = false
self.SpawnGroups[SpawnIndex].Spawned = false
self.SpawnGroups[SpawnIndex].UnControlled = false
self.SpawnGroups[SpawnIndex].Spawned = false
self.SpawnGroups[SpawnIndex].SpawnTime = 0
self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix = self.SpawnTemplatePrefix
self.SpawnGroups[SpawnIndex].SpawnTemplate = self:_Prepare( self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix, SpawnIndex )
end
self:_RandomizeTemplate( SpawnIndex )
self:_RandomizeRoute( SpawnIndex )
--self:_TranslateRotate( SpawnIndex )
return self.SpawnGroups[SpawnIndex]
end end
function SPAWN:GetFirstAliveGroup( SpawnCursor ) function SPAWN:GetFirstAliveGroup( SpawnCursor )
self:T() self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnCursor } )
for SpawnIndex = 1, self.SpawnCount do for SpawnIndex = 1, self.SpawnCount do
local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) local SpawnGroup = self:GetGroupFromIndex( SpawnIndex )
@ -674,7 +793,7 @@ self:T()
end end
function SPAWN:GetNextAliveGroup( SpawnCursor ) function SPAWN:GetNextAliveGroup( SpawnCursor )
self:T() self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnCursor } )
SpawnCursor = SpawnCursor + 1 SpawnCursor = SpawnCursor + 1
for SpawnIndex = SpawnCursor, self.SpawnCount do for SpawnIndex = SpawnCursor, self.SpawnCount do
@ -689,7 +808,7 @@ self:T()
end end
function SPAWN:GetLastAliveGroup() function SPAWN:GetLastAliveGroup()
self:T() self:T( { self.SpawnTemplatePrefixself.SpawnAliasPrefix } )
self.SpawnIndex = self:GetLastIndex() self.SpawnIndex = self:GetLastIndex()
for SpawnIndex = self.SpawnIndex, 1, -1 do for SpawnIndex = self.SpawnIndex, 1, -1 do
@ -745,30 +864,30 @@ end
--- Gets the Group Template from the ME environment definition. --- Gets the Group Template from the ME environment definition.
-- This method used the @{DATABASE} object, which contains ALL initial and new SPAWNed object in MOOSE. -- This method used the @{DATABASE} object, which contains ALL initial and new SPAWNed object in MOOSE.
function SPAWN:_GetTemplate( SpawnPrefix ) function SPAWN:_GetTemplate( SpawnTemplatePrefix )
self:T( SpawnPrefix ) self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnTemplatePrefix } )
local SpawnTemplate = nil local SpawnTemplate = nil
SpawnTemplate = routines.utils.deepCopy( _Database.Groups[SpawnPrefix].Template ) SpawnTemplate = routines.utils.deepCopy( _Database.Groups[SpawnTemplatePrefix].Template )
if SpawnTemplate == nil then if SpawnTemplate == nil then
error( 'No Template returned for SpawnPrefix = ' .. SpawnPrefix ) error( 'No Template returned for SpawnTemplatePrefix = ' .. SpawnTemplatePrefix )
end end
SpawnTemplate.SpawnCoalitionID = self:_GetGroupCoalitionID( SpawnPrefix ) SpawnTemplate.SpawnCoalitionID = self:_GetGroupCoalitionID( SpawnTemplatePrefix )
SpawnTemplate.SpawnCategoryID = self:_GetGroupCategoryID( SpawnPrefix ) SpawnTemplate.SpawnCategoryID = self:_GetGroupCategoryID( SpawnTemplatePrefix )
SpawnTemplate.SpawnCountryID = self:_GetGroupCountryID( SpawnPrefix ) SpawnTemplate.SpawnCountryID = self:_GetGroupCountryID( SpawnTemplatePrefix )
self:T( { SpawnTemplate } ) self:T( { SpawnTemplate } )
return SpawnTemplate return SpawnTemplate
end end
--- Prepares the new Group Template. --- Prepares the new Group Template.
function SPAWN:_Prepare( SpawnPrefix, SpawnIndex ) function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex )
self:T() self:T( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
local SpawnTemplate = routines.utils.deepCopy( self:_GetTemplate( SpawnPrefix ) ) local SpawnTemplate = routines.utils.deepCopy( self:_GetTemplate( SpawnTemplatePrefix ) )
SpawnTemplate.name = self:SpawnGroupName( SpawnIndex ) SpawnTemplate.name = self:SpawnGroupName( SpawnIndex )
SpawnTemplate.groupId = nil SpawnTemplate.groupId = nil
@ -803,10 +922,10 @@ 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 = string.match( event.initiator:getName(), ".*#" ) local EventPrefix = self:GetPrefixFromDCSUnit( event.initiator )
if EventPrefix == self.SpawnPrefix .. '#' 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 " .. SpawnPrefix .. " spawned." , 5, EventPrefix .. '/Event') --MessageToAll( "Mission command: unit " .. SpawnTemplatePrefix .. " spawned." , 5, EventPrefix .. '/Event')
self.AliveUnits = self.AliveUnits + 1 self.AliveUnits = self.AliveUnits + 1
self:T( "Alive Units: " .. self.AliveUnits ) self:T( "Alive Units: " .. self.AliveUnits )
end end
@ -821,12 +940,12 @@ function SPAWN:OnDeadOrCrash( event )
if event.initiator and event.initiator:getName() then if event.initiator and event.initiator:getName() then
local EventPrefix = string.match( event.initiator:getName(), ".*#" ) local EventPrefix = self:GetPrefixFromDCSUnit( event.initiator )
if EventPrefix == self.SpawnPrefix .. '#' 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 )
-- if DestroyedUnit and DestroyedUnit.getLife() <= 1.0 then -- if DestroyedUnit and DestroyedUnit.getLife() <= 1.0 then
--MessageToAll( "Mission command: unit " .. SpawnPrefix .. " crashed." , 5, EventPrefix .. '/Event') --MessageToAll( "Mission command: unit " .. SpawnTemplatePrefix .. " crashed." , 5, EventPrefix .. '/Event')
self.AliveUnits = self.AliveUnits - 1 self.AliveUnits = self.AliveUnits - 1
self:T( "Alive Units: " .. self.AliveUnits ) self:T( "Alive Units: " .. self.AliveUnits )
-- end -- end
@ -861,7 +980,7 @@ function SPAWN:OnLand( 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:GetIndexFromGroup( 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
@ -882,7 +1001,7 @@ function SPAWN:OnEngineShutDown( event )
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:GetIndexFromGroup( 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
@ -896,16 +1015,12 @@ end
--- This function is called automatically by the Spawning scheduler. --- This function is called automatically by the Spawning scheduler.
-- It is the internal worker method SPAWNing new Groups on the defined time intervals. -- It is the internal worker method SPAWNing new Groups on the defined time intervals.
function SPAWN:_Scheduler() function SPAWN:_Scheduler()
self:T( { "_Scheduler", self.SpawnTemplatePrefix, self.SpawnAliasPrefix, self.SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxGroupsAlive } )
if self.SpawnInit or self.SpawnCurrentTimer == self.SpawnSetTimer then if self.SpawnInit or self.SpawnCurrentTimer == self.SpawnSetTimer then
self:T( "Spawn Scheduler:" .. self.SpawnPrefix )
-- Validate if there are still groups left in the batch... -- Validate if there are still groups left in the batch...
if ( self.SpawnMaxGroups == 0 ) or ( self.SpawnCount <= self.SpawnMaxGroups ) then self:Spawn()
if self.AliveUnits < self.SpawnMaxGroupsAlive * #self.SpawnTemplate.units or self.UnControlled then self.SpawnInit = false
self:Spawn()
self.SpawnInit = false
end
end
if self.SpawnIsScheduled == true then if self.SpawnIsScheduled == true then
--local ClientUnit = #AlivePlayerUnits() --local ClientUnit = #AlivePlayerUnits()
self.AliveFactor = 1 -- ( 10 - ClientUnit ) / 10 self.AliveFactor = 1 -- ( 10 - ClientUnit ) / 10
@ -918,7 +1033,7 @@ function SPAWN:_Scheduler()
end end
function SPAWN:_SpawnCleanUpScheduler() function SPAWN:_SpawnCleanUpScheduler()
self:T( "CleanUp Scheduler:" .. self.SpawnPrefix ) self:T( "CleanUp Scheduler:" .. self.SpawnTemplatePrefix )
local SpawnCursor local SpawnCursor
local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup( SpawnCursor ) local SpawnGroup, SpawnCursor = self:GetFirstAliveGroup( SpawnCursor )

View File

@ -284,11 +284,13 @@ self:T()
Client:Message( "We have arrived at the landing zone.", self.MSG.TIME, Mission.Name .. "/StageArrived", "Co-Pilot: Arrived", 10 ) Client:Message( "We have arrived at the landing zone.", self.MSG.TIME, Mission.Name .. "/StageArrived", "Co-Pilot: Arrived", 10 )
Task.HostUnit = Task.CurrentCargoZone:GetHostUnit() Task.HostUnit = Task.CurrentCargoZone:GetHostUnit()
self:T( { Task.HostUnit } )
if Task.HostUnit then if Task.HostUnit then
Task.HostUnitName = Task.HostUnit:getName() Task.HostUnitName = Task.HostUnit:GetPrefix()
Task.HostUnitTypeName = Task.HostUnit:getTypeName() Task.HostUnitTypeName = Task.HostUnit:GetTypeName()
local HostMessage = "" local HostMessage = ""
Task.CargoNames = "" Task.CargoNames = ""

View File

@ -30,6 +30,28 @@ function UNIT:IsAlive()
end end
function UNIT:GetName()
self:T( self.UnitName )
return self.UnitName
end
function UNIT:GetTypeName()
self:T( self.UnitName )
return self.DCSUnit:getTypeName()
end
function UNIT:GetPrefix()
self:T( self.UnitName )
local UnitPrefix = string.match( self.UnitName, ".*#" ):sub( 1, -2 )
self:T( UnitPrefix )
return UnitPrefix
end
function UNIT:GetCallSign() function UNIT:GetCallSign()
self:T( self.UnitName ) self:T( self.UnitName )

View File

@ -62,14 +62,13 @@ end
do do
local Mission = MISSION:New( 'Deliver secret letter', 'Operational', 'Pickup letter to the commander.', 'NATO' ) local Mission = MISSION:New( 'Deliver secret letter', 'Operational', 'Pickup letter to the commander.', 'NATO' )
Mission:AddClient( CLIENT:New( 'BE Package Test 1' ):Transport() ) Client_Package_1 = CLIENT:New( 'BE Package Test 1' ):Transport()
Mission:AddClient( CLIENT:New( 'BE Package Test 2' ):Transport() )
Mission:AddClient( CLIENT:New( 'DE Pickup Test 1' ):Transport() ) Mission:AddClient( Client_Package_1 )
Mission:AddClient( CLIENT:New( 'DE Pickup Test 2' ):Transport() )
Package_Pickup_Zone = CARGO_ZONE:New( 'Package Pickup Zone', 'DE Guard' ):GreenSmoke() Package_Pickup_Zone = CARGO_ZONE:New( 'Package Pickup Zone', 'DE Guard' ):GreenSmoke()
Cargo_Package = CARGO_PACKAGE:New( 'Letter', 'Letter to Command', 0.1, 'DE Guard' ) Cargo_Package = CARGO_PACKAGE:New( 'Letter', 'Letter to Command', 0.1, Client_Package_1 )
--Cargo_Goods = CARGO_STATIC:New( 'Goods', 20, 'Goods', 'Pickup Zone Goods', 'DE Collection Point' ) --Cargo_Goods = CARGO_STATIC:New( 'Goods', 20, 'Goods', 'Pickup Zone Goods', 'DE Collection Point' )
--Cargo_SlingLoad = CARGO_SLING:New( 'Basket', 40, 'Basket', 'Pickup Zone Sling Load', 'DE Cargo Guard' ) --Cargo_SlingLoad = CARGO_SLING:New( 'Basket', 40, 'Basket', 'Pickup Zone Sling Load', 'DE Cargo Guard' )

Binary file not shown.

Binary file not shown.