diff --git a/Moose Development/Moose/Base.lua b/Moose Development/Moose/Base.lua
index d30d37c5a..5e678ec66 100644
--- a/Moose Development/Moose/Base.lua
+++ b/Moose Development/Moose/Base.lua
@@ -331,9 +331,8 @@ function BASE:SetState( Object, StateName, State )
if not self.States[ClassNameAndID] then
self.States[ClassNameAndID] = {}
end
-
self.States[ClassNameAndID][StateName] = State
- self:E( { "SetState " .. ClassNameAndID .. "." .. StateName, State } )
+ self:E( { ClassNameAndID, StateName, State } )
return self.States[ClassNameAndID][StateName]
end
@@ -341,9 +340,11 @@ end
function BASE:GetState( Object, StateName )
local ClassNameAndID = Object:GetClassNameAndID()
+ self:E( { ClassNameAndID } )
if self.States[ClassNameAndID] then
- self:E( { " GetState " .. ClassNameAndID .. "." .. StateName, self.States[ClassNameAndID][StateName] } )
- return self.States[ClassNameAndID][StateName]
+ local State = self.States[ClassNameAndID][StateName]
+ self:E( { ClassNameAndID, StateName, State } )
+ return State
end
return nil
@@ -422,7 +423,10 @@ function BASE:F( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
end
if _TraceAll == true or _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName].Method[Function] then
- local LineCurrent = DebugInfoCurrent.currentline
+ local LineCurrent = 0
+ if DebugInfoCurrent.currentline then
+ LineCurrent = DebugInfoCurrent.currentline
+ end
local LineFrom = 0
if DebugInfoFrom then
LineFrom = DebugInfoFrom.currentline
@@ -476,7 +480,10 @@ function BASE:_T( Arguments, DebugInfoCurrentParam, DebugInfoFromParam )
end
if _TraceAll == true or _TraceClass[self.ClassName] or _TraceClassMethod[self.ClassName].Method[Function] then
- local LineCurrent = DebugInfoCurrent.currentline
+ local LineCurrent = 0
+ if DebugInfoCurrent.currentline then
+ LineCurrent = DebugInfoCurrent.currentline
+ end
local LineFrom = 0
if DebugInfoFrom then
LineFrom = DebugInfoFrom.currentline
diff --git a/Moose Development/Moose/Database.lua b/Moose Development/Moose/Database.lua
index ca8dfa7f2..c74cbdd64 100644
--- a/Moose Development/Moose/Database.lua
+++ b/Moose Development/Moose/Database.lua
@@ -54,9 +54,6 @@ DATABASE = {
ClientsByName = {},
ClientsByID = {},
},
- DCSUnits = {},
- DCSGroups = {},
- DCSStatics = {},
UNITS = {},
STATICS = {},
GROUPS = {},
@@ -125,10 +122,13 @@ end
--- Adds a Unit based on the Unit Name in the DATABASE.
-- @param #DATABASE self
-function DATABASE:AddUnit( DCSUnit, DCSUnitName )
+function DATABASE:AddUnit( DCSUnitName )
- self.DCSUnits[DCSUnitName] = DCSUnit
- self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName )
+ if not self.UNITS[DCSUnitName] then
+ self.UNITS[DCSUnitName] = UNIT:Register( DCSUnitName )
+ end
+
+ return self.UNITS[DCSUnitName]
end
@@ -136,15 +136,16 @@ end
-- @param #DATABASE self
function DATABASE:DeleteUnit( DCSUnitName )
- self.DCSUnits[DCSUnitName] = nil
+ --self.UNITS[DCSUnitName] = nil
end
--- Adds a Static based on the Static Name in the DATABASE.
-- @param #DATABASE self
-function DATABASE:AddStatic( DCSStatic, DCSStaticName )
+function DATABASE:AddStatic( DCSStaticName )
- self.DCSStatics[DCSStaticName] = DCSStatic
- self.STATICS[DCSStaticName] = STATIC:Register( DCSStaticName )
+ if not self.STATICS[DCSStaticName] then
+ self.STATICS[DCSStaticName] = STATIC:Register( DCSStaticName )
+ end
end
@@ -152,7 +153,7 @@ end
-- @param #DATABASE self
function DATABASE:DeleteStatic( DCSStaticName )
- self.DCSStatics[DCSStaticName] = nil
+ --self.STATICS[DCSStaticName] = nil
end
--- Finds a STATIC based on the StaticName.
@@ -181,8 +182,11 @@ end
-- @param #DATABASE self
function DATABASE:AddClient( ClientName )
- self.CLIENTS[ClientName] = CLIENT:Register( ClientName )
- self:E( self.CLIENTS[ClientName]:GetClassNameAndID() )
+ if not self.CLIENTS[ClientName] then
+ self.CLIENTS[ClientName] = CLIENT:Register( ClientName )
+ end
+
+ return self.CLIENTS[ClientName]
end
@@ -199,10 +203,13 @@ end
--- Adds a GROUP based on the GroupName in the DATABASE.
-- @param #DATABASE self
-function DATABASE:AddGroup( DCSGroup, GroupName )
+function DATABASE:AddGroup( GroupName )
- self.DCSGroups[GroupName] = DCSGroup
- self.GROUPS[GroupName] = GROUP:Register( GroupName )
+ if not self.GROUPS[GroupName] then
+ self.GROUPS[GroupName] = GROUP:Register( GroupName )
+ end
+
+ return self.GROUPS[GroupName]
end
--- Adds a player based on the Player Name in the DATABASE.
@@ -261,7 +268,7 @@ function DATABASE:Spawn( SpawnTemplate )
SpawnTemplate.SpawnCountryID = SpawnCountryID
SpawnTemplate.SpawnCategoryID = SpawnCategoryID
- local SpawnGroup = GROUP:Register( SpawnTemplate.name )
+ local SpawnGroup = self:AddGroup( SpawnTemplate.name )
return SpawnGroup
end
@@ -400,14 +407,14 @@ function DATABASE:_RegisterGroupsAndUnits()
if DCSGroup:isExist() then
local DCSGroupName = DCSGroup:getName()
- self:E( { "Register Group:", DCSGroup, DCSGroupName } )
- self:AddGroup( DCSGroup, DCSGroupName )
+ self:E( { "Register Group:", DCSGroupName } )
+ self:AddGroup( DCSGroupName )
for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do
local DCSUnitName = DCSUnit:getName()
- self:E( { "Register Unit:", DCSUnit, DCSUnitName } )
- self:AddUnit( DCSUnit, DCSUnitName )
+ self:E( { "Register Unit:", DCSUnitName } )
+ self:AddUnit( DCSUnitName )
end
else
self:E( { "Group does not exist: ", DCSGroup } )
@@ -441,8 +448,8 @@ function DATABASE:_RegisterStatics()
if DCSStatic:isExist() then
local DCSStaticName = DCSStatic:getName()
- self:E( { "Register Static:", DCSStatic, DCSStaticName } )
- self:AddStatic( DCSStatic, DCSStaticName )
+ self:E( { "Register Static:", DCSStaticName } )
+ self:AddStatic( DCSStaticName )
else
self:E( { "Static does not exist: ", DCSStatic } )
end
@@ -462,8 +469,8 @@ function DATABASE:_EventOnBirth( Event )
self:F2( { Event } )
if Event.IniDCSUnit then
- self:AddUnit( Event.IniDCSUnit, Event.IniDCSUnitName )
- self:AddGroup( Event.IniDCSGroup, Event.IniDCSGroupName )
+ self:AddUnit( Event.IniDCSUnitName )
+ self:AddGroup( Event.IniDCSGroupName )
self:_EventOnPlayerEnterUnit( Event )
end
end
@@ -476,7 +483,7 @@ function DATABASE:_EventOnDeadOrCrash( Event )
self:F2( { Event } )
if Event.IniDCSUnit then
- if self.DCSUnits[Event.IniDCSUnitName] then
+ if self.UNITS[Event.IniDCSUnitName] then
self:DeleteUnit( Event.IniDCSUnitName )
-- add logic to correctly remove a group once all units are destroyed...
end
@@ -558,19 +565,6 @@ function DATABASE:ForEach( IteratorFunction, arg, Set )
end
---- Iterate the DATABASE and call an iterator function for each **alive** unit, providing the DCSUnit and optional parameters.
--- @param #DATABASE self
--- @param #function IteratorFunction The function that will be called when there is an alive unit in the database. The function needs to accept a DCSUnit parameter.
--- @return #DATABASE self
-function DATABASE:ForEachDCSUnit( IteratorFunction, ... )
- self:F2( arg )
-
- self:ForEach( IteratorFunction, arg, self.DCSUnits )
-
- return self
-end
-
-
--- Iterate the DATABASE and call an iterator function for each **alive** UNIT, providing the UNIT and optional parameters.
-- @param #DATABASE self
-- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the database. The function needs to accept a UNIT parameter.
diff --git a/Moose Development/Moose/Escort.lua b/Moose Development/Moose/Escort.lua
index 355a576fb..2a543e7c5 100644
--- a/Moose Development/Moose/Escort.lua
+++ b/Moose Development/Moose/Escort.lua
@@ -99,23 +99,31 @@
-- * @{#ESCORT.MenuEvasion: Creates a menu structure to set the evasion techniques when the escort is under threat.
-- * @{#ESCORT.MenuResumeMission}: Creates a menu structure so that the escort can resume from a waypoint.
--
+--
+-- @usage
+-- -- Declare a new EscortPlanes object as follows:
+--
+-- -- First find the GROUP object and the CLIENT object.
+-- local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
+-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
+--
+-- -- Now use these 2 objects to construct the new EscortPlanes object.
+-- EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
+--
+--
+--
-- @module Escort
-- @author FlightControl
-
-
-
-
-
-
----
+--- ESCORT class
-- @type ESCORT
-- @extends Base#BASE
-- @field Client#CLIENT EscortClient
-- @field Group#GROUP EscortGroup
-- @field #string EscortName
-- @field #ESCORT.MODE EscortMode The mode the escort is in.
--- @field #number FollowScheduler The id of the _FollowScheduler function.
+-- @field Scheduler#SCHEDULER FollowScheduler The instance of the SCHEDULER class.
+-- @field #number FollowDistance The current follow distance.
-- @field #boolean ReportTargets If true, nearby targets are reported.
-- @Field DCSTypes#AI.Option.Air.val.ROE OptionROE Which ROE is set to the EscortGroup.
-- @field DCSTypes#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the EscortGroup.
@@ -125,7 +133,7 @@ ESCORT = {
EscortName = nil, -- The Escort Name
EscortClient = nil,
EscortGroup = nil,
- EscortMode = nil,
+ EscortMode = 1,
MODE = {
FOLLOW = 1,
MISSION = 2,
@@ -135,6 +143,7 @@ ESCORT = {
ReportTargets = true,
OptionROE = AI.Option.Air.val.ROE.OPEN_FIRE,
OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION,
+ SmokeDirectionVector = false,
TaskPoints = {}
}
@@ -156,6 +165,15 @@ ESCORT = {
-- @param Group#GROUP EscortGroup The group AI escorting the EscortClient.
-- @param #string EscortName Name of the escort.
-- @return #ESCORT self
+-- @usage
+-- -- Declare a new EscortPlanes object as follows:
+--
+-- -- First find the GROUP object and the CLIENT object.
+-- local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
+-- local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
+--
+-- -- Now use these 2 objects to construct the new EscortPlanes object.
+-- EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
local self = BASE:Inherit( self, BASE:New() )
self:F( { EscortClient, EscortGroup, EscortName } )
@@ -165,8 +183,6 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
self.EscortName = EscortName
self.EscortBriefing = EscortBriefing
- self:T( EscortGroup:GetClassNameAndID() )
-
-- Set EscortGroup known at EscortClient.
if not self.EscortClient._EscortGroups then
self.EscortClient._EscortGroups = {}
@@ -177,10 +193,8 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortGroup = self.EscortGroup
self.EscortClient._EscortGroups[EscortGroup:GetName()].EscortName = self.EscortName
self.EscortClient._EscortGroups[EscortGroup:GetName()].Targets = {}
- self.EscortMode = ESCORT.MODE.FOLLOW
end
-
self.EscortMenu = MENU_CLIENT:New( self.EscortClient, self.EscortName )
self.EscortGroup:WayPointInitialize(1)
@@ -194,9 +208,24 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing )
60, EscortClient
)
+ self.FollowDistance = 100
+ self.CT1 = 0
+ self.GT1 = 0
+ self.FollowScheduler = SCHEDULER:New( self, self._FollowScheduler, {}, 1, .5, .01 )
+ self.EscortMode = ESCORT.MODE.MISSION
+ self.FollowScheduler:Stop()
+
return self
end
+--- This function is for test, it will put on the frequency of the FollowScheduler a red smoke at the direction vector calculated for the escort to fly to.
+-- This allows to visualize where the escort is flying to.
+-- @param #ESCORT self
+-- @param #boolean SmokeDirection If true, then the direction vector will be smoked.
+function ESCORT:TestSmokeDirectionVector( SmokeDirection )
+ self.SmokeDirectionVector = ( SmokeDirection == true ) and true or false
+end
+
--- Defines the default menus
-- @param #ESCORT self
@@ -223,6 +252,7 @@ function ESCORT:Menus()
self:MenuEvasion()
self:MenuResumeMission()
+
return self
end
@@ -633,7 +663,7 @@ function ESCORT._HoldPosition( MenuParam )
local OrbitHeight = MenuParam.ParamHeight
local OrbitSeconds = MenuParam.ParamSeconds -- Not implemented yet
- routines.removeFunction( self.FollowScheduler )
+ self.FollowScheduler:Stop()
local PointFrom = {}
local GroupPoint = EscortGroup:GetUnit(1):GetPointVec3()
@@ -662,6 +692,7 @@ function ESCORT._HoldPosition( MenuParam )
EscortGroup:SetTask( EscortGroup:TaskRoute( Points ) )
EscortGroup:MessageToClient( "Orbiting at location.", 10, EscortClient )
+
end
--- @param #MENUPARAM MenuParam
@@ -684,9 +715,7 @@ end
function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
self:F( { EscortGroup, EscortClient, Distance } )
- if self.FollowScheduler then
- routines.removeFunction( self.FollowScheduler )
- end
+ self.FollowScheduler:Stop()
EscortGroup:OptionROEHoldFire()
EscortGroup:OptionROTPassiveDefense()
@@ -695,8 +724,8 @@ function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance )
self.CT1 = 0
self.GT1 = 0
- --self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, .5 )
- self.FollowScheduler = SCHEDULER:New( self, self._FollowScheduler, { Distance }, 1, .5, .1 )
+ self.FollowScheduler:Start()
+
EscortGroup:MessageToClient( "Rejoining and Following at " .. Distance .. "!", 30, EscortClient )
end
@@ -768,11 +797,7 @@ function ESCORT._ScanTargets( MenuParam )
local ScanDuration = MenuParam.ParamScanDuration
- if self.FollowScheduler then
- routines.removeFunction( self.FollowScheduler )
- end
-
- self:T( { "FollowScheduler after removefunction: ", self.FollowScheduler } )
+ self.FollowScheduler:Stop()
if EscortGroup:IsHelicopter() then
SCHEDULER:New( EscortGroup, EscortGroup.PushTask,
@@ -797,16 +822,16 @@ function ESCORT._ScanTargets( MenuParam )
EscortGroup:MessageToClient( "Scanning targets for " .. ScanDuration .. " seconds.", ScanDuration, EscortClient )
if self.EscortMode == ESCORT.MODE.FOLLOW then
- --self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + ScanDuration, 1 )
self.FollowScheduler:Start()
end
end
+--- @param Group#GROUP EscortGroup
function _Resume( EscortGroup )
env.info( '_Resume' )
- local Escort = EscortGroup.Escort -- #ESCORT
+ local Escort = EscortGroup:GetState( EscortGroup, "Escort" )
env.info( "EscortMode = " .. Escort.EscortMode )
if Escort.EscortMode == ESCORT.MODE.FOLLOW then
Escort:JoinUpAndFollow( EscortGroup, Escort.EscortClient, Escort.Distance )
@@ -819,19 +844,18 @@ function ESCORT._AttackTarget( MenuParam )
local self = MenuParam.ParamSelf
local EscortGroup = self.EscortGroup
+
local EscortClient = self.EscortClient
local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT
- if self.FollowScheduler then
- routines.removeFunction( self.FollowScheduler )
- end
+ self.FollowScheduler:Stop()
self:T( AttackUnit )
if EscortGroup:IsAir() then
EscortGroup:OptionROEOpenFire()
EscortGroup:OptionROTPassiveDefense()
- EscortGroup.Escort = self -- Need to do this trick to get the reference for the escort in the _Resume function.
+ EscortGroup:SetState( EscortGroup, "Escort", self )
-- routines.scheduleFunction(
-- EscortGroup.PushTask,
-- { EscortGroup,
@@ -846,7 +870,7 @@ function ESCORT._AttackTarget( MenuParam )
EscortGroup.PushTask,
{ EscortGroup:TaskCombo(
{ EscortGroup:TaskAttackUnit( AttackUnit ),
- EscortGroup:TaskFunction( 1, 2, "_Resume", {"''"} )
+ EscortGroup:TaskFunction( 1, 2, "_Resume", { "''" } )
}
)
}, 10
@@ -870,9 +894,9 @@ function ESCORT._AttackTarget( MenuParam )
}, 10
)
end
+
EscortGroup:MessageToClient( "Engaging Designated Unit!", 10, EscortClient )
-
end
--- @param #MENUPARAM MenuParam
@@ -884,10 +908,7 @@ function ESCORT._AssistTarget( MenuParam )
local EscortGroupAttack = MenuParam.ParamEscortGroup
local AttackUnit = MenuParam.ParamUnit -- Unit#UNIT
- if self.FollowScheduler then
- routines.removeFunction( self.FollowScheduler )
- end
-
+ self.FollowScheduler:Stop()
self:T( AttackUnit )
@@ -973,8 +994,7 @@ function ESCORT._ResumeMission( MenuParam )
local WayPoint = MenuParam.ParamWayPoint
- routines.removeFunction( self.FollowScheduler )
- self.FollowScheduler = nil
+ self.FollowScheduler:Stop()
local WayPoints = EscortGroup:GetTaskRoute()
self:T( WayPoint, WayPoints )
@@ -1005,16 +1025,21 @@ function ESCORT:RegisterRoute()
end
--- @param Escort#ESCORT self
-function ESCORT:_FollowScheduler( FollowDistance )
- self:F( { FollowDistance })
+function ESCORT:_FollowScheduler()
+ self:F( { self.FollowDistance } )
+ self:T( {self.EscortClient.UnitName, self.EscortGroup.GroupName } )
if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then
local ClientUnit = self.EscortClient:GetClientGroupUnit()
local GroupUnit = self.EscortGroup:GetUnit( 1 )
+ local FollowDistance = self.FollowDistance
+
+ self:T( {ClientUnit.UnitName, GroupUnit.UnitName } )
if self.CT1 == 0 and self.GT1 == 0 then
self.CV1 = ClientUnit:GetPointVec3()
+ self:T( { "self.CV1", self.CV1 } )
self.CT1 = timer.getTime()
self.GV1 = GroupUnit:GetPointVec3()
self.GT1 = timer.getTime()
@@ -1074,7 +1099,10 @@ function ESCORT:_FollowScheduler( FollowDistance )
-- Now we can calculate the group destination vector GDV.
local GDV = { x = DVu.x * CS * 8 + CVI.x, y = CVI.y, z = DVu.z * CS * 8 + CVI.z }
- --trigger.action.smoke( GDV, trigger.smokeColor.Red )
+ if self.SmokeDirectionVector == true then
+ trigger.action.smoke( GDV, trigger.smokeColor.Red )
+ end
+
self:T2( { "CV2:", CV2 } )
self:T2( { "CVI:", CVI } )
self:T2( { "GDV:", GDV } )
@@ -1092,11 +1120,12 @@ function ESCORT:_FollowScheduler( FollowDistance )
Speed = 0
end
- self:T( { "Client Speed, Escort Speed, Speed, FlyDistance, Time:", CS, GS, Speed, Distance, Time } )
+ self:T( { "Client Speed, Escort Speed, Speed, FollowDistance, Time:", CS, GS, Speed, FollowDistance, Time } )
-- Now route the escort to the desired point with the desired speed.
self.EscortGroup:TaskRouteToVec3( GDV, Speed / 3.6 ) -- DCS models speed in Mps (Miles per second)
end
+
return true
end
@@ -1278,6 +1307,7 @@ function ESCORT:_ReportTargetsScheduler()
MENU_CLIENT_COMMAND:New( self.EscortClient, "Waypoint " .. WayPointID .. " at " .. string.format( "%.2f", Distance ).. "km", self.EscortMenuResumeMission, ESCORT._ResumeMission, { ParamSelf = self, ParamWayPoint = WayPointID } )
end
end
+
return true
end
diff --git a/Moose Development/Moose/Event.lua b/Moose Development/Moose/Event.lua
index e58e8a2ec..959d9839a 100644
--- a/Moose Development/Moose/Event.lua
+++ b/Moose Development/Moose/Event.lua
@@ -494,11 +494,11 @@ function EVENT:onEvent( Event )
self:E( { _EVENTCODES[Event.id], Event } )
for ClassName, EventData in pairs( self.Events[Event.id] ) do
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
- self:T2( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } )
+ self:E( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } )
EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventSelf, Event )
else
if Event.IniDCSUnit and not EventData.IniUnit then
- self:T2( { "Calling event function for class ", ClassName } )
+ self:E( { "Calling event function for class ", ClassName } )
EventData.EventFunction( EventData.EventSelf, Event )
end
end
diff --git a/Moose Development/Moose/Group.lua b/Moose Development/Moose/Group.lua
index 4778c31c5..87cddd07e 100644
--- a/Moose Development/Moose/Group.lua
+++ b/Moose Development/Moose/Group.lua
@@ -185,6 +185,7 @@ function GROUP:Find( DCSGroup )
local GroupName = DCSGroup:getName() -- Group#GROUP
local GroupFound = _DATABASE:FindGroup( GroupName )
+ GroupFound:E( { GroupName, GroupFound:GetClassNameAndID() } )
return GroupFound
end
@@ -517,13 +518,14 @@ end
function GROUP:TaskFunction( WayPoint, WayPointIndex, FunctionString, FunctionArguments )
+ self:F2( { WayPoint, WayPointIndex, FunctionString, FunctionArguments } )
local DCSTask
local DCSScript = {}
DCSScript[#DCSScript+1] = "local MissionGroup = GROUP:Find( ... ) "
- if FunctionArguments.n > 0 then
+ if FunctionArguments and #FunctionArguments > 0 then
DCSScript[#DCSScript+1] = FunctionString .. "( MissionGroup, " .. table.concat( FunctionArguments, "," ) .. ")"
else
DCSScript[#DCSScript+1] = FunctionString .. "( MissionGroup )"
diff --git a/Moose Development/Moose/Scheduler.lua b/Moose Development/Moose/Scheduler.lua
index 652c74da9..82e78c5d3 100644
--- a/Moose Development/Moose/Scheduler.lua
+++ b/Moose Development/Moose/Scheduler.lua
@@ -46,13 +46,12 @@ function SCHEDULER:New( TimeEventObject, TimeEventFunction, TimeEventFunctionArg
self.TimeEventFunction = TimeEventFunction
self.TimeEventFunctionArguments = TimeEventFunctionArguments
self.StartSeconds = StartSeconds
+ self.Repeat = false
if RepeatSecondsInterval then
self.RepeatSecondsInterval = RepeatSecondsInterval
- self.Repeat = true
else
self.RepeatSecondsInterval = 0
- self.Repeat = false
end
if RandomizationFactor then
@@ -79,7 +78,10 @@ end
function SCHEDULER:Start()
self:F2( self.TimeEventObject )
- timer.scheduleFunction( self._Scheduler, self, timer.getTime() + self.StartSeconds + .01 )
+ if self.RepeatSecondsInterval ~= 0 then
+ self.Repeat = true
+ end
+ timer.scheduleFunction( self._Scheduler, self, timer.getTime() + self.StartSeconds + .01 )
return self
end
diff --git a/Moose Development/Moose/Test.lua b/Moose Development/Moose/Test.lua
deleted file mode 100644
index e69de29bb..000000000
diff --git a/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua b/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua
index 732b5b5ac..0af903907 100644
--- a/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua
+++ b/Moose Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua
@@ -19,6 +19,11 @@ do
:MenuReportTargets( 60, 20 )
:MenuResumeMission()
:MenuAssistedAttack()
+
+ local EscortGroupArtillery = SpawnEscortArtillery:ReSpawn(1)
+ local EscortArtillery = ESCORT
+ :New( Client, EscortGroupArtillery, "Escort Artillery" )
+ :Menus()
end
local function EventAlivePlane( Client )
@@ -52,6 +57,7 @@ do
SpawnEscortPlane = SPAWN:New( "Escort Plane" )
SpawnEscortGround = SPAWN:New( "Escort Ground" )
SpawnEscortShip = SPAWN:New( "Escort Ship" )
+ SpawnEscortArtillery = SPAWN:New( "Ground Attack Assistance" )
EscortClientHeli = CLIENT:FindByName( "Lead Helicopter", "Fly around and observe the behaviour of the escort helicopter" ):Alive( EventAliveHelicopter )
EscortClientPlane = CLIENT:FindByName( "Lead Plane", "Fly around and observe the behaviour of the escort airplane. Select Navigate->Joun-Up and airplane should follow you. Change speed and directions." )
diff --git a/Moose Training/Documentation/AIBalancer.html b/Moose Training/Documentation/AIBalancer.html
new file mode 100644
index 000000000..12bf002c5
--- /dev/null
+++ b/Moose Training/Documentation/AIBalancer.html
@@ -0,0 +1,253 @@
+
+
+
The AIBalancer#AIBALANCER class controls the dynamic spawning of AI GROUPS depending on a SETCLIENT.
+There will be as many AI GROUPS spawned as there at CLIENTS in SETCLIENT not spawned.
+
+
1.1) AIBALANCER construction method:
+
Create a new AIBALANCER object with the AIBALANCER.New method:
@@ -175,6 +176,20 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
+
+
Usage:
+
-- Declare a new EscortPlanes object as follows:
+
+-- First find the GROUP object and the CLIENT object.
+local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
+local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
+
+-- Now use these 2 objects to construct the new EscortPlanes object.
+EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
+
+
+
+
Global(s)
@@ -430,12 +445,18 @@ Note that this is really fantastic, as you now have the dynamic of taking contro
-- Declare a new EscortPlanes object as follows:
+
+-- First find the GROUP object and the CLIENT object.
+local EscortClient = CLIENT:FindByName( "Unit Name" ) -- The Unit Name is the name of the unit flagged with the skill Client in the mission editor.
+local EscortGroup = GROUP:FindByName( "Group Name" ) -- The Group Name is the name of the group that will escort the Escort Client.
+
+-- Now use these 2 objects to construct the new EscortPlanes object.
+EscortPlanes = ESCORT:New( EscortClient, EscortGroup, "Desert", "Welcome to the mission. You are escorted by a plane with code name 'Desert', which can be instructed through the F10 radio menu." )
Once the filters have been defined and the SETUNIT has been built, you can iterate the SETUNIT with the available iterator methods.
The iterator methods will walk the SETUNIT set, and call for each element within the set a function that you provide.
The following iterator methods are currently available within the SETUNIT:
SET_UNIT.ForEachUnit: Calls a function for each alive unit it finds within the SET_UNIT.
+
SET_GROUP.ForEachGroupCompletelyInZone: Iterate the SET_GROUP and call an iterator function for each alive GROUP presence completely in a Zone, providing the GROUP and optional parameters to the called function.
+
SET_GROUP.ForEachGroupNotInZone: Iterate the SET_GROUP and call an iterator function for each alive GROUP presence not in a Zone, providing the GROUP and optional parameters to the called function.
Planned iterators methods in development are (so these are not yet available):
SET_UNIT.ForEachUnitCompletelyInZone: Iterate and call an iterator function for each alive UNIT presence completely in a Zone, providing the UNIT and optional parameters to the called function.
+
SET_UNIT.ForEachUnitNotInZone: Iterate and call an iterator function for each alive UNIT presence not in a Zone, providing the UNIT and optional parameters to the called function.
Once the filters have been defined and the SETCLIENT has been built, you can iterate the SETCLIENT with the available iterator methods.
+The iterator methods will walk the SETCLIENT set, and call for each element within the set a function that you provide.
+The following iterator methods are currently available within the SETCLIENT:
+
+
+
SET_CLIENT.ForEachClient: Calls a function for each alive client it finds within the SET_CLIENT.
+
@@ -220,6 +281,12 @@ The following iterator methods are currently available within the SETUNIT:<
Iterate the SET_CLIENT and call an iterator function for each alive CLIENT presence completely in a Zone, providing the CLIENT and optional parameters to the called function.
Iterate the SET_CLIENT and call an iterator function for each alive CLIENT presence not in a Zone, providing the CLIENT and optional parameters to the called function.
Iterate the SET_UNIT and call an iterator function for each alive UNIT presence completely in a Zone, providing the UNIT and optional parameters to the called function.
Iterate the SET_UNIT and call an iterator function for each alive UNIT presence not in a Zone, providing the UNIT and optional parameters to the called function.
@@ -543,6 +746,12 @@ The following iterator methods are currently available within the SETUNIT:<
Interate the SET_CLIENT and call an interator function for each alive CLIENT, providing the CLIENT and optional parameters.
+
+
Parameters
+
+
+
+
#function IteratorFunction :
+The function that will be called when there is an alive CLIENT in the SET_CLIENT. The function needs to accept a CLIENT parameter.
Iterate the SET_CLIENT and call an iterator function for each alive CLIENT presence completely in a Zone, providing the CLIENT and optional parameters to the called function.
+
+
Parameters
+
+
+
+
Zone#ZONE ZoneObject :
+The Zone to be tested for.
+
+
+
+
+
#function IteratorFunction :
+The function that will be called when there is an alive CLIENT in the SET_CLIENT. The function needs to accept a CLIENT parameter.
Iterate the SET_CLIENT and call an iterator function for each alive CLIENT presence not in a Zone, providing the CLIENT and optional parameters to the called function.
+
+
Parameters
+
+
+
+
Zone#ZONE ZoneObject :
+The Zone to be tested for.
+
+
+
+
+
#function IteratorFunction :
+The function that will be called when there is an alive CLIENT in the SET_CLIENT. The function needs to accept a CLIENT parameter.
Iterate the SET_UNIT and call an iterator function for each alive UNIT presence completely in a Zone, providing the UNIT and optional parameters to the called function.
+
+
Parameters
+
+
+
+
Zone#ZONE ZoneObject :
+The Zone to be tested for.
+
+
+
+
+
#function IteratorFunction :
+The function that will be called when there is an alive UNIT in the SET_UNIT. The function needs to accept a UNIT parameter.
Iterate the SET_UNIT and call an iterator function for each alive UNIT presence not in a Zone, providing the UNIT and optional parameters to the called function.
+
+
Parameters
+
+
+
+
Zone#ZONE ZoneObject :
+The Zone to be tested for.
+
+
+
+
+
#function IteratorFunction :
+The function that will be called when there is an alive UNIT in the SET_UNIT. The function needs to accept a UNIT parameter.