mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Updated Mission, cleaned it up and removed stuff.
This commit is contained in:
parent
9fc3f7a601
commit
520ee6e459
@ -12,22 +12,6 @@ MISSION = {
|
||||
ClassName = "MISSION",
|
||||
Name = "",
|
||||
MissionStatus = "PENDING",
|
||||
_Clients = {},
|
||||
TaskMenus = {},
|
||||
TaskCategoryMenus = {},
|
||||
TaskTypeMenus = {},
|
||||
_ActiveTasks = {},
|
||||
GoalFunction = nil,
|
||||
MissionReportTrigger = 0,
|
||||
MissionProgressTrigger = 0,
|
||||
MissionReportShow = false,
|
||||
MissionReportFlash = false,
|
||||
MissionTimeInterval = 0,
|
||||
MissionCoalition = "",
|
||||
SUCCESS = 1,
|
||||
FAILED = 2,
|
||||
REPEAT = 3,
|
||||
_GoalTasks = {}
|
||||
}
|
||||
|
||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||
@ -234,6 +218,10 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
|
||||
self.MissionCoalition = MissionCoalition
|
||||
|
||||
self.Tasks = {}
|
||||
|
||||
-- Private implementations
|
||||
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
@ -524,76 +512,44 @@ function MISSION:GetNextTaskID( Task )
|
||||
return self.Tasks[TaskName].n
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- old stuff
|
||||
|
||||
--- Returns if a Mission has completed.
|
||||
-- @return bool
|
||||
--- Is the @{Mission} **Completed**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsCompleted()
|
||||
self:F()
|
||||
return self.MissionStatus == "ACCOMPLISHED"
|
||||
return self:Is( "Completed" )
|
||||
end
|
||||
|
||||
--- Set a Mission to completed.
|
||||
function MISSION:Completed()
|
||||
self:F()
|
||||
self.MissionStatus = "ACCOMPLISHED"
|
||||
self:StatusToClients()
|
||||
--- Is the @{Mission} **Idle**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsIdle()
|
||||
return self:Is( "Idle" )
|
||||
end
|
||||
|
||||
--- Returns if a Mission is ongoing.
|
||||
-- treturn bool
|
||||
--- Is the @{Mission} **Ongoing**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsOngoing()
|
||||
self:F()
|
||||
return self.MissionStatus == "ONGOING"
|
||||
return self:Is( "Ongoing" )
|
||||
end
|
||||
|
||||
--- Set a Mission to ongoing.
|
||||
function MISSION:Ongoing()
|
||||
self:F()
|
||||
self.MissionStatus = "ONGOING"
|
||||
--self:StatusToClients()
|
||||
--- Is the @{Mission} **Failed**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsFailed()
|
||||
return self:Is( "Failed" )
|
||||
end
|
||||
|
||||
--- Returns if a Mission is pending.
|
||||
-- treturn bool
|
||||
function MISSION:IsPending()
|
||||
self:F()
|
||||
return self.MissionStatus == "PENDING"
|
||||
end
|
||||
|
||||
--- Set a Mission to pending.
|
||||
function MISSION:Pending()
|
||||
self:F()
|
||||
self.MissionStatus = "PENDING"
|
||||
self:StatusToClients()
|
||||
end
|
||||
|
||||
--- Returns if a Mission has failed.
|
||||
-- treturn bool
|
||||
function MISSION:IsFailed()
|
||||
self:F()
|
||||
return self.MissionStatus == "FAILED"
|
||||
end
|
||||
|
||||
--- Set a Mission to failed.
|
||||
function MISSION:Failed()
|
||||
self:F()
|
||||
self.MissionStatus = "FAILED"
|
||||
self:StatusToClients()
|
||||
end
|
||||
|
||||
--- Send the status of the MISSION to all Clients.
|
||||
function MISSION:StatusToClients()
|
||||
self:F()
|
||||
if self.MissionReportFlash then
|
||||
for ClientID, Client in pairs( self._Clients ) do
|
||||
Client:Message( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. '! ( ' .. self.MissionPriority .. ' mission ) ', 10, "Mission Command: Mission Status")
|
||||
end
|
||||
end
|
||||
--- Is the @{Mission} **Hold**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsHold()
|
||||
return self:Is( "Hold" )
|
||||
end
|
||||
|
||||
--- Validates if the Mission has a Group
|
||||
-- @param #MISSION
|
||||
-- @return #boolean true if the Mission has a Group.
|
||||
function MISSION:HasGroup( TaskGroup )
|
||||
local Has = false
|
||||
|
||||
@ -686,107 +642,6 @@ function MISSION:ReportDetails()
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Report the status of all MISSIONs to all active Clients.
|
||||
function MISSION:ReportToAll()
|
||||
self:F()
|
||||
|
||||
local AlivePlayers = ''
|
||||
for ClientID, Client in pairs( self._Clients ) do
|
||||
if Client:GetDCSGroup() then
|
||||
if Client:GetClientGroupDCSUnit() then
|
||||
if Client:GetClientGroupDCSUnit():getLife() > 0.0 then
|
||||
if AlivePlayers == '' then
|
||||
AlivePlayers = ' Players: ' .. Client:GetClientGroupDCSUnit():getPlayerName()
|
||||
else
|
||||
AlivePlayers = AlivePlayers .. ' / ' .. Client:GetClientGroupDCSUnit():getPlayerName()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local Tasks = self:GetTasks()
|
||||
local TaskText = ""
|
||||
for TaskID, TaskData in pairs( Tasks ) do
|
||||
TaskText = TaskText .. " - Task " .. TaskID .. ": " .. TaskData.Name .. ": " .. TaskData:GetGoalProgress() .. "\n"
|
||||
end
|
||||
MESSAGE:New( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. ' ( ' .. self.MissionPriority .. ' mission )' .. AlivePlayers .. "\n" .. TaskText:gsub("\n$",""), 10, "Mission Command: Mission Report" ):ToAll()
|
||||
end
|
||||
|
||||
|
||||
--- Add a goal function to a MISSION. Goal functions are called when a @{TASK} within a mission has been completed.
|
||||
-- @param function GoalFunction is the function defined by the mission designer to evaluate whether a certain goal has been reached after a @{TASK} finishes within the @{MISSION}. A GoalFunction must accept 2 parameters: Mission, Client, which contains the current MISSION object and the current CLIENT object respectively.
|
||||
-- @usage
|
||||
-- PatriotActivation = {
|
||||
-- { "US SAM Patriot Zerti", false },
|
||||
-- { "US SAM Patriot Zegduleti", false },
|
||||
-- { "US SAM Patriot Gvleti", false }
|
||||
-- }
|
||||
--
|
||||
-- function DeployPatriotTroopsGoal( Mission, Client )
|
||||
--
|
||||
--
|
||||
-- -- Check if the cargo is all deployed for mission success.
|
||||
-- for CargoID, CargoData in pairs( Mission._Cargos ) do
|
||||
-- if Group.getByName( CargoData.CargoGroupName ) then
|
||||
-- CargoGroup = Group.getByName( CargoData.CargoGroupName )
|
||||
-- if CargoGroup then
|
||||
-- -- Check if the cargo is ready to activate
|
||||
-- CurrentLandingZoneID = routines.IsUnitInZones( CargoGroup:getUnits()[1], Mission:GetTask( 2 ).LandingZones ) -- The second task is the Deploytask to measure mission success upon
|
||||
-- if CurrentLandingZoneID then
|
||||
-- if PatriotActivation[CurrentLandingZoneID][2] == false then
|
||||
-- -- Now check if this is a new Mission Task to be completed...
|
||||
-- trigger.action.setGroupAIOn( Group.getByName( PatriotActivation[CurrentLandingZoneID][1] ) )
|
||||
-- PatriotActivation[CurrentLandingZoneID][2] = true
|
||||
-- MessageToBlue( "Mission Command: Message to all airborne units! The " .. PatriotActivation[CurrentLandingZoneID][1] .. " is armed. Our air defenses are now stronger.", 60, "BLUE/PatriotDefense" )
|
||||
-- MessageToRed( "Mission Command: Our satellite systems are detecting additional NATO air defenses. To all airborne units: Take care!!!", 60, "RED/PatriotDefense" )
|
||||
-- Mission:GetTask( 2 ):AddGoalCompletion( "Patriots activated", PatriotActivation[CurrentLandingZoneID][1], 1 ) -- Register Patriot activation as part of mission goal.
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Transport Troops', 'Operational', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.', 'NATO' )
|
||||
-- Mission:AddGoalFunction( DeployPatriotTroopsGoal )
|
||||
function MISSION:AddGoalFunction( GoalFunction )
|
||||
self:F()
|
||||
self.GoalFunction = GoalFunction
|
||||
end
|
||||
|
||||
--- Register a new @{CLIENT} to participate within the mission.
|
||||
-- @param CLIENT Client is the @{CLIENT} object. The object must have been instantiated with @{CLIENT:New}.
|
||||
-- @return CLIENT
|
||||
-- @usage
|
||||
-- Add a number of Client objects to the Mission.
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 1', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 3', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
function MISSION:AddClient( Client )
|
||||
self:F( { Client } )
|
||||
|
||||
local Valid = true
|
||||
|
||||
if Valid then
|
||||
self._Clients[Client.ClientName] = Client
|
||||
end
|
||||
|
||||
return Client
|
||||
end
|
||||
|
||||
--- Find a @{CLIENT} object within the @{MISSION} by its ClientName.
|
||||
-- @param CLIENT ClientName is a string defining the Client Group as defined within the ME.
|
||||
-- @return CLIENT
|
||||
-- @usage
|
||||
-- -- Seach for Client "Bomber" within the Mission.
|
||||
-- local BomberClient = Mission:FindClient( "Bomber" )
|
||||
function MISSION:FindClient( ClientName )
|
||||
self:F( { self._Clients[ClientName] } )
|
||||
return self._Clients[ClientName]
|
||||
end
|
||||
|
||||
|
||||
--- Get all the TASKs from the Mission. This function is useful in GoalFunctions.
|
||||
-- @return {TASK,...} Structure of TASKS with the @{TASK} number as the key.
|
||||
-- @usage
|
||||
@ -800,330 +655,3 @@ function MISSION:GetTasks()
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
_TransportExecuteStage: Defines the different stages of Transport unload/load execution. This table is internal and is used to control the validity of Transport load/unload timing.
|
||||
|
||||
- _TransportExecuteStage.EXECUTING
|
||||
- _TransportExecuteStage.SUCCESS
|
||||
- _TransportExecuteStage.FAILED
|
||||
|
||||
--]]
|
||||
_TransportExecuteStage = {
|
||||
NONE = 0,
|
||||
EXECUTING = 1,
|
||||
SUCCESS = 2,
|
||||
FAILED = 3
|
||||
}
|
||||
|
||||
|
||||
--- The MISSIONSCHEDULER is an OBJECT and is the main scheduler of ALL active MISSIONs registered within this scheduler. It's workings are considered internal and is automatically created when the Mission.lua file is included.
|
||||
-- @type MISSIONSCHEDULER
|
||||
-- @field #MISSIONSCHEDULER.MISSIONS Missions
|
||||
MISSIONSCHEDULER = {
|
||||
Missions = {},
|
||||
MissionCount = 0,
|
||||
TimeIntervalCount = 0,
|
||||
TimeIntervalShow = 150,
|
||||
TimeSeconds = 14400,
|
||||
TimeShow = 5
|
||||
}
|
||||
|
||||
--- @type MISSIONSCHEDULER.MISSIONS
|
||||
-- @list <#MISSION> Mission
|
||||
|
||||
--- This is the main MISSIONSCHEDULER Scheduler function. It is considered internal and is automatically created when the Mission.lua file is included.
|
||||
function MISSIONSCHEDULER.Scheduler()
|
||||
|
||||
|
||||
-- loop through the missions in the TransportTasks
|
||||
for MissionName, MissionData in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
|
||||
local Mission = MissionData -- #MISSION
|
||||
|
||||
if not Mission:IsCompleted() then
|
||||
|
||||
-- This flag will monitor if for this mission, there are clients alive. If this flag is still false at the end of the loop, the mission status will be set to Pending (if not Failed or Completed).
|
||||
local ClientsAlive = false
|
||||
|
||||
for ClientID, ClientData in pairs( Mission._Clients ) do
|
||||
|
||||
local Client = ClientData -- Wrapper.Client#CLIENT
|
||||
|
||||
if Client:IsAlive() then
|
||||
|
||||
-- There is at least one Client that is alive... So the Mission status is set to Ongoing.
|
||||
ClientsAlive = true
|
||||
|
||||
-- If this Client was not registered as Alive before:
|
||||
-- 1. We register the Client as Alive.
|
||||
-- 2. We initialize the Client Tasks and make a link to the original Mission Task.
|
||||
-- 3. We initialize the Cargos.
|
||||
-- 4. We flag the Mission as Ongoing.
|
||||
if not Client.ClientAlive then
|
||||
Client.ClientAlive = true
|
||||
Client.ClientBriefingShown = false
|
||||
for TaskNumber, Task in pairs( Mission._Tasks ) do
|
||||
-- Note that this a deepCopy. Each client must have their own Tasks with own Stages!!!
|
||||
Client._Tasks[TaskNumber] = routines.utils.deepCopy( Mission._Tasks[TaskNumber] )
|
||||
-- Each MissionTask must point to the original Mission.
|
||||
Client._Tasks[TaskNumber].MissionTask = Mission._Tasks[TaskNumber]
|
||||
Client._Tasks[TaskNumber].Cargos = Mission._Tasks[TaskNumber].Cargos
|
||||
Client._Tasks[TaskNumber].LandingZones = Mission._Tasks[TaskNumber].LandingZones
|
||||
end
|
||||
|
||||
Mission:Ongoing()
|
||||
end
|
||||
|
||||
|
||||
-- For each Client, check for each Task the state and evolve the mission.
|
||||
-- This flag will indicate if the Task of the Client is Complete.
|
||||
local TaskComplete = false
|
||||
|
||||
for TaskNumber, Task in pairs( Client._Tasks ) do
|
||||
|
||||
if not Task.Stage then
|
||||
Task:SetStage( 1 )
|
||||
end
|
||||
|
||||
|
||||
local TransportTime = timer.getTime()
|
||||
|
||||
if not Task:IsDone() then
|
||||
|
||||
if Task:Goal() then
|
||||
Task:ShowGoalProgress( Mission, Client )
|
||||
end
|
||||
|
||||
--env.info( 'Scheduler: Mission = ' .. Mission.Name .. ' / Client = ' .. Client.ClientName .. ' / Task = ' .. Task.Name .. ' / Stage = ' .. Task.ActiveStage .. ' - ' .. Task.Stage.Name .. ' - ' .. Task.Stage.StageType )
|
||||
|
||||
-- Action
|
||||
if Task:StageExecute() then
|
||||
Task.Stage:Execute( Mission, Client, Task )
|
||||
end
|
||||
|
||||
-- Wait until execution is finished
|
||||
if Task.ExecuteStage == _TransportExecuteStage.EXECUTING then
|
||||
Task.Stage:Executing( Mission, Client, Task )
|
||||
end
|
||||
|
||||
-- Validate completion or reverse to earlier stage
|
||||
if Task.Time + Task.Stage.WaitTime <= TransportTime then
|
||||
Task:SetStage( Task.Stage:Validate( Mission, Client, Task ) )
|
||||
end
|
||||
|
||||
if Task:IsDone() then
|
||||
--env.info( 'Scheduler: Mission '.. Mission.Name .. ' Task ' .. Task.Name .. ' Stage ' .. Task.Stage.Name .. ' done. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
||||
TaskComplete = true -- when a task is not yet completed, a mission cannot be completed
|
||||
|
||||
else
|
||||
-- break only if this task is not yet done, so that future task are not yet activated.
|
||||
TaskComplete = false -- when a task is not yet completed, a mission cannot be completed
|
||||
--env.info( 'Scheduler: Mission "'.. Mission.Name .. '" Task "' .. Task.Name .. '" Stage "' .. Task.Stage.Name .. '" break. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
||||
break
|
||||
end
|
||||
|
||||
if TaskComplete then
|
||||
|
||||
if Mission.GoalFunction ~= nil then
|
||||
Mission.GoalFunction( Mission, Client )
|
||||
end
|
||||
if MISSIONSCHEDULER.Scoring then
|
||||
MISSIONSCHEDULER.Scoring:_AddMissionTaskScore( Client:GetClientGroupDCSUnit(), Mission.Name, 25 )
|
||||
end
|
||||
|
||||
-- if not Mission:IsCompleted() then
|
||||
-- end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local MissionComplete = true
|
||||
for TaskNumber, Task in pairs( Mission._Tasks ) do
|
||||
if Task:Goal() then
|
||||
-- Task:ShowGoalProgress( Mission, Client )
|
||||
if Task:IsGoalReached() then
|
||||
else
|
||||
MissionComplete = false
|
||||
end
|
||||
else
|
||||
MissionComplete = false -- If there is no goal, the mission should never be ended. The goal status will be set somewhere else.
|
||||
end
|
||||
end
|
||||
|
||||
if MissionComplete then
|
||||
Mission:Completed()
|
||||
if MISSIONSCHEDULER.Scoring then
|
||||
MISSIONSCHEDULER.Scoring:_AddMissionScore( Mission.Name, 100 )
|
||||
end
|
||||
else
|
||||
if TaskComplete then
|
||||
-- Reset for new tasking of active client
|
||||
Client.ClientAlive = false -- Reset the client tasks.
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
if Client.ClientAlive then
|
||||
env.info( 'Scheduler: Client "' .. Client.ClientName .. '" is inactive.' )
|
||||
Client.ClientAlive = false
|
||||
|
||||
-- This is tricky. If we sanitize Client._Tasks before sanitizing Client._Tasks[TaskNumber].MissionTask, then the original MissionTask will be sanitized, and will be lost within the garbage collector.
|
||||
-- So first sanitize Client._Tasks[TaskNumber].MissionTask, after that, sanitize only the whole _Tasks structure...
|
||||
--Client._Tasks[TaskNumber].MissionTask = nil
|
||||
--Client._Tasks = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If all Clients of this Mission are not activated, then the Mission status needs to be put back into Pending status.
|
||||
-- But only if the Mission was Ongoing. In case the Mission is Completed or Failed, the Mission status may not be changed. In these cases, this will be the last run of this Mission in the Scheduler.
|
||||
if ClientsAlive == false then
|
||||
if Mission:IsOngoing() then
|
||||
-- Mission status back to pending...
|
||||
Mission:Pending()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Mission:StatusToClients()
|
||||
|
||||
if Mission:ReportTrigger() then
|
||||
Mission:ReportToAll()
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Start the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.Start()
|
||||
if MISSIONSCHEDULER ~= nil then
|
||||
--MISSIONSCHEDULER.SchedulerId = routines.scheduleFunction( MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
MISSIONSCHEDULER.SchedulerId = SCHEDULER:New( nil, MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Stop the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.Stop()
|
||||
if MISSIONSCHEDULER.SchedulerId then
|
||||
routines.removeFunction(MISSIONSCHEDULER.SchedulerId)
|
||||
MISSIONSCHEDULER.SchedulerId = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||
-- @param Mission is the MISSION object instantiated by @{MISSION:New}.
|
||||
-- @return MISSION
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
function MISSIONSCHEDULER.AddMission( Mission )
|
||||
MISSIONSCHEDULER.Missions[Mission.Name] = Mission
|
||||
MISSIONSCHEDULER.MissionCount = MISSIONSCHEDULER.MissionCount + 1
|
||||
-- Add an overall AI Client for the AI tasks... This AI Client will facilitate the Events in the background for each Task.
|
||||
--MissionAdd:AddClient( CLIENT:Register( 'AI' ) )
|
||||
|
||||
return Mission
|
||||
end
|
||||
|
||||
--- Remove a MISSION from the MISSIONSCHEDULER.
|
||||
-- @param MissionName is the name of the MISSION given at declaration using @{AddMission}.
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
--
|
||||
-- -- Now remove the Mission.
|
||||
-- MISSIONSCHEDULER:RemoveMission( 'Russia Transport Troops SA-6' )
|
||||
function MISSIONSCHEDULER.RemoveMission( MissionName )
|
||||
MISSIONSCHEDULER.Missions[MissionName] = nil
|
||||
MISSIONSCHEDULER.MissionCount = MISSIONSCHEDULER.MissionCount - 1
|
||||
end
|
||||
|
||||
--- Find a MISSION within the MISSIONSCHEDULER.
|
||||
-- @param MissionName is the name of the MISSION given at declaration using @{AddMission}.
|
||||
-- @return MISSION
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
--
|
||||
-- -- Now find the Mission.
|
||||
-- MissionFind = MISSIONSCHEDULER:FindMission( 'Russia Transport Troops SA-6' )
|
||||
function MISSIONSCHEDULER.FindMission( MissionName )
|
||||
return MISSIONSCHEDULER.Missions[MissionName]
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsShow( )
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = true
|
||||
Mission.MissionReportFlash = false
|
||||
end
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsFlash( TimeInterval )
|
||||
local Count = 0
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = false
|
||||
Mission.MissionReportFlash = true
|
||||
Mission.MissionReportTrigger = timer.getTime() + Count * TimeInterval
|
||||
Mission.MissionTimeInterval = MISSIONSCHEDULER.MissionCount * TimeInterval
|
||||
env.info( "TimeInterval = " .. Mission.MissionTimeInterval )
|
||||
Count = Count + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsHide( Prm )
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = false
|
||||
Mission.MissionReportFlash = false
|
||||
end
|
||||
end
|
||||
|
||||
--- Enables a MENU option in the communications menu under F10 to control the status of the active missions.
|
||||
-- This function should be called only once when starting the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.ReportMenu()
|
||||
local ReportMenu = SUBMENU:New( 'Status' )
|
||||
local ReportMenuShow = COMMANDMENU:New( 'Show Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsShow, 0 )
|
||||
local ReportMenuFlash = COMMANDMENU:New('Flash Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsFlash, 120 )
|
||||
local ReportMenuHide = COMMANDMENU:New( 'Hide Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsHide, 0 )
|
||||
end
|
||||
|
||||
--- Show the remaining mission time.
|
||||
function MISSIONSCHEDULER:TimeShow()
|
||||
self.TimeIntervalCount = self.TimeIntervalCount + 1
|
||||
if self.TimeIntervalCount >= self.TimeTriggerShow then
|
||||
local TimeMsg = string.format("%00d", ( self.TimeSeconds / 60 ) - ( timer.getTime() / 60 )) .. ' minutes left until mission reload.'
|
||||
MESSAGE:New( TimeMsg, self.TimeShow, "Mission time" ):ToAll()
|
||||
self.TimeIntervalCount = 0
|
||||
end
|
||||
end
|
||||
|
||||
function MISSIONSCHEDULER:Time( TimeSeconds, TimeIntervalShow, TimeShow )
|
||||
|
||||
self.TimeIntervalCount = 0
|
||||
self.TimeSeconds = TimeSeconds
|
||||
self.TimeIntervalShow = TimeIntervalShow
|
||||
self.TimeShow = TimeShow
|
||||
end
|
||||
|
||||
--- Adds a mission scoring to the game.
|
||||
function MISSIONSCHEDULER:Scoring( Scoring )
|
||||
|
||||
self.Scoring = Scoring
|
||||
end
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20170315_1007' )
|
||||
env.info( 'Moose Generation Timestamp: 20170315_1149' )
|
||||
local base = _G
|
||||
|
||||
Include = {}
|
||||
@ -32319,22 +32319,6 @@ MISSION = {
|
||||
ClassName = "MISSION",
|
||||
Name = "",
|
||||
MissionStatus = "PENDING",
|
||||
_Clients = {},
|
||||
TaskMenus = {},
|
||||
TaskCategoryMenus = {},
|
||||
TaskTypeMenus = {},
|
||||
_ActiveTasks = {},
|
||||
GoalFunction = nil,
|
||||
MissionReportTrigger = 0,
|
||||
MissionProgressTrigger = 0,
|
||||
MissionReportShow = false,
|
||||
MissionReportFlash = false,
|
||||
MissionTimeInterval = 0,
|
||||
MissionCoalition = "",
|
||||
SUCCESS = 1,
|
||||
FAILED = 2,
|
||||
REPEAT = 3,
|
||||
_GoalTasks = {}
|
||||
}
|
||||
|
||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||
@ -32541,6 +32525,10 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
|
||||
self.MissionCoalition = MissionCoalition
|
||||
|
||||
self.Tasks = {}
|
||||
|
||||
-- Private implementations
|
||||
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
@ -32831,76 +32819,44 @@ function MISSION:GetNextTaskID( Task )
|
||||
return self.Tasks[TaskName].n
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- old stuff
|
||||
|
||||
--- Returns if a Mission has completed.
|
||||
-- @return bool
|
||||
--- Is the @{Mission} **Completed**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsCompleted()
|
||||
self:F()
|
||||
return self.MissionStatus == "ACCOMPLISHED"
|
||||
return self:Is( "Completed" )
|
||||
end
|
||||
|
||||
--- Set a Mission to completed.
|
||||
function MISSION:Completed()
|
||||
self:F()
|
||||
self.MissionStatus = "ACCOMPLISHED"
|
||||
self:StatusToClients()
|
||||
--- Is the @{Mission} **Idle**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsIdle()
|
||||
return self:Is( "Idle" )
|
||||
end
|
||||
|
||||
--- Returns if a Mission is ongoing.
|
||||
-- treturn bool
|
||||
--- Is the @{Mission} **Ongoing**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsOngoing()
|
||||
self:F()
|
||||
return self.MissionStatus == "ONGOING"
|
||||
return self:Is( "Ongoing" )
|
||||
end
|
||||
|
||||
--- Set a Mission to ongoing.
|
||||
function MISSION:Ongoing()
|
||||
self:F()
|
||||
self.MissionStatus = "ONGOING"
|
||||
--self:StatusToClients()
|
||||
--- Is the @{Mission} **Failed**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsFailed()
|
||||
return self:Is( "Failed" )
|
||||
end
|
||||
|
||||
--- Returns if a Mission is pending.
|
||||
-- treturn bool
|
||||
function MISSION:IsPending()
|
||||
self:F()
|
||||
return self.MissionStatus == "PENDING"
|
||||
end
|
||||
|
||||
--- Set a Mission to pending.
|
||||
function MISSION:Pending()
|
||||
self:F()
|
||||
self.MissionStatus = "PENDING"
|
||||
self:StatusToClients()
|
||||
end
|
||||
|
||||
--- Returns if a Mission has failed.
|
||||
-- treturn bool
|
||||
function MISSION:IsFailed()
|
||||
self:F()
|
||||
return self.MissionStatus == "FAILED"
|
||||
end
|
||||
|
||||
--- Set a Mission to failed.
|
||||
function MISSION:Failed()
|
||||
self:F()
|
||||
self.MissionStatus = "FAILED"
|
||||
self:StatusToClients()
|
||||
end
|
||||
|
||||
--- Send the status of the MISSION to all Clients.
|
||||
function MISSION:StatusToClients()
|
||||
self:F()
|
||||
if self.MissionReportFlash then
|
||||
for ClientID, Client in pairs( self._Clients ) do
|
||||
Client:Message( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. '! ( ' .. self.MissionPriority .. ' mission ) ', 10, "Mission Command: Mission Status")
|
||||
end
|
||||
end
|
||||
--- Is the @{Mission} **Hold**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsHold()
|
||||
return self:Is( "Hold" )
|
||||
end
|
||||
|
||||
--- Validates if the Mission has a Group
|
||||
-- @param #MISSION
|
||||
-- @return #boolean true if the Mission has a Group.
|
||||
function MISSION:HasGroup( TaskGroup )
|
||||
local Has = false
|
||||
|
||||
@ -32993,107 +32949,6 @@ function MISSION:ReportDetails()
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Report the status of all MISSIONs to all active Clients.
|
||||
function MISSION:ReportToAll()
|
||||
self:F()
|
||||
|
||||
local AlivePlayers = ''
|
||||
for ClientID, Client in pairs( self._Clients ) do
|
||||
if Client:GetDCSGroup() then
|
||||
if Client:GetClientGroupDCSUnit() then
|
||||
if Client:GetClientGroupDCSUnit():getLife() > 0.0 then
|
||||
if AlivePlayers == '' then
|
||||
AlivePlayers = ' Players: ' .. Client:GetClientGroupDCSUnit():getPlayerName()
|
||||
else
|
||||
AlivePlayers = AlivePlayers .. ' / ' .. Client:GetClientGroupDCSUnit():getPlayerName()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local Tasks = self:GetTasks()
|
||||
local TaskText = ""
|
||||
for TaskID, TaskData in pairs( Tasks ) do
|
||||
TaskText = TaskText .. " - Task " .. TaskID .. ": " .. TaskData.Name .. ": " .. TaskData:GetGoalProgress() .. "\n"
|
||||
end
|
||||
MESSAGE:New( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. ' ( ' .. self.MissionPriority .. ' mission )' .. AlivePlayers .. "\n" .. TaskText:gsub("\n$",""), 10, "Mission Command: Mission Report" ):ToAll()
|
||||
end
|
||||
|
||||
|
||||
--- Add a goal function to a MISSION. Goal functions are called when a @{TASK} within a mission has been completed.
|
||||
-- @param function GoalFunction is the function defined by the mission designer to evaluate whether a certain goal has been reached after a @{TASK} finishes within the @{MISSION}. A GoalFunction must accept 2 parameters: Mission, Client, which contains the current MISSION object and the current CLIENT object respectively.
|
||||
-- @usage
|
||||
-- PatriotActivation = {
|
||||
-- { "US SAM Patriot Zerti", false },
|
||||
-- { "US SAM Patriot Zegduleti", false },
|
||||
-- { "US SAM Patriot Gvleti", false }
|
||||
-- }
|
||||
--
|
||||
-- function DeployPatriotTroopsGoal( Mission, Client )
|
||||
--
|
||||
--
|
||||
-- -- Check if the cargo is all deployed for mission success.
|
||||
-- for CargoID, CargoData in pairs( Mission._Cargos ) do
|
||||
-- if Group.getByName( CargoData.CargoGroupName ) then
|
||||
-- CargoGroup = Group.getByName( CargoData.CargoGroupName )
|
||||
-- if CargoGroup then
|
||||
-- -- Check if the cargo is ready to activate
|
||||
-- CurrentLandingZoneID = routines.IsUnitInZones( CargoGroup:getUnits()[1], Mission:GetTask( 2 ).LandingZones ) -- The second task is the Deploytask to measure mission success upon
|
||||
-- if CurrentLandingZoneID then
|
||||
-- if PatriotActivation[CurrentLandingZoneID][2] == false then
|
||||
-- -- Now check if this is a new Mission Task to be completed...
|
||||
-- trigger.action.setGroupAIOn( Group.getByName( PatriotActivation[CurrentLandingZoneID][1] ) )
|
||||
-- PatriotActivation[CurrentLandingZoneID][2] = true
|
||||
-- MessageToBlue( "Mission Command: Message to all airborne units! The " .. PatriotActivation[CurrentLandingZoneID][1] .. " is armed. Our air defenses are now stronger.", 60, "BLUE/PatriotDefense" )
|
||||
-- MessageToRed( "Mission Command: Our satellite systems are detecting additional NATO air defenses. To all airborne units: Take care!!!", 60, "RED/PatriotDefense" )
|
||||
-- Mission:GetTask( 2 ):AddGoalCompletion( "Patriots activated", PatriotActivation[CurrentLandingZoneID][1], 1 ) -- Register Patriot activation as part of mission goal.
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Transport Troops', 'Operational', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.', 'NATO' )
|
||||
-- Mission:AddGoalFunction( DeployPatriotTroopsGoal )
|
||||
function MISSION:AddGoalFunction( GoalFunction )
|
||||
self:F()
|
||||
self.GoalFunction = GoalFunction
|
||||
end
|
||||
|
||||
--- Register a new @{CLIENT} to participate within the mission.
|
||||
-- @param CLIENT Client is the @{CLIENT} object. The object must have been instantiated with @{CLIENT:New}.
|
||||
-- @return CLIENT
|
||||
-- @usage
|
||||
-- Add a number of Client objects to the Mission.
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 1', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 3', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
function MISSION:AddClient( Client )
|
||||
self:F( { Client } )
|
||||
|
||||
local Valid = true
|
||||
|
||||
if Valid then
|
||||
self._Clients[Client.ClientName] = Client
|
||||
end
|
||||
|
||||
return Client
|
||||
end
|
||||
|
||||
--- Find a @{CLIENT} object within the @{MISSION} by its ClientName.
|
||||
-- @param CLIENT ClientName is a string defining the Client Group as defined within the ME.
|
||||
-- @return CLIENT
|
||||
-- @usage
|
||||
-- -- Seach for Client "Bomber" within the Mission.
|
||||
-- local BomberClient = Mission:FindClient( "Bomber" )
|
||||
function MISSION:FindClient( ClientName )
|
||||
self:F( { self._Clients[ClientName] } )
|
||||
return self._Clients[ClientName]
|
||||
end
|
||||
|
||||
|
||||
--- Get all the TASKs from the Mission. This function is useful in GoalFunctions.
|
||||
-- @return {TASK,...} Structure of TASKS with the @{TASK} number as the key.
|
||||
-- @usage
|
||||
@ -33107,333 +32962,6 @@ function MISSION:GetTasks()
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
_TransportExecuteStage: Defines the different stages of Transport unload/load execution. This table is internal and is used to control the validity of Transport load/unload timing.
|
||||
|
||||
- _TransportExecuteStage.EXECUTING
|
||||
- _TransportExecuteStage.SUCCESS
|
||||
- _TransportExecuteStage.FAILED
|
||||
|
||||
--]]
|
||||
_TransportExecuteStage = {
|
||||
NONE = 0,
|
||||
EXECUTING = 1,
|
||||
SUCCESS = 2,
|
||||
FAILED = 3
|
||||
}
|
||||
|
||||
|
||||
--- The MISSIONSCHEDULER is an OBJECT and is the main scheduler of ALL active MISSIONs registered within this scheduler. It's workings are considered internal and is automatically created when the Mission.lua file is included.
|
||||
-- @type MISSIONSCHEDULER
|
||||
-- @field #MISSIONSCHEDULER.MISSIONS Missions
|
||||
MISSIONSCHEDULER = {
|
||||
Missions = {},
|
||||
MissionCount = 0,
|
||||
TimeIntervalCount = 0,
|
||||
TimeIntervalShow = 150,
|
||||
TimeSeconds = 14400,
|
||||
TimeShow = 5
|
||||
}
|
||||
|
||||
--- @type MISSIONSCHEDULER.MISSIONS
|
||||
-- @list <#MISSION> Mission
|
||||
|
||||
--- This is the main MISSIONSCHEDULER Scheduler function. It is considered internal and is automatically created when the Mission.lua file is included.
|
||||
function MISSIONSCHEDULER.Scheduler()
|
||||
|
||||
|
||||
-- loop through the missions in the TransportTasks
|
||||
for MissionName, MissionData in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
|
||||
local Mission = MissionData -- #MISSION
|
||||
|
||||
if not Mission:IsCompleted() then
|
||||
|
||||
-- This flag will monitor if for this mission, there are clients alive. If this flag is still false at the end of the loop, the mission status will be set to Pending (if not Failed or Completed).
|
||||
local ClientsAlive = false
|
||||
|
||||
for ClientID, ClientData in pairs( Mission._Clients ) do
|
||||
|
||||
local Client = ClientData -- Wrapper.Client#CLIENT
|
||||
|
||||
if Client:IsAlive() then
|
||||
|
||||
-- There is at least one Client that is alive... So the Mission status is set to Ongoing.
|
||||
ClientsAlive = true
|
||||
|
||||
-- If this Client was not registered as Alive before:
|
||||
-- 1. We register the Client as Alive.
|
||||
-- 2. We initialize the Client Tasks and make a link to the original Mission Task.
|
||||
-- 3. We initialize the Cargos.
|
||||
-- 4. We flag the Mission as Ongoing.
|
||||
if not Client.ClientAlive then
|
||||
Client.ClientAlive = true
|
||||
Client.ClientBriefingShown = false
|
||||
for TaskNumber, Task in pairs( Mission._Tasks ) do
|
||||
-- Note that this a deepCopy. Each client must have their own Tasks with own Stages!!!
|
||||
Client._Tasks[TaskNumber] = routines.utils.deepCopy( Mission._Tasks[TaskNumber] )
|
||||
-- Each MissionTask must point to the original Mission.
|
||||
Client._Tasks[TaskNumber].MissionTask = Mission._Tasks[TaskNumber]
|
||||
Client._Tasks[TaskNumber].Cargos = Mission._Tasks[TaskNumber].Cargos
|
||||
Client._Tasks[TaskNumber].LandingZones = Mission._Tasks[TaskNumber].LandingZones
|
||||
end
|
||||
|
||||
Mission:Ongoing()
|
||||
end
|
||||
|
||||
|
||||
-- For each Client, check for each Task the state and evolve the mission.
|
||||
-- This flag will indicate if the Task of the Client is Complete.
|
||||
local TaskComplete = false
|
||||
|
||||
for TaskNumber, Task in pairs( Client._Tasks ) do
|
||||
|
||||
if not Task.Stage then
|
||||
Task:SetStage( 1 )
|
||||
end
|
||||
|
||||
|
||||
local TransportTime = timer.getTime()
|
||||
|
||||
if not Task:IsDone() then
|
||||
|
||||
if Task:Goal() then
|
||||
Task:ShowGoalProgress( Mission, Client )
|
||||
end
|
||||
|
||||
--env.info( 'Scheduler: Mission = ' .. Mission.Name .. ' / Client = ' .. Client.ClientName .. ' / Task = ' .. Task.Name .. ' / Stage = ' .. Task.ActiveStage .. ' - ' .. Task.Stage.Name .. ' - ' .. Task.Stage.StageType )
|
||||
|
||||
-- Action
|
||||
if Task:StageExecute() then
|
||||
Task.Stage:Execute( Mission, Client, Task )
|
||||
end
|
||||
|
||||
-- Wait until execution is finished
|
||||
if Task.ExecuteStage == _TransportExecuteStage.EXECUTING then
|
||||
Task.Stage:Executing( Mission, Client, Task )
|
||||
end
|
||||
|
||||
-- Validate completion or reverse to earlier stage
|
||||
if Task.Time + Task.Stage.WaitTime <= TransportTime then
|
||||
Task:SetStage( Task.Stage:Validate( Mission, Client, Task ) )
|
||||
end
|
||||
|
||||
if Task:IsDone() then
|
||||
--env.info( 'Scheduler: Mission '.. Mission.Name .. ' Task ' .. Task.Name .. ' Stage ' .. Task.Stage.Name .. ' done. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
||||
TaskComplete = true -- when a task is not yet completed, a mission cannot be completed
|
||||
|
||||
else
|
||||
-- break only if this task is not yet done, so that future task are not yet activated.
|
||||
TaskComplete = false -- when a task is not yet completed, a mission cannot be completed
|
||||
--env.info( 'Scheduler: Mission "'.. Mission.Name .. '" Task "' .. Task.Name .. '" Stage "' .. Task.Stage.Name .. '" break. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
||||
break
|
||||
end
|
||||
|
||||
if TaskComplete then
|
||||
|
||||
if Mission.GoalFunction ~= nil then
|
||||
Mission.GoalFunction( Mission, Client )
|
||||
end
|
||||
if MISSIONSCHEDULER.Scoring then
|
||||
MISSIONSCHEDULER.Scoring:_AddMissionTaskScore( Client:GetClientGroupDCSUnit(), Mission.Name, 25 )
|
||||
end
|
||||
|
||||
-- if not Mission:IsCompleted() then
|
||||
-- end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local MissionComplete = true
|
||||
for TaskNumber, Task in pairs( Mission._Tasks ) do
|
||||
if Task:Goal() then
|
||||
-- Task:ShowGoalProgress( Mission, Client )
|
||||
if Task:IsGoalReached() then
|
||||
else
|
||||
MissionComplete = false
|
||||
end
|
||||
else
|
||||
MissionComplete = false -- If there is no goal, the mission should never be ended. The goal status will be set somewhere else.
|
||||
end
|
||||
end
|
||||
|
||||
if MissionComplete then
|
||||
Mission:Completed()
|
||||
if MISSIONSCHEDULER.Scoring then
|
||||
MISSIONSCHEDULER.Scoring:_AddMissionScore( Mission.Name, 100 )
|
||||
end
|
||||
else
|
||||
if TaskComplete then
|
||||
-- Reset for new tasking of active client
|
||||
Client.ClientAlive = false -- Reset the client tasks.
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
if Client.ClientAlive then
|
||||
env.info( 'Scheduler: Client "' .. Client.ClientName .. '" is inactive.' )
|
||||
Client.ClientAlive = false
|
||||
|
||||
-- This is tricky. If we sanitize Client._Tasks before sanitizing Client._Tasks[TaskNumber].MissionTask, then the original MissionTask will be sanitized, and will be lost within the garbage collector.
|
||||
-- So first sanitize Client._Tasks[TaskNumber].MissionTask, after that, sanitize only the whole _Tasks structure...
|
||||
--Client._Tasks[TaskNumber].MissionTask = nil
|
||||
--Client._Tasks = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If all Clients of this Mission are not activated, then the Mission status needs to be put back into Pending status.
|
||||
-- But only if the Mission was Ongoing. In case the Mission is Completed or Failed, the Mission status may not be changed. In these cases, this will be the last run of this Mission in the Scheduler.
|
||||
if ClientsAlive == false then
|
||||
if Mission:IsOngoing() then
|
||||
-- Mission status back to pending...
|
||||
Mission:Pending()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Mission:StatusToClients()
|
||||
|
||||
if Mission:ReportTrigger() then
|
||||
Mission:ReportToAll()
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Start the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.Start()
|
||||
if MISSIONSCHEDULER ~= nil then
|
||||
--MISSIONSCHEDULER.SchedulerId = routines.scheduleFunction( MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
MISSIONSCHEDULER.SchedulerId = SCHEDULER:New( nil, MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Stop the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.Stop()
|
||||
if MISSIONSCHEDULER.SchedulerId then
|
||||
routines.removeFunction(MISSIONSCHEDULER.SchedulerId)
|
||||
MISSIONSCHEDULER.SchedulerId = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||
-- @param Mission is the MISSION object instantiated by @{MISSION:New}.
|
||||
-- @return MISSION
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
function MISSIONSCHEDULER.AddMission( Mission )
|
||||
MISSIONSCHEDULER.Missions[Mission.Name] = Mission
|
||||
MISSIONSCHEDULER.MissionCount = MISSIONSCHEDULER.MissionCount + 1
|
||||
-- Add an overall AI Client for the AI tasks... This AI Client will facilitate the Events in the background for each Task.
|
||||
--MissionAdd:AddClient( CLIENT:Register( 'AI' ) )
|
||||
|
||||
return Mission
|
||||
end
|
||||
|
||||
--- Remove a MISSION from the MISSIONSCHEDULER.
|
||||
-- @param MissionName is the name of the MISSION given at declaration using @{AddMission}.
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
--
|
||||
-- -- Now remove the Mission.
|
||||
-- MISSIONSCHEDULER:RemoveMission( 'Russia Transport Troops SA-6' )
|
||||
function MISSIONSCHEDULER.RemoveMission( MissionName )
|
||||
MISSIONSCHEDULER.Missions[MissionName] = nil
|
||||
MISSIONSCHEDULER.MissionCount = MISSIONSCHEDULER.MissionCount - 1
|
||||
end
|
||||
|
||||
--- Find a MISSION within the MISSIONSCHEDULER.
|
||||
-- @param MissionName is the name of the MISSION given at declaration using @{AddMission}.
|
||||
-- @return MISSION
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
--
|
||||
-- -- Now find the Mission.
|
||||
-- MissionFind = MISSIONSCHEDULER:FindMission( 'Russia Transport Troops SA-6' )
|
||||
function MISSIONSCHEDULER.FindMission( MissionName )
|
||||
return MISSIONSCHEDULER.Missions[MissionName]
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsShow( )
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = true
|
||||
Mission.MissionReportFlash = false
|
||||
end
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsFlash( TimeInterval )
|
||||
local Count = 0
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = false
|
||||
Mission.MissionReportFlash = true
|
||||
Mission.MissionReportTrigger = timer.getTime() + Count * TimeInterval
|
||||
Mission.MissionTimeInterval = MISSIONSCHEDULER.MissionCount * TimeInterval
|
||||
env.info( "TimeInterval = " .. Mission.MissionTimeInterval )
|
||||
Count = Count + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsHide( Prm )
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = false
|
||||
Mission.MissionReportFlash = false
|
||||
end
|
||||
end
|
||||
|
||||
--- Enables a MENU option in the communications menu under F10 to control the status of the active missions.
|
||||
-- This function should be called only once when starting the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.ReportMenu()
|
||||
local ReportMenu = SUBMENU:New( 'Status' )
|
||||
local ReportMenuShow = COMMANDMENU:New( 'Show Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsShow, 0 )
|
||||
local ReportMenuFlash = COMMANDMENU:New('Flash Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsFlash, 120 )
|
||||
local ReportMenuHide = COMMANDMENU:New( 'Hide Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsHide, 0 )
|
||||
end
|
||||
|
||||
--- Show the remaining mission time.
|
||||
function MISSIONSCHEDULER:TimeShow()
|
||||
self.TimeIntervalCount = self.TimeIntervalCount + 1
|
||||
if self.TimeIntervalCount >= self.TimeTriggerShow then
|
||||
local TimeMsg = string.format("%00d", ( self.TimeSeconds / 60 ) - ( timer.getTime() / 60 )) .. ' minutes left until mission reload.'
|
||||
MESSAGE:New( TimeMsg, self.TimeShow, "Mission time" ):ToAll()
|
||||
self.TimeIntervalCount = 0
|
||||
end
|
||||
end
|
||||
|
||||
function MISSIONSCHEDULER:Time( TimeSeconds, TimeIntervalShow, TimeShow )
|
||||
|
||||
self.TimeIntervalCount = 0
|
||||
self.TimeSeconds = TimeSeconds
|
||||
self.TimeIntervalShow = TimeIntervalShow
|
||||
self.TimeShow = TimeShow
|
||||
end
|
||||
|
||||
--- Adds a mission scoring to the game.
|
||||
function MISSIONSCHEDULER:Scoring( Scoring )
|
||||
|
||||
self.Scoring = Scoring
|
||||
end
|
||||
|
||||
--- This module contains the TASK class.
|
||||
--
|
||||
-- 1) @{#TASK} class, extends @{Base#BASE}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20170315_1007' )
|
||||
env.info( 'Moose Generation Timestamp: 20170315_1149' )
|
||||
local base = _G
|
||||
|
||||
Include = {}
|
||||
@ -32319,22 +32319,6 @@ MISSION = {
|
||||
ClassName = "MISSION",
|
||||
Name = "",
|
||||
MissionStatus = "PENDING",
|
||||
_Clients = {},
|
||||
TaskMenus = {},
|
||||
TaskCategoryMenus = {},
|
||||
TaskTypeMenus = {},
|
||||
_ActiveTasks = {},
|
||||
GoalFunction = nil,
|
||||
MissionReportTrigger = 0,
|
||||
MissionProgressTrigger = 0,
|
||||
MissionReportShow = false,
|
||||
MissionReportFlash = false,
|
||||
MissionTimeInterval = 0,
|
||||
MissionCoalition = "",
|
||||
SUCCESS = 1,
|
||||
FAILED = 2,
|
||||
REPEAT = 3,
|
||||
_GoalTasks = {}
|
||||
}
|
||||
|
||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||
@ -32541,6 +32525,10 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi
|
||||
self.MissionCoalition = MissionCoalition
|
||||
|
||||
self.Tasks = {}
|
||||
|
||||
-- Private implementations
|
||||
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
@ -32831,76 +32819,44 @@ function MISSION:GetNextTaskID( Task )
|
||||
return self.Tasks[TaskName].n
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- old stuff
|
||||
|
||||
--- Returns if a Mission has completed.
|
||||
-- @return bool
|
||||
--- Is the @{Mission} **Completed**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsCompleted()
|
||||
self:F()
|
||||
return self.MissionStatus == "ACCOMPLISHED"
|
||||
return self:Is( "Completed" )
|
||||
end
|
||||
|
||||
--- Set a Mission to completed.
|
||||
function MISSION:Completed()
|
||||
self:F()
|
||||
self.MissionStatus = "ACCOMPLISHED"
|
||||
self:StatusToClients()
|
||||
--- Is the @{Mission} **Idle**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsIdle()
|
||||
return self:Is( "Idle" )
|
||||
end
|
||||
|
||||
--- Returns if a Mission is ongoing.
|
||||
-- treturn bool
|
||||
--- Is the @{Mission} **Ongoing**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsOngoing()
|
||||
self:F()
|
||||
return self.MissionStatus == "ONGOING"
|
||||
return self:Is( "Ongoing" )
|
||||
end
|
||||
|
||||
--- Set a Mission to ongoing.
|
||||
function MISSION:Ongoing()
|
||||
self:F()
|
||||
self.MissionStatus = "ONGOING"
|
||||
--self:StatusToClients()
|
||||
--- Is the @{Mission} **Failed**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsFailed()
|
||||
return self:Is( "Failed" )
|
||||
end
|
||||
|
||||
--- Returns if a Mission is pending.
|
||||
-- treturn bool
|
||||
function MISSION:IsPending()
|
||||
self:F()
|
||||
return self.MissionStatus == "PENDING"
|
||||
end
|
||||
|
||||
--- Set a Mission to pending.
|
||||
function MISSION:Pending()
|
||||
self:F()
|
||||
self.MissionStatus = "PENDING"
|
||||
self:StatusToClients()
|
||||
end
|
||||
|
||||
--- Returns if a Mission has failed.
|
||||
-- treturn bool
|
||||
function MISSION:IsFailed()
|
||||
self:F()
|
||||
return self.MissionStatus == "FAILED"
|
||||
end
|
||||
|
||||
--- Set a Mission to failed.
|
||||
function MISSION:Failed()
|
||||
self:F()
|
||||
self.MissionStatus = "FAILED"
|
||||
self:StatusToClients()
|
||||
end
|
||||
|
||||
--- Send the status of the MISSION to all Clients.
|
||||
function MISSION:StatusToClients()
|
||||
self:F()
|
||||
if self.MissionReportFlash then
|
||||
for ClientID, Client in pairs( self._Clients ) do
|
||||
Client:Message( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. '! ( ' .. self.MissionPriority .. ' mission ) ', 10, "Mission Command: Mission Status")
|
||||
end
|
||||
end
|
||||
--- Is the @{Mission} **Hold**.
|
||||
-- @param #MISSION self
|
||||
-- @return #boolean
|
||||
function MISSION:IsHold()
|
||||
return self:Is( "Hold" )
|
||||
end
|
||||
|
||||
--- Validates if the Mission has a Group
|
||||
-- @param #MISSION
|
||||
-- @return #boolean true if the Mission has a Group.
|
||||
function MISSION:HasGroup( TaskGroup )
|
||||
local Has = false
|
||||
|
||||
@ -32993,107 +32949,6 @@ function MISSION:ReportDetails()
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
--- Report the status of all MISSIONs to all active Clients.
|
||||
function MISSION:ReportToAll()
|
||||
self:F()
|
||||
|
||||
local AlivePlayers = ''
|
||||
for ClientID, Client in pairs( self._Clients ) do
|
||||
if Client:GetDCSGroup() then
|
||||
if Client:GetClientGroupDCSUnit() then
|
||||
if Client:GetClientGroupDCSUnit():getLife() > 0.0 then
|
||||
if AlivePlayers == '' then
|
||||
AlivePlayers = ' Players: ' .. Client:GetClientGroupDCSUnit():getPlayerName()
|
||||
else
|
||||
AlivePlayers = AlivePlayers .. ' / ' .. Client:GetClientGroupDCSUnit():getPlayerName()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local Tasks = self:GetTasks()
|
||||
local TaskText = ""
|
||||
for TaskID, TaskData in pairs( Tasks ) do
|
||||
TaskText = TaskText .. " - Task " .. TaskID .. ": " .. TaskData.Name .. ": " .. TaskData:GetGoalProgress() .. "\n"
|
||||
end
|
||||
MESSAGE:New( self.MissionCoalition .. ' "' .. self.Name .. '": ' .. self.MissionStatus .. ' ( ' .. self.MissionPriority .. ' mission )' .. AlivePlayers .. "\n" .. TaskText:gsub("\n$",""), 10, "Mission Command: Mission Report" ):ToAll()
|
||||
end
|
||||
|
||||
|
||||
--- Add a goal function to a MISSION. Goal functions are called when a @{TASK} within a mission has been completed.
|
||||
-- @param function GoalFunction is the function defined by the mission designer to evaluate whether a certain goal has been reached after a @{TASK} finishes within the @{MISSION}. A GoalFunction must accept 2 parameters: Mission, Client, which contains the current MISSION object and the current CLIENT object respectively.
|
||||
-- @usage
|
||||
-- PatriotActivation = {
|
||||
-- { "US SAM Patriot Zerti", false },
|
||||
-- { "US SAM Patriot Zegduleti", false },
|
||||
-- { "US SAM Patriot Gvleti", false }
|
||||
-- }
|
||||
--
|
||||
-- function DeployPatriotTroopsGoal( Mission, Client )
|
||||
--
|
||||
--
|
||||
-- -- Check if the cargo is all deployed for mission success.
|
||||
-- for CargoID, CargoData in pairs( Mission._Cargos ) do
|
||||
-- if Group.getByName( CargoData.CargoGroupName ) then
|
||||
-- CargoGroup = Group.getByName( CargoData.CargoGroupName )
|
||||
-- if CargoGroup then
|
||||
-- -- Check if the cargo is ready to activate
|
||||
-- CurrentLandingZoneID = routines.IsUnitInZones( CargoGroup:getUnits()[1], Mission:GetTask( 2 ).LandingZones ) -- The second task is the Deploytask to measure mission success upon
|
||||
-- if CurrentLandingZoneID then
|
||||
-- if PatriotActivation[CurrentLandingZoneID][2] == false then
|
||||
-- -- Now check if this is a new Mission Task to be completed...
|
||||
-- trigger.action.setGroupAIOn( Group.getByName( PatriotActivation[CurrentLandingZoneID][1] ) )
|
||||
-- PatriotActivation[CurrentLandingZoneID][2] = true
|
||||
-- MessageToBlue( "Mission Command: Message to all airborne units! The " .. PatriotActivation[CurrentLandingZoneID][1] .. " is armed. Our air defenses are now stronger.", 60, "BLUE/PatriotDefense" )
|
||||
-- MessageToRed( "Mission Command: Our satellite systems are detecting additional NATO air defenses. To all airborne units: Take care!!!", 60, "RED/PatriotDefense" )
|
||||
-- Mission:GetTask( 2 ):AddGoalCompletion( "Patriots activated", PatriotActivation[CurrentLandingZoneID][1], 1 ) -- Register Patriot activation as part of mission goal.
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Transport Troops', 'Operational', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.', 'NATO' )
|
||||
-- Mission:AddGoalFunction( DeployPatriotTroopsGoal )
|
||||
function MISSION:AddGoalFunction( GoalFunction )
|
||||
self:F()
|
||||
self.GoalFunction = GoalFunction
|
||||
end
|
||||
|
||||
--- Register a new @{CLIENT} to participate within the mission.
|
||||
-- @param CLIENT Client is the @{CLIENT} object. The object must have been instantiated with @{CLIENT:New}.
|
||||
-- @return CLIENT
|
||||
-- @usage
|
||||
-- Add a number of Client objects to the Mission.
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 1', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 3', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*HOT-Deploy Troops 2', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
-- Mission:AddClient( CLIENT:FindByName( 'US UH-1H*RAMP-Deploy Troops 4', 'Transport 3 groups of air defense engineers from our barracks "Gold" and "Titan" to each patriot battery control center to activate our air defenses.' ):Transport() )
|
||||
function MISSION:AddClient( Client )
|
||||
self:F( { Client } )
|
||||
|
||||
local Valid = true
|
||||
|
||||
if Valid then
|
||||
self._Clients[Client.ClientName] = Client
|
||||
end
|
||||
|
||||
return Client
|
||||
end
|
||||
|
||||
--- Find a @{CLIENT} object within the @{MISSION} by its ClientName.
|
||||
-- @param CLIENT ClientName is a string defining the Client Group as defined within the ME.
|
||||
-- @return CLIENT
|
||||
-- @usage
|
||||
-- -- Seach for Client "Bomber" within the Mission.
|
||||
-- local BomberClient = Mission:FindClient( "Bomber" )
|
||||
function MISSION:FindClient( ClientName )
|
||||
self:F( { self._Clients[ClientName] } )
|
||||
return self._Clients[ClientName]
|
||||
end
|
||||
|
||||
|
||||
--- Get all the TASKs from the Mission. This function is useful in GoalFunctions.
|
||||
-- @return {TASK,...} Structure of TASKS with the @{TASK} number as the key.
|
||||
-- @usage
|
||||
@ -33107,333 +32962,6 @@ function MISSION:GetTasks()
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
_TransportExecuteStage: Defines the different stages of Transport unload/load execution. This table is internal and is used to control the validity of Transport load/unload timing.
|
||||
|
||||
- _TransportExecuteStage.EXECUTING
|
||||
- _TransportExecuteStage.SUCCESS
|
||||
- _TransportExecuteStage.FAILED
|
||||
|
||||
--]]
|
||||
_TransportExecuteStage = {
|
||||
NONE = 0,
|
||||
EXECUTING = 1,
|
||||
SUCCESS = 2,
|
||||
FAILED = 3
|
||||
}
|
||||
|
||||
|
||||
--- The MISSIONSCHEDULER is an OBJECT and is the main scheduler of ALL active MISSIONs registered within this scheduler. It's workings are considered internal and is automatically created when the Mission.lua file is included.
|
||||
-- @type MISSIONSCHEDULER
|
||||
-- @field #MISSIONSCHEDULER.MISSIONS Missions
|
||||
MISSIONSCHEDULER = {
|
||||
Missions = {},
|
||||
MissionCount = 0,
|
||||
TimeIntervalCount = 0,
|
||||
TimeIntervalShow = 150,
|
||||
TimeSeconds = 14400,
|
||||
TimeShow = 5
|
||||
}
|
||||
|
||||
--- @type MISSIONSCHEDULER.MISSIONS
|
||||
-- @list <#MISSION> Mission
|
||||
|
||||
--- This is the main MISSIONSCHEDULER Scheduler function. It is considered internal and is automatically created when the Mission.lua file is included.
|
||||
function MISSIONSCHEDULER.Scheduler()
|
||||
|
||||
|
||||
-- loop through the missions in the TransportTasks
|
||||
for MissionName, MissionData in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
|
||||
local Mission = MissionData -- #MISSION
|
||||
|
||||
if not Mission:IsCompleted() then
|
||||
|
||||
-- This flag will monitor if for this mission, there are clients alive. If this flag is still false at the end of the loop, the mission status will be set to Pending (if not Failed or Completed).
|
||||
local ClientsAlive = false
|
||||
|
||||
for ClientID, ClientData in pairs( Mission._Clients ) do
|
||||
|
||||
local Client = ClientData -- Wrapper.Client#CLIENT
|
||||
|
||||
if Client:IsAlive() then
|
||||
|
||||
-- There is at least one Client that is alive... So the Mission status is set to Ongoing.
|
||||
ClientsAlive = true
|
||||
|
||||
-- If this Client was not registered as Alive before:
|
||||
-- 1. We register the Client as Alive.
|
||||
-- 2. We initialize the Client Tasks and make a link to the original Mission Task.
|
||||
-- 3. We initialize the Cargos.
|
||||
-- 4. We flag the Mission as Ongoing.
|
||||
if not Client.ClientAlive then
|
||||
Client.ClientAlive = true
|
||||
Client.ClientBriefingShown = false
|
||||
for TaskNumber, Task in pairs( Mission._Tasks ) do
|
||||
-- Note that this a deepCopy. Each client must have their own Tasks with own Stages!!!
|
||||
Client._Tasks[TaskNumber] = routines.utils.deepCopy( Mission._Tasks[TaskNumber] )
|
||||
-- Each MissionTask must point to the original Mission.
|
||||
Client._Tasks[TaskNumber].MissionTask = Mission._Tasks[TaskNumber]
|
||||
Client._Tasks[TaskNumber].Cargos = Mission._Tasks[TaskNumber].Cargos
|
||||
Client._Tasks[TaskNumber].LandingZones = Mission._Tasks[TaskNumber].LandingZones
|
||||
end
|
||||
|
||||
Mission:Ongoing()
|
||||
end
|
||||
|
||||
|
||||
-- For each Client, check for each Task the state and evolve the mission.
|
||||
-- This flag will indicate if the Task of the Client is Complete.
|
||||
local TaskComplete = false
|
||||
|
||||
for TaskNumber, Task in pairs( Client._Tasks ) do
|
||||
|
||||
if not Task.Stage then
|
||||
Task:SetStage( 1 )
|
||||
end
|
||||
|
||||
|
||||
local TransportTime = timer.getTime()
|
||||
|
||||
if not Task:IsDone() then
|
||||
|
||||
if Task:Goal() then
|
||||
Task:ShowGoalProgress( Mission, Client )
|
||||
end
|
||||
|
||||
--env.info( 'Scheduler: Mission = ' .. Mission.Name .. ' / Client = ' .. Client.ClientName .. ' / Task = ' .. Task.Name .. ' / Stage = ' .. Task.ActiveStage .. ' - ' .. Task.Stage.Name .. ' - ' .. Task.Stage.StageType )
|
||||
|
||||
-- Action
|
||||
if Task:StageExecute() then
|
||||
Task.Stage:Execute( Mission, Client, Task )
|
||||
end
|
||||
|
||||
-- Wait until execution is finished
|
||||
if Task.ExecuteStage == _TransportExecuteStage.EXECUTING then
|
||||
Task.Stage:Executing( Mission, Client, Task )
|
||||
end
|
||||
|
||||
-- Validate completion or reverse to earlier stage
|
||||
if Task.Time + Task.Stage.WaitTime <= TransportTime then
|
||||
Task:SetStage( Task.Stage:Validate( Mission, Client, Task ) )
|
||||
end
|
||||
|
||||
if Task:IsDone() then
|
||||
--env.info( 'Scheduler: Mission '.. Mission.Name .. ' Task ' .. Task.Name .. ' Stage ' .. Task.Stage.Name .. ' done. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
||||
TaskComplete = true -- when a task is not yet completed, a mission cannot be completed
|
||||
|
||||
else
|
||||
-- break only if this task is not yet done, so that future task are not yet activated.
|
||||
TaskComplete = false -- when a task is not yet completed, a mission cannot be completed
|
||||
--env.info( 'Scheduler: Mission "'.. Mission.Name .. '" Task "' .. Task.Name .. '" Stage "' .. Task.Stage.Name .. '" break. TaskComplete = ' .. string.format ( "%s", TaskComplete and "true" or "false" ) )
|
||||
break
|
||||
end
|
||||
|
||||
if TaskComplete then
|
||||
|
||||
if Mission.GoalFunction ~= nil then
|
||||
Mission.GoalFunction( Mission, Client )
|
||||
end
|
||||
if MISSIONSCHEDULER.Scoring then
|
||||
MISSIONSCHEDULER.Scoring:_AddMissionTaskScore( Client:GetClientGroupDCSUnit(), Mission.Name, 25 )
|
||||
end
|
||||
|
||||
-- if not Mission:IsCompleted() then
|
||||
-- end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local MissionComplete = true
|
||||
for TaskNumber, Task in pairs( Mission._Tasks ) do
|
||||
if Task:Goal() then
|
||||
-- Task:ShowGoalProgress( Mission, Client )
|
||||
if Task:IsGoalReached() then
|
||||
else
|
||||
MissionComplete = false
|
||||
end
|
||||
else
|
||||
MissionComplete = false -- If there is no goal, the mission should never be ended. The goal status will be set somewhere else.
|
||||
end
|
||||
end
|
||||
|
||||
if MissionComplete then
|
||||
Mission:Completed()
|
||||
if MISSIONSCHEDULER.Scoring then
|
||||
MISSIONSCHEDULER.Scoring:_AddMissionScore( Mission.Name, 100 )
|
||||
end
|
||||
else
|
||||
if TaskComplete then
|
||||
-- Reset for new tasking of active client
|
||||
Client.ClientAlive = false -- Reset the client tasks.
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
if Client.ClientAlive then
|
||||
env.info( 'Scheduler: Client "' .. Client.ClientName .. '" is inactive.' )
|
||||
Client.ClientAlive = false
|
||||
|
||||
-- This is tricky. If we sanitize Client._Tasks before sanitizing Client._Tasks[TaskNumber].MissionTask, then the original MissionTask will be sanitized, and will be lost within the garbage collector.
|
||||
-- So first sanitize Client._Tasks[TaskNumber].MissionTask, after that, sanitize only the whole _Tasks structure...
|
||||
--Client._Tasks[TaskNumber].MissionTask = nil
|
||||
--Client._Tasks = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If all Clients of this Mission are not activated, then the Mission status needs to be put back into Pending status.
|
||||
-- But only if the Mission was Ongoing. In case the Mission is Completed or Failed, the Mission status may not be changed. In these cases, this will be the last run of this Mission in the Scheduler.
|
||||
if ClientsAlive == false then
|
||||
if Mission:IsOngoing() then
|
||||
-- Mission status back to pending...
|
||||
Mission:Pending()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Mission:StatusToClients()
|
||||
|
||||
if Mission:ReportTrigger() then
|
||||
Mission:ReportToAll()
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--- Start the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.Start()
|
||||
if MISSIONSCHEDULER ~= nil then
|
||||
--MISSIONSCHEDULER.SchedulerId = routines.scheduleFunction( MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
MISSIONSCHEDULER.SchedulerId = SCHEDULER:New( nil, MISSIONSCHEDULER.Scheduler, { }, 0, 2 )
|
||||
end
|
||||
end
|
||||
|
||||
--- Stop the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.Stop()
|
||||
if MISSIONSCHEDULER.SchedulerId then
|
||||
routines.removeFunction(MISSIONSCHEDULER.SchedulerId)
|
||||
MISSIONSCHEDULER.SchedulerId = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- This is the main MISSION declaration method. Each Mission is like the master or a Mission orchestration between, Clients, Tasks, Stages etc.
|
||||
-- @param Mission is the MISSION object instantiated by @{MISSION:New}.
|
||||
-- @return MISSION
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
function MISSIONSCHEDULER.AddMission( Mission )
|
||||
MISSIONSCHEDULER.Missions[Mission.Name] = Mission
|
||||
MISSIONSCHEDULER.MissionCount = MISSIONSCHEDULER.MissionCount + 1
|
||||
-- Add an overall AI Client for the AI tasks... This AI Client will facilitate the Events in the background for each Task.
|
||||
--MissionAdd:AddClient( CLIENT:Register( 'AI' ) )
|
||||
|
||||
return Mission
|
||||
end
|
||||
|
||||
--- Remove a MISSION from the MISSIONSCHEDULER.
|
||||
-- @param MissionName is the name of the MISSION given at declaration using @{AddMission}.
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
--
|
||||
-- -- Now remove the Mission.
|
||||
-- MISSIONSCHEDULER:RemoveMission( 'Russia Transport Troops SA-6' )
|
||||
function MISSIONSCHEDULER.RemoveMission( MissionName )
|
||||
MISSIONSCHEDULER.Missions[MissionName] = nil
|
||||
MISSIONSCHEDULER.MissionCount = MISSIONSCHEDULER.MissionCount - 1
|
||||
end
|
||||
|
||||
--- Find a MISSION within the MISSIONSCHEDULER.
|
||||
-- @param MissionName is the name of the MISSION given at declaration using @{AddMission}.
|
||||
-- @return MISSION
|
||||
-- @usage
|
||||
-- -- Declare a mission.
|
||||
-- Mission = MISSION:New( 'Russia Transport Troops SA-6',
|
||||
-- 'Operational',
|
||||
-- 'Transport troops from the control center to one of the SA-6 SAM sites to activate their operation.',
|
||||
-- 'Russia' )
|
||||
-- MISSIONSCHEDULER:AddMission( Mission )
|
||||
--
|
||||
-- -- Now find the Mission.
|
||||
-- MissionFind = MISSIONSCHEDULER:FindMission( 'Russia Transport Troops SA-6' )
|
||||
function MISSIONSCHEDULER.FindMission( MissionName )
|
||||
return MISSIONSCHEDULER.Missions[MissionName]
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsShow( )
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = true
|
||||
Mission.MissionReportFlash = false
|
||||
end
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsFlash( TimeInterval )
|
||||
local Count = 0
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = false
|
||||
Mission.MissionReportFlash = true
|
||||
Mission.MissionReportTrigger = timer.getTime() + Count * TimeInterval
|
||||
Mission.MissionTimeInterval = MISSIONSCHEDULER.MissionCount * TimeInterval
|
||||
env.info( "TimeInterval = " .. Mission.MissionTimeInterval )
|
||||
Count = Count + 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Internal function used by the MISSIONSCHEDULER menu.
|
||||
function MISSIONSCHEDULER.ReportMissionsHide( Prm )
|
||||
for MissionName, Mission in pairs( MISSIONSCHEDULER.Missions ) do
|
||||
Mission.MissionReportShow = false
|
||||
Mission.MissionReportFlash = false
|
||||
end
|
||||
end
|
||||
|
||||
--- Enables a MENU option in the communications menu under F10 to control the status of the active missions.
|
||||
-- This function should be called only once when starting the MISSIONSCHEDULER.
|
||||
function MISSIONSCHEDULER.ReportMenu()
|
||||
local ReportMenu = SUBMENU:New( 'Status' )
|
||||
local ReportMenuShow = COMMANDMENU:New( 'Show Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsShow, 0 )
|
||||
local ReportMenuFlash = COMMANDMENU:New('Flash Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsFlash, 120 )
|
||||
local ReportMenuHide = COMMANDMENU:New( 'Hide Report Missions', ReportMenu, MISSIONSCHEDULER.ReportMissionsHide, 0 )
|
||||
end
|
||||
|
||||
--- Show the remaining mission time.
|
||||
function MISSIONSCHEDULER:TimeShow()
|
||||
self.TimeIntervalCount = self.TimeIntervalCount + 1
|
||||
if self.TimeIntervalCount >= self.TimeTriggerShow then
|
||||
local TimeMsg = string.format("%00d", ( self.TimeSeconds / 60 ) - ( timer.getTime() / 60 )) .. ' minutes left until mission reload.'
|
||||
MESSAGE:New( TimeMsg, self.TimeShow, "Mission time" ):ToAll()
|
||||
self.TimeIntervalCount = 0
|
||||
end
|
||||
end
|
||||
|
||||
function MISSIONSCHEDULER:Time( TimeSeconds, TimeIntervalShow, TimeShow )
|
||||
|
||||
self.TimeIntervalCount = 0
|
||||
self.TimeSeconds = TimeSeconds
|
||||
self.TimeIntervalShow = TimeIntervalShow
|
||||
self.TimeShow = TimeShow
|
||||
end
|
||||
|
||||
--- Adds a mission scoring to the game.
|
||||
function MISSIONSCHEDULER:Scoring( Scoring )
|
||||
|
||||
self.Scoring = Scoring
|
||||
end
|
||||
|
||||
--- This module contains the TASK class.
|
||||
--
|
||||
-- 1) @{#TASK} class, extends @{Base#BASE}
|
||||
|
||||
@ -354,6 +354,12 @@ Use the method <a href="AI_Cap.html##(AI_CAP_ZONE).SetEngageZone">AI<em>Cap#AI</
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAP_ZONE).OnEnterEngaging">AI_CAP_ZONE:OnEnterEngaging(Controllable, From, Event, To)</a></td>
|
||||
<td class="summary">
|
||||
<p>OnEnter Transition Handler for State Engaging.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAP_ZONE).OnEventDead">AI_CAP_ZONE:OnEventDead(EventData)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -1171,6 +1177,27 @@ The To State string.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAP_ZONE).OnEventDead" >
|
||||
<strong>AI_CAP_ZONE:OnEventDead(EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAP_ZONE).OnLeaveEngaging" >
|
||||
<strong>AI_CAP_ZONE:OnLeaveEngaging(Controllable, From, Event, To)</strong>
|
||||
</a>
|
||||
|
||||
@ -163,13 +163,16 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
<h3>1.2.2) AI<em>CAS</em>ZONE Events</h3>
|
||||
|
||||
<ul>
|
||||
<li><strong>Start</strong> ( Group ): Start the process.</li>
|
||||
<li><strong>Route</strong> ( Group ): Route the AI to a new random 3D point within the Patrol Zone.</li>
|
||||
<li><strong>Engage</strong> ( Group ): Engage the AI to provide CAS in the Engage Zone, destroying any target it finds.</li>
|
||||
<li><strong>RTB</strong> ( Group ): Route the AI to the home base.</li>
|
||||
<li><strong>Detect</strong> ( Group ): The AI is detecting targets.</li>
|
||||
<li><strong>Detected</strong> ( Group ): The AI has detected new targets.</li>
|
||||
<li><strong>Status</strong> ( Group ): The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.</li>
|
||||
<li>**<a href="AI_Patrol.html##(AI_PATROL_ZONE).Start">AI<em>Patrol#AI</em>PATROL_ZONE.Start</a>**: Start the process.</li>
|
||||
<li>**<a href="AI_Patrol.html##(AI_PATROL_ZONE).Route">AI<em>Patrol#AI</em>PATROL_ZONE.Route</a>**: Route the AI to a new random 3D point within the Patrol Zone.</li>
|
||||
<li>**<a href="##(AI_CAS_ZONE).Engage">AI<em>CAS</em>ZONE.Engage</a>**: Engage the AI to provide CAS in the Engage Zone, destroying any target it finds.</li>
|
||||
<li>**<a href="##(AI_CAS_ZONE).Abort">AI<em>CAS</em>ZONE.Abort</a>**: Aborts the engagement and return patrolling in the patrol zone.</li>
|
||||
<li>**<a href="AI_Patrol.html##(AI_PATROL_ZONE).RTB">AI<em>Patrol#AI</em>PATROL_ZONE.RTB</a>**: Route the AI to the home base.</li>
|
||||
<li>**<a href="AI_Patrol.html##(AI_PATROL_ZONE).Detect">AI<em>Patrol#AI</em>PATROL_ZONE.Detect</a>**: The AI is detecting targets.</li>
|
||||
<li>**<a href="AI_Patrol.html##(AI_PATROL_ZONE).Detected">AI<em>Patrol#AI</em>PATROL_ZONE.Detected</a>**: The AI has detected new targets.</li>
|
||||
<li>**<a href="##(AI_CAS_ZONE).Destroy">AI<em>CAS</em>ZONE.Destroy</a>**: The AI has destroyed a target <a href="Unit.html">Unit</a>.</li>
|
||||
<li>**<a href="##(AI_CAS_ZONE).Destroyed">AI<em>CAS</em>ZONE.Destroyed</a>**: The AI has destroyed all target <a href="Unit.html">Unit</a>s assigned in the CAS task.</li>
|
||||
<li><strong>Status</strong>: The AI is checking status (fuel and damage). When the tresholds have been reached, the AI will RTB.</li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
@ -260,7 +263,7 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).Engage">AI_CAS_ZONE:Engage(EngageSpeed, EngageAltitude, EngageWeaponExpend, EngageAttackQty, EngageDirection)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).Engage">AI_CAS_ZONE:Engage(EngageSpeed, EngageWeaponExpend, EngageAltitude, EngageAttackQty, EngageDirection)</a></td>
|
||||
<td class="summary">
|
||||
<p>Synchronous Event Trigger for Event Engage.</p>
|
||||
</td>
|
||||
@ -371,18 +374,18 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).OnBeforeFired">AI_CAS_ZONE:OnBeforeFired(Controllable, From, Event, To)</a></td>
|
||||
<td class="summary">
|
||||
<p>OnBefore Transition Handler for Event Fired.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).OnDead">AI_CAS_ZONE:OnDead(EventData)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).OnEnterEngaging">AI_CAS_ZONE:OnEnterEngaging(Controllable, From, Event, To)</a></td>
|
||||
<td class="summary">
|
||||
<p>OnEnter Transition Handler for State Engaging.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).OnEventDead">AI_CAS_ZONE:OnEventDead(EventData)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -422,7 +425,7 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).__Engage">AI_CAS_ZONE:__Engage(Delay, EngageSpeed, EngageAltitude, EngageWeaponExpend, EngageAttackQty, EngageDirection)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).__Engage">AI_CAS_ZONE:__Engage(Delay, EngageSpeed, EngageWeaponExpend, EngageAltitude, EngageAttackQty, EngageDirection)</a></td>
|
||||
<td class="summary">
|
||||
<p>Asynchronous Event Trigger for Event Engage.</p>
|
||||
</td>
|
||||
@ -431,6 +434,12 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).__Fired">AI_CAS_ZONE:__Fired(Delay)</a></td>
|
||||
<td class="summary">
|
||||
<p>Asynchronous Event Trigger for Event Fired.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(AI_CAS_ZONE).onafterAbort">AI_CAS_ZONE:onafterAbort(Controllable, From, Event, To)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -599,7 +608,7 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).Engage" >
|
||||
<strong>AI_CAS_ZONE:Engage(EngageSpeed, EngageAltitude, EngageWeaponExpend, EngageAttackQty, EngageDirection)</strong>
|
||||
<strong>AI_CAS_ZONE:Engage(EngageSpeed, EngageWeaponExpend, EngageAltitude, EngageAttackQty, EngageDirection)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -616,14 +625,14 @@ It can be notified to go RTB through the <strong>RTB</strong> event.</p>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> EngageAltitude </em></code>:
|
||||
(optional) Desired altitude to perform the unit engagement.</p>
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(AI.Task.WeaponExpend)">Dcs.DCSTypes#AI.Task.WeaponExpend</a> EngageWeaponExpend </em></code>:
|
||||
(optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(AI.Task.WeaponExpend)">Dcs.DCSTypes#AI.Task.WeaponExpend</a> EngageWeaponExpend </em></code>:
|
||||
(optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.</p>
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> EngageAltitude </em></code>:
|
||||
(optional) Desired altitude to perform the unit engagement.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
@ -1222,27 +1231,6 @@ Return false to cancel Transition.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).OnDead" >
|
||||
<strong>AI_CAS_ZONE:OnDead(EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).OnEnterEngaging" >
|
||||
<strong>AI_CAS_ZONE:OnEnterEngaging(Controllable, From, Event, To)</strong>
|
||||
</a>
|
||||
@ -1283,6 +1271,27 @@ The To State string.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).OnEventDead" >
|
||||
<strong>AI_CAS_ZONE:OnEventDead(EventData)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Core.Event.html##(EVENTDATA)">Core.Event#EVENTDATA</a> EventData </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).OnLeaveEngaging" >
|
||||
<strong>AI_CAS_ZONE:OnLeaveEngaging(Controllable, From, Event, To)</strong>
|
||||
</a>
|
||||
@ -1439,7 +1448,7 @@ The delay in seconds.</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).__Engage" >
|
||||
<strong>AI_CAS_ZONE:__Engage(Delay, EngageSpeed, EngageAltitude, EngageWeaponExpend, EngageAttackQty, EngageDirection)</strong>
|
||||
<strong>AI_CAS_ZONE:__Engage(Delay, EngageSpeed, EngageWeaponExpend, EngageAltitude, EngageAttackQty, EngageDirection)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -1462,14 +1471,14 @@ The delay in seconds.</p>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> EngageAltitude </em></code>:
|
||||
(optional) Desired altitude to perform the unit engagement.</p>
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(AI.Task.WeaponExpend)">Dcs.DCSTypes#AI.Task.WeaponExpend</a> EngageWeaponExpend </em></code>:
|
||||
(optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(AI.Task.WeaponExpend)">Dcs.DCSTypes#AI.Task.WeaponExpend</a> EngageWeaponExpend </em></code>:
|
||||
(optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.</p>
|
||||
<p><code><em><a href="Dcs.DCSTypes.html##(Distance)">Dcs.DCSTypes#Distance</a> EngageAltitude </em></code>:
|
||||
(optional) Desired altitude to perform the unit engagement.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
@ -1512,6 +1521,46 @@ The delay in seconds.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).onafterAbort" >
|
||||
<strong>AI_CAS_ZONE:onafterAbort(Controllable, From, Event, To)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Wrapper.Controllable.html##(CONTROLLABLE)">Wrapper.Controllable#CONTROLLABLE</a> Controllable </em></code>:
|
||||
The Controllable Object managed by the FSM.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string From </em></code>:
|
||||
The From State string.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>:
|
||||
The Event string.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string To </em></code>:
|
||||
The To State string.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(AI_CAS_ZONE).onafterAccomplish" >
|
||||
<strong>AI_CAS_ZONE:onafterAccomplish(Controllable, From, Event, To)</strong>
|
||||
</a>
|
||||
|
||||
@ -276,12 +276,6 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS).TaskName">ACT_ACCOUNT_DEADS.TaskName</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(ACT_ACCOUNT_DEADS)._Destructor">ACT_ACCOUNT_DEADS:_Destructor()</a></td>
|
||||
<td class="summary">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -683,19 +677,6 @@ Each successful dead will trigger an Account state transition that can be scored
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(ACT_ACCOUNT_DEADS)._Destructor" >
|
||||
<strong>ACT_ACCOUNT_DEADS:_Destructor()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
|
||||
@ -2216,6 +2216,9 @@ A #table or any field.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> THIS IS WHY WE NEED LUA 5.2 ...</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
|
||||
@ -2425,6 +2425,7 @@ The UNIT carrying the package.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<a id="#(AI_CARGO_UNIT).CargoCarrier" >
|
||||
<strong>AI_CARGO_UNIT.CargoCarrier</strong>
|
||||
</a>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -832,6 +832,12 @@ YYYY-MM-DD: CLASS:<strong>NewFunction( Params )</strong> added</p>
|
||||
<td class="name" nowrap="nowrap"><a href="##(FSM_PROCESS).New">FSM_PROCESS:New(Controllable, Task)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a new FSM_PROCESS object.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(FSM_PROCESS).Remove">FSM_PROCESS:Remove()</a></td>
|
||||
<td class="summary">
|
||||
<p>Removes an FSM_PROCESS object.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -2473,6 +2479,24 @@ self</p>
|
||||
<p><em><a href="##(FSM_PROCESS)">#FSM_PROCESS</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(FSM_PROCESS).Remove" >
|
||||
<strong>FSM_PROCESS:Remove()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Removes an FSM_PROCESS object.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em><a href="##(FSM_PROCESS)">#FSM_PROCESS</a>:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
|
||||
@ -262,7 +262,7 @@ Use the following Zone validation methods on the group:</p>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(GROUP).GetCategoryName">GROUP:GetCategoryName()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns the category name of the DCS Group.</p>
|
||||
<p>Returns the category name of the #GROUP.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -748,7 +748,7 @@ The category ID</p>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns the category name of the DCS Group.</p>
|
||||
<p>Returns the category name of the #GROUP.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
|
||||
@ -190,7 +190,6 @@ on defined intervals (currently every minute).</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em>#number</em>
|
||||
<a id="#(MOVEMENT).AliveUnits" >
|
||||
<strong>MOVEMENT.AliveUnits</strong>
|
||||
</a>
|
||||
@ -199,9 +198,6 @@ on defined intervals (currently every minute).</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> Contains the counter how many units are currently alive</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -342,7 +342,7 @@ Nothing of this code should be modified without testing it thoroughly.</p>
|
||||
|
||||
|
||||
|
||||
<p> setmetatable( {}, { __mode = "v" } )</p>
|
||||
<p> or {}</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
@ -1870,6 +1870,9 @@ The group that was spawned. You can use this group for further actions.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> Don't repeat the group from Take-Off till Landing and back Take-Off by ReSpawning.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@ -2323,6 +2326,9 @@ when nothing was spawned.</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<p> Overwrite unit names by default with group name.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@ -2710,7 +2716,7 @@ Spawn_BE_KA50 = SPAWN:New( 'BE KA-50@RAMP-Ground Defense' ):Schedule( 600, 0.5 )
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<em>#boolean</em>
|
||||
<a id="#(SPAWN).SpawnUnControlled" >
|
||||
<strong>SPAWN.SpawnUnControlled</strong>
|
||||
</a>
|
||||
|
||||
@ -297,12 +297,24 @@ Use the method <a href="##(TASK).AddScore">TASK.AddScore</a>() to add scores whe
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).IsAssignedToGroup">TASK:IsAssignedToGroup(TaskGroup)</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns if the <a href="Task.html">Task</a> is assigned to the Group.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).IsStateAborted">TASK:IsStateAborted()</a></td>
|
||||
<td class="summary">
|
||||
<p>Is the <a href="Task.html">Task</a> status <strong>Aborted</strong>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).IsStateAssigned">TASK:IsStateAssigned()</a></td>
|
||||
<td class="summary">
|
||||
<p>Is the <a href="Task.html">Task</a> status <strong>Assigned</strong>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).IsStateCancelled">TASK:IsStateCancelled()</a></td>
|
||||
<td class="summary">
|
||||
<p>Is the <a href="Task.html">Task</a> status <strong>Cancelled</strong>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -354,9 +366,9 @@ Use the method <a href="##(TASK).AddScore">TASK.AddScore</a>() to add scores whe
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).MenuTaskAbort">TASK.MenuTaskAbort(MenuParam)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).MenuTaskAbort">TASK:MenuTaskAbort(TaskGroup)</a></td>
|
||||
<td class="summary">
|
||||
|
||||
<p>Report the task status.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -537,12 +549,24 @@ Use the method <a href="##(TASK).AddScore">TASK.AddScore</a>() to add scores whe
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).SetUnitProcess">TASK:SetUnitProcess(Core, FsmTemplate)</a></td>
|
||||
<td class="summary">
|
||||
<p>Sets the Task FSM Process Template</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).StateAborted">TASK:StateAborted()</a></td>
|
||||
<td class="summary">
|
||||
<p>Sets a <a href="Task.html">Task</a> to status <strong>Aborted</strong>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).StateAssigned">TASK:StateAssigned()</a></td>
|
||||
<td class="summary">
|
||||
<p>Sets a <a href="Task.html">Task</a> to status <strong>Assigned</strong>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).StateCancelled">TASK:StateCancelled()</a></td>
|
||||
<td class="summary">
|
||||
<p>Sets a <a href="Task.html">Task</a> to status <strong>Cancelled</strong>.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -1299,6 +1323,19 @@ self</p>
|
||||
<p><em>#boolean:</em></p>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).IsStateAborted" >
|
||||
<strong>TASK:IsStateAborted()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Is the <a href="Task.html">Task</a> status <strong>Aborted</strong>.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
@ -1317,6 +1354,19 @@ self</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).IsStateCancelled" >
|
||||
<strong>TASK:IsStateCancelled()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Is the <a href="Task.html">Task</a> status <strong>Cancelled</strong>.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).IsStateFailed" >
|
||||
<strong>TASK:IsStateFailed()</strong>
|
||||
</a>
|
||||
@ -1456,18 +1506,18 @@ true if Unit is part of the Task.</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).MenuTaskAbort" >
|
||||
<strong>TASK.MenuTaskAbort(MenuParam)</strong>
|
||||
<strong>TASK:MenuTaskAbort(TaskGroup)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<p>Report the task status.</p>
|
||||
|
||||
<h3>Parameter</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em> MenuParam </em></code>: </p>
|
||||
<p><code><em> TaskGroup </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
@ -2143,6 +2193,19 @@ Fsm#FSM_PROCESS</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).StateAborted" >
|
||||
<strong>TASK:StateAborted()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Sets a <a href="Task.html">Task</a> to status <strong>Aborted</strong>.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).StateAssigned" >
|
||||
<strong>TASK:StateAssigned()</strong>
|
||||
</a>
|
||||
@ -2156,6 +2219,19 @@ Fsm#FSM_PROCESS</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).StateCancelled" >
|
||||
<strong>TASK:StateCancelled()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Sets a <a href="Task.html">Task</a> to status <strong>Cancelled</strong>.</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).StateFailed" >
|
||||
<strong>TASK:StateFailed()</strong>
|
||||
</a>
|
||||
|
||||
@ -153,13 +153,13 @@ Find a summary below describing for which situation a task type is created:</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).EvaluateBAI">TASK_A2G_DISPATCHER:EvaluateBAI(DetectedArea, FriendlyCoalition)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).EvaluateBAI">TASK_A2G_DISPATCHER:EvaluateBAI(DetectedItem, FriendlyCoalition)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a BAI task when there are targets for it.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).EvaluateCAS">TASK_A2G_DISPATCHER:EvaluateCAS(DetectedArea)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK_A2G_DISPATCHER).EvaluateCAS">TASK_A2G_DISPATCHER:EvaluateCAS(DetectedItem)</a></td>
|
||||
<td class="summary">
|
||||
<p>Creates a CAS task when there are targets for it.</p>
|
||||
</td>
|
||||
@ -270,7 +270,7 @@ Find a summary below describing for which situation a task type is created:</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK_A2G_DISPATCHER).EvaluateBAI" >
|
||||
<strong>TASK_A2G_DISPATCHER:EvaluateBAI(DetectedArea, FriendlyCoalition)</strong>
|
||||
<strong>TASK_A2G_DISPATCHER:EvaluateBAI(DetectedItem, FriendlyCoalition)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -281,7 +281,7 @@ Find a summary below describing for which situation a task type is created:</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Functional.Detection.html##(DETECTION_AREAS.DetectedArea)">Functional.Detection#DETECTION_AREAS.DetectedArea</a> DetectedArea </em></code>: </p>
|
||||
<p><code><em><a href="Functional.Detection.html##(DETECTION_AREAS.DetectedItem)">Functional.Detection#DETECTION_AREAS.DetectedItem</a> DetectedItem </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
@ -301,7 +301,7 @@ Find a summary below describing for which situation a task type is created:</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK_A2G_DISPATCHER).EvaluateCAS" >
|
||||
<strong>TASK_A2G_DISPATCHER:EvaluateCAS(DetectedArea)</strong>
|
||||
<strong>TASK_A2G_DISPATCHER:EvaluateCAS(DetectedItem)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -312,7 +312,7 @@ Find a summary below describing for which situation a task type is created:</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em><a href="Functional.Detection.html##(DETECTION_AREAS.DetectedArea)">Functional.Detection#DETECTION_AREAS.DetectedArea</a> DetectedArea </em></code>: </p>
|
||||
<p><code><em><a href="Functional.Detection.html##(DETECTION_AREAS.DetectedItem)">Functional.Detection#DETECTION_AREAS.DetectedItem</a> DetectedItem </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
@ -335,7 +335,7 @@ Find a summary below describing for which situation a task type is created:</p>
|
||||
<p>Evaluates the removal of the Task from the Mission.</p>
|
||||
|
||||
|
||||
<p>Can only occur when the DetectedArea is Changed AND the state of the Task is "Planned".</p>
|
||||
<p>Can only occur when the DetectedItem is Changed AND the state of the Task is "Planned".</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
|
||||
@ -214,6 +214,12 @@ If you want to obtain the complete <strong>3D position</strong> including ori<72>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetCallsign">UNIT:GetCallsign()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns the Unit's callsign - the localized string.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(UNIT).GetCategoryName">UNIT:GetCategoryName()</a></td>
|
||||
<td class="summary">
|
||||
<p>Returns the category name of the #UNIT.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -693,6 +699,24 @@ The DCS Unit is not existing or alive. </p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetCategoryName" >
|
||||
<strong>UNIT:GetCategoryName()</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>Returns the category name of the #UNIT.</p>
|
||||
|
||||
<h3>Return value</h3>
|
||||
|
||||
<p><em>#string:</em>
|
||||
Category name = Helicopter, Airplane, Ground Unit, Ship</p>
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(UNIT).GetDCSObject" >
|
||||
<strong>UNIT:GetDCSObject()</strong>
|
||||
</a>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user