Progress, got now task acceptance working

This commit is contained in:
FlightControl 2016-07-07 13:11:31 +02:00
parent bba6aa8fb6
commit c5cc069e46
18 changed files with 833 additions and 253 deletions

View File

@ -115,7 +115,6 @@ function BASE:New()
self.__index = self
_ClassID = _ClassID + 1
self.ClassID = _ClassID
self.ClassNameAndID = string.format( '%s#%09d', self.ClassName, self.ClassID )
return self
end
@ -152,7 +151,7 @@ end
-- @param #BASE self
-- @return #string The ClassName + ClassID of the class instance.
function BASE:GetClassNameAndID()
return self.ClassNameAndID
return string.format( '%s#%09d', self.ClassName, self.ClassID )
end
--- Get the ClassName of the class instance.

View File

@ -272,6 +272,19 @@ function EVENT:OnDeadForUnit( EventDCSUnitName, EventFunction, EventSelf )
return self
end
--- Set a new listener for an S_EVENT_PILOT_DEAD event.
-- @param #EVENT self
-- @param #function EventFunction The function to be called when the event occurs for the unit.
-- @param Base#BASE EventSelf
-- @return #EVENT
function EVENT:OnPilotDead( EventFunction, EventSelf )
self:F2()
self:OnEventGeneric( EventFunction, EventSelf, world.event.S_EVENT_PILOT_DEAD )
return self
end
--- Set a new listener for an S_EVENT_PILOT_DEAD event.
-- @param #EVENT self
-- @param #string EventDCSUnitName
@ -468,7 +481,6 @@ end
--- @param #EVENT self
-- @param #EVENTDATA Event
function EVENT:onEvent( Event )
self:F2( { _EVENTCODES[Event.id], Event } )
if self and self.Events and self.Events[Event.id] then
if Event.initiator and Event.initiator:getCategory() == Object.Category.UNIT then
@ -500,18 +512,23 @@ function EVENT:onEvent( Event )
Event.WeaponName = Event.Weapon:getTypeName()
--Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
end
self:E( { _EVENTCODES[Event.id], Event.IniUnitName, Event.TgtUnitName, Event.WeaponName } )
self:E( { _EVENTCODES[Event.id], Event } )
--self:E( { _EVENTCODES[Event.id], Event.IniUnitName, Event.TgtUnitName, Event.WeaponName } )
for ClassName, EventData in pairs( self.Events[Event.id] ) do
if Event.IniDCSUnitName and EventData.IniUnit and EventData.IniUnit[Event.IniDCSUnitName] then
self:E( { "Calling event function for class ", ClassName, " unit ", Event.IniDCSUnitName } )
EventData.IniUnit[Event.IniDCSUnitName].EventFunction( EventData.IniUnit[Event.IniDCSUnitName].EventSelf, Event )
else
if Event.IniDCSUnit and not EventData.IniUnit then
self:E( { "Calling event function for class ", ClassName } )
EventData.EventFunction( EventData.EventSelf, Event )
if ClassName == EventData.EventSelf:GetClassNameAndID() then
self:E( { "Calling event function for class ", ClassName } )
EventData.EventFunction( EventData.EventSelf, Event )
end
end
end
end
else
self:E( { _EVENTCODES[Event.id], Event } )
end
end

View File

@ -70,180 +70,362 @@ function SUBMENU:New( MenuText, ParentMenu )
return Child
end
-- This local variable is used to cache the menus registered under clients.
-- Menus don't dissapear when clients are destroyed and restarted.
-- So every menu for a client created must be tracked so that program logic accidentally does not create
-- the same menus twice during initialization logic.
-- These menu classes are handling this logic with this variable.
local _MENUCLIENTS = {}
do
--- The MENU_CLIENT class
-- @type MENU_CLIENT
-- @extends Menu#MENU
MENU_CLIENT = {
ClassName = "MENU_CLIENT"
}
--- Creates a new menu item for a group
-- @param self
-- @param Client#CLIENT MenuClient The Client owning the menu.
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu.
-- @return #MENU_CLIENT self
function MENU_CLIENT:New( MenuClient, MenuText, ParentMenu )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self:F( { MenuClient, MenuText, ParentMenu } )
self.MenuClient = MenuClient
self.MenuClientGroupID = MenuClient:GetClientGroupID()
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
-- This local variable is used to cache the menus registered under clients.
-- Menus don't dissapear when clients are destroyed and restarted.
-- So every menu for a client created must be tracked so that program logic accidentally does not create
-- the same menus twice during initialization logic.
-- These menu classes are handling this logic with this variable.
local _MENUCLIENTS = {}
self.Menus = {}
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
--- The MENU_CLIENT class
-- @type MENU_CLIENT
-- @extends Menu#MENU
MENU_CLIENT = {
ClassName = "MENU_CLIENT"
}
--- Creates a new menu item for a group
-- @param self
-- @param Client#CLIENT MenuClient The Client owning the menu.
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu.
-- @return #MENU_CLIENT self
function MENU_CLIENT:New( MenuClient, MenuText, ParentMenu )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self:F( { MenuClient, MenuText, ParentMenu } )
self.MenuClient = MenuClient
self.MenuClientGroupID = MenuClient:GetClientGroupID()
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self.Menus = {}
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } )
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
if MenuPath[MenuPathID] then
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
end
self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath )
MenuPath[MenuPathID] = self.MenuPath
self:T( { MenuClient:GetClientGroupName(), self.MenuPath } )
if ParentMenu and ParentMenu.Menus then
ParentMenu.Menus[self.MenuPath] = self
end
return self
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } )
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
if MenuPath[MenuPathID] then
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
--- Removes the sub menus recursively of this MENU_CLIENT.
-- @param #MENU_CLIENT self
-- @return #MENU_CLIENT self
function MENU_CLIENT:RemoveSubMenus()
self:F( self.MenuPath )
for MenuID, Menu in pairs( self.Menus ) do
Menu:Remove()
end
end
--- Removes the sub menus recursively of this MENU_CLIENT.
-- @param #MENU_CLIENT self
-- @return #MENU_CLIENT self
function MENU_CLIENT:Remove()
self:F( self.MenuPath )
self:RemoveSubMenus()
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
end
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end
--- The MENU_CLIENT_COMMAND class
-- @type MENU_CLIENT_COMMAND
-- @extends Menu#MENU
MENU_CLIENT_COMMAND = {
ClassName = "MENU_CLIENT_COMMAND"
}
--- Creates a new radio command item for a group
-- @param self
-- @param Client#CLIENT MenuClient The Client owning the menu.
-- @param MenuText The text for the menu.
-- @param ParentMenu The parent menu.
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
-- @param CommandMenuArgument An argument for the function.
-- @return Menu#MENU_CLIENT_COMMAND self
function MENU_CLIENT_COMMAND:New( MenuClient, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self.MenuClient = MenuClient
self.MenuClientGroupID = MenuClient:GetClientGroupID()
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, CommandMenuArgument } )
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
if MenuPath[MenuPathID] then
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
end
self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
MenuPath[MenuPathID] = self.MenuPath
self.CommandMenuFunction = CommandMenuFunction
self.CommandMenuArgument = CommandMenuArgument
ParentMenu.Menus[self.MenuPath] = self
return self
end
function MENU_CLIENT_COMMAND:Remove()
self:F( self.MenuPath )
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
end
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end
end
self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath )
MenuPath[MenuPathID] = self.MenuPath
--- MENU_GROUP
self:T( { MenuClient:GetClientGroupName(), self.MenuPath } )
do
-- This local variable is used to cache the menus registered under clients.
-- Menus don't dissapear when clients are destroyed and restarted.
-- So every menu for a client created must be tracked so that program logic accidentally does not create
-- the same menus twice during initialization logic.
-- These menu classes are handling this logic with this variable.
local _MENUGROUPS = {}
if ParentMenu and ParentMenu.Menus then
--- The MENU_GROUP class
-- @type MENU_GROUP
-- @extends Menu#MENU
MENU_GROUP = {
ClassName = "MENU_GROUP"
}
--- Creates a new menu item for a group
-- @param self
-- @param Group#GROUP MenuGroup The Group owning the menu.
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu.
-- @return #MENU_GROUP self
function MENU_GROUP:New( MenuGroup, MenuText, ParentMenu )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self:F( { MenuGroup, MenuText, ParentMenu } )
self.MenuGroup = MenuGroup
self.MenuGroupID = MenuGroup:GetID()
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self.Menus = {}
if not _MENUGROUPS[self.MenuGroupID] then
_MENUGROUPS[self.MenuGroupID] = {}
end
local MenuPath = _MENUGROUPS[self.MenuGroupID]
self:T( { MenuGroup:GetName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } )
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
if MenuPath[MenuPathID] then
missionCommands.removeItemForGroup( self.MenuGroupID, MenuPath[MenuPathID] )
end
self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuGroupID, MenuText, MenuParentPath )
MenuPath[MenuPathID] = self.MenuPath
self:T( { self.MenuGroupID, self.MenuPath } )
if ParentMenu and ParentMenu.Menus then
ParentMenu.Menus[self.MenuPath] = self
end
return self
end
--- Removes the sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP self
-- @return #MENU_GROUP self
function MENU_GROUP:RemoveSubMenus()
self:F( self.MenuPath )
for MenuID, Menu in pairs( self.Menus ) do
Menu:Remove()
end
end
--- Removes the sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP self
-- @return #MENU_GROUP self
function MENU_GROUP:Remove()
self:F( self.MenuPath )
self:RemoveSubMenus()
if not _MENUGROUPS[self.MenuGroupID] then
_MENUGROUPS[self.MenuGroupID] = {}
end
local MenuPath = _MENUGROUPS[self.MenuGroupID]
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
end
missionCommands.removeItemForGroup( self.MenuGroupID, self.MenuPath )
if self.ParentMenu then
self.ParentMenu.Menus[self.MenuPath] = nil
end
return nil
end
--- The MENU_GROUP_COMMAND class
-- @type MENU_GROUP_COMMAND
-- @extends Menu#MENU
MENU_GROUP_COMMAND = {
ClassName = "MENU_GROUP_COMMAND"
}
--- Creates a new radio command item for a group
-- @param #MENU_GROUP_COMMAND self
-- @param Group#GROUP MenuGroup The Group owning the menu.
-- @param MenuText The text for the menu.
-- @param ParentMenu The parent menu.
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
-- @param CommandMenuArgument An argument for the function.
-- @return Menu#MENU_GROUP_COMMAND self
function MENU_GROUP_COMMAND:New( MenuGroup, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self.MenuGroup = MenuGroup
self.MenuGroupID = MenuGroup:GetID()
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
if not _MENUGROUPS[self.MenuGroupID] then
_MENUGROUPS[self.MenuGroupID] = {}
end
local MenuPath = _MENUGROUPS[self.MenuGroupID]
self:T( { MenuGroup:GetName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, CommandMenuArgument } )
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
if MenuPath[MenuPathID] then
missionCommands.removeItemForGroup( self.MenuGroupID, MenuPath[MenuPathID] )
end
self.MenuPath = missionCommands.addCommandForGroup( self.MenuGroupID, MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
MenuPath[MenuPathID] = self.MenuPath
self.CommandMenuFunction = CommandMenuFunction
self.CommandMenuArgument = CommandMenuArgument
ParentMenu.Menus[self.MenuPath] = self
return self
end
return self
end
--- Removes the sub menus recursively of this MENU_CLIENT.
-- @param #MENU_CLIENT self
-- @return #MENU_CLIENT self
function MENU_CLIENT:RemoveSubMenus()
self:F( self.MenuPath )
for MenuID, Menu in pairs( self.Menus ) do
Menu:Remove()
function MENU_GROUP_COMMAND:Remove()
self:F( self.MenuPath )
if not _MENUGROUPS[self.MenuGroupID] then
_MENUGROUPS[self.MenuGroupID] = {}
end
local MenuPath = _MENUGROUPS[self.MenuGroupID]
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
end
missionCommands.removeItemForGroup( self.MenuGroupID, self.MenuPath )
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end
end
--- Removes the sub menus recursively of this MENU_CLIENT.
-- @param #MENU_CLIENT self
-- @return #MENU_CLIENT self
function MENU_CLIENT:Remove()
self:F( self.MenuPath )
self:RemoveSubMenus()
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
end
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end
--- The MENU_CLIENT_COMMAND class
-- @type MENU_CLIENT_COMMAND
-- @extends Menu#MENU
MENU_CLIENT_COMMAND = {
ClassName = "MENU_CLIENT_COMMAND"
}
--- Creates a new radio command item for a group
-- @param self
-- @param Client#CLIENT MenuClient The Client owning the menu.
-- @param MenuText The text for the menu.
-- @param ParentMenu The parent menu.
-- @param CommandMenuFunction A function that is called when the menu key is pressed.
-- @param CommandMenuArgument An argument for the function.
-- @return Menu#MENU_CLIENT_COMMAND self
function MENU_CLIENT_COMMAND:New( MenuClient, MenuText, ParentMenu, CommandMenuFunction, CommandMenuArgument )
-- Arrange meta tables
local MenuParentPath = {}
if ParentMenu ~= nil then
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, MENU:New( MenuText, MenuParentPath ) )
self.MenuClient = MenuClient
self.MenuClientGroupID = MenuClient:GetClientGroupID()
self.MenuParentPath = MenuParentPath
self.MenuText = MenuText
self.ParentMenu = ParentMenu
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, CommandMenuArgument } )
local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText
if MenuPath[MenuPathID] then
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] )
end
self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument )
MenuPath[MenuPathID] = self.MenuPath
self.CommandMenuFunction = CommandMenuFunction
self.CommandMenuArgument = CommandMenuArgument
ParentMenu.Menus[self.MenuPath] = self
return self
end
function MENU_CLIENT_COMMAND:Remove()
self:F( self.MenuPath )
if not _MENUCLIENTS[self.MenuClientGroupID] then
_MENUCLIENTS[self.MenuClientGroupID] = {}
end
local MenuPath = _MENUCLIENTS[self.MenuClientGroupID]
if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then
MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil
end
missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath )
self.ParentMenu.Menus[self.MenuPath] = nil
return nil
end
--- The MENU_COALITION class
-- @type MENU_COALITION
-- @extends Menu#MENU

View File

@ -44,7 +44,7 @@ end
-- @param #string MissionName is the name of the mission. This name will be used to reference the status of each mission by the players.
-- @param #string MissionPriority is a string indicating the "priority" of the Mission. f.e. "Primary", "Secondary" or "First", "Second". It is free format and up to the Mission designer to choose. There are no rules behind this field.
-- @param #string MissionBriefing is a string indicating the mission briefing to be shown when a player joins a @{CLIENT}.
-- @param #string MissionCoalition is a string indicating the coalition or party to which this mission belongs to. It is free format and can be chosen freely by the mission designer. Note that this field is not to be confused with the coalition concept of the ME. Examples of a Mission Coalition could be "NATO", "CCCP", "Intruders", "Terrorists"...
-- @param DCSCoalitionObject#coalition DCSCoalition is a string indicating the coalition or party to which this mission belongs to. It is free format and can be chosen freely by the mission designer. Note that this field is not to be confused with the coalition concept of the ME. Examples of a Mission Coalition could be "NATO", "CCCP", "Intruders", "Terrorists"...
-- @return #MISSION self
-- @usage
-- -- Declare a few missions.
@ -56,15 +56,15 @@ end
-- local Mission = MISSIONSCHEDULER.AddMission( 'SA-6 SAMs', 'Primary', 'Our intelligence reports that 3 SA-6 SAM defense batteries are located near Didmukha, Khetagurov and Berula. Eliminate the Russian SAMs.', 'NATO' )
-- local Mission = MISSIONSCHEDULER.AddMission( 'NATO Sling Load', 'Operational', 'Fly to the cargo pickup zone at Dzegvi or Kaspi, and sling the cargo to Soganlug airbase.', 'NATO' )
-- local Mission = MISSIONSCHEDULER.AddMission( 'Rescue secret agent', 'Tactical', 'In order to be in full control of the situation, we need you to rescue a secret agent from the woods behind enemy lines. Avoid the Russian defenses and rescue the agent. Keep south until Khasuri, and keep your eyes open for any SAM presence. The agent is located at waypoint 4 on your kneeboard.', 'NATO' )
function MISSION:New( MissionName, MissionPriority, MissionBriefing, MissionCoalition )
function MISSION:New( MissionName, MissionPriority, MissionBriefing, DCSCoalition )
self = MISSION:Meta()
self:T({ MissionName, MissionPriority, MissionBriefing, MissionCoalition })
self:T( { MissionName, MissionPriority, MissionBriefing, DCSCoalition } )
self.Name = MissionName
self.MissionPriority = MissionPriority
self.MissionBriefing = MissionBriefing
self.MissionCoalition = MissionCoalition
self.DCSCoalition = DCSCoalition
self:SetMissionMenu()
@ -97,7 +97,7 @@ end
-- @param #MISSION self
-- @return #MISSION self
function MISSION:SetMissionMenu()
self.MissionMenu = MENU_COALITION:New( self.MissionCoalition, self.Name )
self.MissionMenu = MENU_COALITION:New( self.DCSCoalition, self.Name )
end
--- Gets the mission menu for the coalition.

View File

@ -48,15 +48,16 @@ Include.File( "Detection" )
Include.File( "FAC" )
Include.File( "StateMachine" )
Include.File( "Process" )
Include.File( "Process_SEAD" )
Include.File( "Process_Assign" )
Include.File( "Process_Route" )
Include.File( "Process_SEAD" )
Include.File( "Task" )
Include.File( "Task_SEAD" )
-- The order of the declarations is important here. Don't touch it.
--- Declare the event dispatcher based on the EVENT class
_EVENTDISPATCHER = EVENT:New() -- #EVENT
_EVENTDISPATCHER = EVENT:New() -- Event#EVENT
--- Declare the main database object, which is used internally by the MOOSE classes.
_DATABASE = DATABASE:New() -- Database#DATABASE

View File

@ -4,7 +4,7 @@
-- @type PROCESS
-- @field Scheduler#SCHEDULER ProcessScheduler
-- @field Unit#UNIT ProcessUnit
-- @field Task#MISSION Task
-- @field Task#TASK Task
-- @field StateMachine#STATEMACHINE_TASK Fsm
-- @extends Base#BASE
PROCESS = {
@ -25,14 +25,28 @@ function PROCESS:New( Task, ProcessUnit )
self.ProcessUnit = ProcessUnit
self.Task = Task
self.AllowEvents = true
return self
end
--- @param #PROCESS self
function PROCESS:NextEvent( NextEvent, ... )
self:E( NextEvent )
self:F2( arg )
if self.AllowEvents == true then
self.ProcessScheduler = SCHEDULER:New( self.Fsm, NextEvent, { self, self.ProcessUnit, unpack( arg ) }, 1 )
end
end
self.ProcessScheduler = SCHEDULER:New( self.Fsm, NextEvent, { self, self.ProcessUnit, unpack( arg ) }, 1 )
--- @param #PROCESS self
function PROCESS:StopEvents( )
self:F2()
if self.ProcessScheduler then
self:E( "Stop" )
self.ProcessScheduler:Stop()
self.ProcessScheduler = nil
self.AllowEvents = false
end
end
--- Adds a score for the PROCESS to be achieved.
@ -60,10 +74,11 @@ function PROCESS:OnStateChange( Fsm, Event, From, To )
self:E( { Event, From, To, self.ProcessUnit.UnitName } )
if self.Scores[To] then
self.Unit:Message( "Score:" .. self.Scores[To].ScoreText .. " " .. To , 15 )
MESSAGE:New( "Score:" .. self.Scores[To].ScoreText .. " " .. To , 15 ):ToGroup( self.ProcessUnit:GetGroup() )
local Scoring = self.Task:GetScoring()
if Scoring then
Scoring:_AddTaskProcessScore( self.ProcessUnit, self.Task:GetName(), self.Scores[To].Score )
Scoring:_AddMissionTaskScore( self.Task.Mission, self.ProcessUnit, self.Scores[To].ScoreText, self.Scores[To].Score )
end
end
end

View File

@ -0,0 +1,105 @@
--- @module Task_Assign
--- PROCESS_ASSIGN class
-- @type PROCESS_ASSIGN
-- @field Task#TASK_BASE Task
-- @field Unit#UNIT ProcessUnit
-- @field Zone#ZONE_BASE TargetZone
-- @extends Task2#TASK2
PROCESS_ASSIGN = {
ClassName = "PROCESS_ASSIGN",
}
--- Creates a new task assignment state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator.
-- @param #PROCESS_ASSIGN self
-- @param Task#TASK Task
-- @param Unit#UNIT Unit
-- @return #PROCESS_ASSIGN self
function PROCESS_ASSIGN:New( Task, ProcessUnit, TaskBriefing )
-- Inherits from BASE
local self = BASE:Inherit( self, PROCESS:New( Task, ProcessUnit ) ) -- #PROCESS_ASSIGN
self.TaskBriefing = TaskBriefing
self.Fsm = STATEMACHINE_PROCESS:New( self, {
initial = 'UnAssigned',
events = {
{ name = 'Menu', from = 'UnAssigned', to = 'AwaitAccept' },
{ name = 'Assign', from = 'AwaitAccept', to = 'Assigned' },
{ name = 'Reject', from = 'AwaitAccept', to = 'Rejected' },
{ name = 'Fail', from = 'AwaitAccept', to = 'Rejected' },
},
callbacks = {
onMenu = self.OnMenu,
onAssign = self.OnAssign,
onReject = self.OnReject,
},
endstates = {
'Assigned', 'Rejected'
},
} )
return self
end
--- StateMachine callback function for a TASK2
-- @param #PROCESS_ASSIGN self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
function PROCESS_ASSIGN:OnMenu( Fsm, Event, From, To )
self:E( { Event, From, To, self.ProcessUnit.UnitName} )
MESSAGE:New( self.TaskBriefing .. "\nAccess the radio menu to accept the task. You have 30 seconds or the assignment will be cancelled.", 30, "Assignment" ):ToGroup( self.ProcessUnit:GetGroup() )
self.MenuText = self.Task.TaskName
local ProcessGroup = self.ProcessUnit:GetGroup()
self.Menu = MENU_GROUP:New( ProcessGroup, "Task " .. self.MenuText .. " acceptance" )
self.MenuAcceptTask = MENU_GROUP_COMMAND:New( ProcessGroup, "Accept task " .. self.MenuText, self.Menu, self.MenuAssign, self )
self.MenuRejectTask = MENU_GROUP_COMMAND:New( ProcessGroup, "Reject task " .. self.MenuText, self.Menu, self.MenuReject, self )
end
--- Menu function.
-- @param #PROCESS_ASSIGN self
function PROCESS_ASSIGN:MenuAssign()
self:E( )
self:NextEvent( self.Fsm.Assign )
end
--- Menu function.
-- @param #PROCESS_ASSIGN self
function PROCESS_ASSIGN:MenuReject()
self:E( )
self:NextEvent( self.Fsm.Reject )
end
--- StateMachine callback function for a TASK2
-- @param #PROCESS_ASSIGN self
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
function PROCESS_ASSIGN:OnAssign( Fsm, Event, From, To )
self:E( { Event, From, To, self.ProcessUnit.UnitName} )
self.Menu:Remove()
end
--- StateMachine callback function for a TASK2
-- @param #PROCESS_ASSIGN self
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
function PROCESS_ASSIGN:OnReject( Fsm, Event, From, To )
self:E( { Event, From, To, self.ProcessUnit.UnitName} )
self.Menu:Remove()
self.Task:UnAssignFromUnit( self.ProcessUnit )
self.ProcessUnit:Destroy()
end

View File

@ -1,9 +1,9 @@
--- @module Task_Route
--- TASK2_ROUTE_CLIENT class
-- @type TASK2_ROUTE_CLIENT
-- @field Mission#MISSION Mission
-- @field Unit#UNIT TaskUnit
--- PROCESS_ROUTE class
-- @type PROCESS_ROUTE
-- @field Task#TASK TASK
-- @field Unit#UNIT ProcessUnit
-- @field Zone#ZONE_BASE TargetZone
-- @extends Task2#TASK2
PROCESS_ROUTE = {
@ -12,14 +12,14 @@ PROCESS_ROUTE = {
--- Creates a new routing state machine. The task will route a CLIENT to a ZONE until the CLIENT is within that ZONE.
-- @param #TASK2_ROUTE_CLIENT self
-- @param Mission#MISSION Mission
-- @param #PROCESS_ROUTE self
-- @param Task#TASK Task
-- @param Unit#UNIT Unit
-- @return #TASK2_ROUTE_CLIENT self
function PROCESS_ROUTE:New( Mission, TaskUnit, TargetZone )
-- @return #PROCESS_ROUTE self
function PROCESS_ROUTE:New( Task, ProcessUnit, TargetZone )
-- Inherits from BASE
local self = BASE:Inherit( self, TASK2:New( Mission, TaskUnit ) ) -- #TASK2_ROUTE_CLIENT
local self = BASE:Inherit( self, PROCESS:New( Task, ProcessUnit ) ) -- #PROCESS_ROUTE
self.TargetZone = TargetZone
self.DisplayInterval = 30
@ -28,7 +28,7 @@ function PROCESS_ROUTE:New( Mission, TaskUnit, TargetZone )
self.DisplayTime = 10 -- 10 seconds is the default
self.DisplayCategory = "Route" -- Route is the default display category
self.Fsm = STATEMACHINE_TASK:New( self, {
self.Fsm = STATEMACHINE_PROCESS:New( self, {
initial = 'UnArrived',
events = {
{ name = 'Route', from = 'UnArrived', to = 'Arrived' },
@ -49,24 +49,23 @@ end
--- Task Events
--- StateMachine callback function for a TASK2
-- @param #TASK2_ROUTE_CLIENT self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param #PROCESS_ROUTE self
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
function PROCESS_ROUTE:OnLeaveUnArrived( Fsm, Event, From, To )
self:E( { Event, From, To, self.TaskUnit.UnitName } )
local IsInZone = self.TaskUnit:IsInZone( self.TargetZone )
local IsInZone = self.ProcessUnit:IsInZone( self.TargetZone )
if self.DisplayCount >= self.DisplayInterval then
if not IsInZone then
local ZoneVec2 = self.TargetZone:GetVec2()
local ZonePointVec2 = POINT_VEC2:New( ZoneVec2.x, ZoneVec2.y )
local TaskUnitVec2 = self.TaskUnit:GetVec2()
local TaskUnitVec2 = self.ProcessUnit:GetVec2()
local TaskUnitPointVec2 = POINT_VEC2:New( TaskUnitVec2.x, TaskUnitVec2.y )
local RouteText = TaskUnitPointVec2:GetBRText( ZonePointVec2 )
self.TaskUnit:Message( RouteText, self.DisplayTime, self.DisplayCategory )
MESSAGE:New( RouteText, self.DisplayTime, self.DisplayCategory ):ToGroup( self.ProcessUnit:GetGroup() )
end
self.DisplayCount = 1
else

View File

@ -3,38 +3,38 @@
--- PROCESS_SEAD class
-- @type PROCESS_SEAD
-- @field Unit#UNIT ProcessUnit
-- @field Set#SET_UNIT TargetSet
-- @field Set#SET_UNIT TargetSetUnit
-- @extends Process#PROCESS
PROCESS_SEAD = {
ClassName = "PROCESS_SEAD",
Fsm = {},
TargetSet = nil,
TargetSetUnit = nil,
}
--- Creates a new SEAD task.
-- @param #PROCESS_SEAD self
-- @param Task#MISSION Task
-- @param Task#TASK Task
-- @param Unit#UNIT ProcessUnit
-- @param Set#SET_UNIT TargetSet
-- @param Set#SET_UNIT TargetSetUnit
-- @return #PROCESS_SEAD self
function PROCESS_SEAD:New( Task, ProcessUnit, TargetSet )
function PROCESS_SEAD:New( Task, ProcessUnit, TargetSetUnit )
-- Inherits from BASE
local self = BASE:Inherit( self, PROCESS:New( Task, ProcessUnit ) ) -- #PROCESS_SEAD
self.TargetSet = TargetSet
self.TargetSetUnit = TargetSetUnit
self.Fsm = STATEMACHINE_TASK:New( self, {
self.Fsm = STATEMACHINE_PROCESS:New( self, {
initial = 'Assigned',
events = {
{ name = 'Await', from = 'Assigned', to = 'Waiting' },
{ name = 'HitTarget', from = 'Waiting', to = 'Destroy' },
{ name = 'MoreTargets', from = 'Destroy', to = 'Waiting' },
{ name = 'Destroyed', from = 'Destroy', to = 'Success' },
{ name = 'Killed', from = 'Assigned', to = 'Failed' },
{ name = 'Killed', from = 'Waiting', to = 'Failed' },
{ name = 'Killed', from = 'Destroy', to = 'Failed' },
{ name = 'Fail', from = 'Assigned', to = 'Failed' },
{ name = 'Fail', from = 'Waiting', to = 'Failed' },
{ name = 'Fail', from = 'Destroy', to = 'Failed' },
},
callbacks = {
onAwait = self.OnAwait,
@ -48,8 +48,6 @@ function PROCESS_SEAD:New( Task, ProcessUnit, TargetSet )
_EVENTDISPATCHER:OnHit( self.EventHit, self )
_EVENTDISPATCHER:OnDead( self.EventKilled, self )
_EVENTDISPATCHER:OnCrash( self.EventKilled, self )
return self
end
@ -58,28 +56,26 @@ end
--- StateMachine callback function for a PROCESS
-- @param #PROCESS_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
function PROCESS_SEAD:OnAwait( Fsm, Event, From, To )
self:E( { Event, From, To, self.ProcessUnit.UnitName} )
self.ProcessUnit:Message( "Waiting", 15 )
self:NextEvent( Fsm.Await )
end
--- StateMachine callback function for a PROCESS
-- @param #PROCESS_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Event#EVENTDATA Event
function PROCESS_SEAD:OnHitTarget( Fsm, Event, From, To, Event )
self.ProcessUnit:Message( "Hit Target", 15 )
if self.TargetSet:Count() > 0 then
if self.TargetSetUnit:Count() > 0 then
self:NextEvent( Fsm.MoreTargets )
else
self:NextEvent( Fsm.Destroyed )
@ -88,46 +84,43 @@ end
--- StateMachine callback function for a PROCESS
-- @param #PROCESS_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
function PROCESS_SEAD:OnMoreTargets( Fsm, Event, From, To )
self.ProcessUnit:Message( "More Targets", 15 )
end
--- StateMachine callback function for a PROCESS
-- @param #PROCESS_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Event#EVENTDATA DCSEvent
function PROCESS_SEAD:OnKilled( Fsm, Event, From, To )
self.ProcessUnit:Message( "Player got killed", 15 )
self:NextEvent( Fsm.Restart )
end
--- StateMachine callback function for a PROCESS
-- @param #PROCESS_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
function PROCESS_SEAD:OnRestart( Fsm, Event, From, To )
self.ProcessUnit:Message( "Restart SEAD Process", 15 )
self:NextEvent( Fsm.Menu )
end
--- StateMachine callback function for a PROCESS
-- @param #PROCESS_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param StateMachine#STATEMACHINE_PROCESS Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
@ -148,14 +141,4 @@ function PROCESS_SEAD:EventHit( Event )
end
end
--- @param #PROCESS_SEAD self
-- @param Event#EVENTDATA Event
function PROCESS_SEAD:EventKilled( Event )
if Event.IniUnit then
if Event.IniUnitName == self.ProcessUnit.UnitName then
self:NextEvent( self.Fsm.Killed, Event )
end
end
end

View File

@ -95,6 +95,7 @@ function SCHEDULER:Stop()
self.Repeat = false
if self.ScheduleID then
self:E( "Stop Schedule" )
timer.removeFunction( self.ScheduleID )
end
self.ScheduleID = nil

View File

@ -263,13 +263,16 @@ end
--- Registers Scores the players completing a Mission Task.
-- @param #SCORING self
-- @param Mission#MISSION Mission
-- @param Unit#UNIT PlayerUnit
-- @param #string MissionName
-- @param #string Text
-- @param #number Score
function SCORING:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
self:F( { PlayerUnit.UnitName, MissionName, Score } )
function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score )
local PlayerName = PlayerUnit:GetPlayerName()
local MissionName = Mission:GetName()
self:F( { Mission:GetName(), PlayerUnit.UnitName, PlayerName, Text, Score } )
if not self.Players[PlayerName].Mission[MissionName] then
self.Players[PlayerName].Mission[MissionName] = {}
@ -283,9 +286,9 @@ function SCORING:_AddMissionTaskScore( PlayerUnit, MissionName, Score )
self.Players[PlayerName].Score = self.Players[PlayerName].Score + Score
self.Players[PlayerName].Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
MESSAGE:New( "Player '" .. PlayerName .. "' has finished another Task in Mission '" .. MissionName .. "'. " ..
Score .. " Score points added.",
20 ):ToAll()
MESSAGE:New( "Player '" .. PlayerName .. "' has " .. Text .. " in Mission '" .. MissionName .. "'. " ..
Score .. " points!",
30 ):ToAll()
self:ScoreCSV( PlayerName, "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:GetName() )
end

View File

@ -113,6 +113,8 @@ function STATEMACHINE:_create_transition(name)
local fsmparent, event = self:_isendstate( to )
if fsmparent and event then
self:_call_handler(self["onenter" .. to] or self["on" .. to], params)
self:_call_handler(self["onafter" .. name] or self["on" .. name], params)
self:_call_handler(self["onstatechange"], params)
fsmparent[event]( fsmparent )
execute = false
@ -146,11 +148,13 @@ function STATEMACHINE:_isendstate( state )
self:E( { state = state, endstates = self.endstates, endstate = self.endstates[state] } )
local returnevent = nil
local fromstate = fsmparent.current
self:E( fromstate )
self:E( self.returnevents )
for _, eventname in pairs( self.returnevents ) do
local event = fsmparent.events[eventname]
self:E( event )
local to = event and event.map[fromstate] or event.map['*']
if to then
if to and to == state then
return fsmparent, eventname
end
end
@ -232,3 +236,34 @@ function STATEMACHINE_PROCESS:_call_handler( handler, params )
return handler( self.Process, unpack( params ) )
end
end
--- STATEMACHINE_TASK class
-- @type STATEMACHINE_TASK
-- @field Task#TASK_BASE Task
-- @extends StateMachine#STATEMACHINE
STATEMACHINE_TASK = {
ClassName = "STATEMACHINE_TASK",
}
--- Creates a new STATEMACHINE_TASK object.
-- @param #STATEMACHINE_TASK self
-- @return #STATEMACHINE_TASK
function STATEMACHINE_TASK:New( Task, options )
local FsmTask = routines.utils.deepCopy( self ) -- Create a new self instance
local Parent = STATEMACHINE:New(options)
setmetatable( FsmTask, Parent )
FsmTask.__index = FsmTask
FsmTask["onstatechange"] = Task.OnStateChange
FsmTask.Task = Task
return FsmTask
end
function STATEMACHINE_TASK:_call_handler( handler, params )
if handler then
return handler( self.Task, unpack( params ) )
end
end

View File

@ -10,18 +10,22 @@ TASK_BASE = {
ClassName = "TASK_BASE",
TaskScheduler = nil,
Processes = {},
Players = nil,
Scores = {},
}
--- Instantiates a new TASK_BASE. Should never be used. Interface Class.
-- @param #TASK_BASE self
-- @return #TASK_BASE self
function TASK_BASE:New()
function TASK_BASE:New( Mission, TaskName )
local self = BASE:Inherit( self, BASE:New() )
self:F()
self.Processes = {}
self.Fsm = {}
self.Mission = Mission
self.TaskName = TaskName
self.TaskBriefing = "You are assigned to the task: " .. self.TaskName .. "."
return self
end
@ -31,7 +35,7 @@ end
-- @param Group#GROUP TaskGroup
-- @return #TASK_BASE self
function TASK_BASE:AssignToGroup( TaskGroup )
self:FZ( TaskGroup:GetName() )
self:F2( TaskGroup:GetName() )
local TaskUnits = TaskGroup:GetUnits()
for UnitID, UnitData in pairs( TaskUnits ) do
@ -44,6 +48,8 @@ function TASK_BASE:AssignToGroup( TaskGroup )
return self
end
--- Add Process to @{Task} with key @{Unit}
-- @param #TASK_BASE self
-- @param Unit#UNIT TaskUnit
@ -58,11 +64,19 @@ end
--- Remove Processes from @{Task} with key @{Unit}
-- @param #TASK_BASE self
-- @return #TASK_BASE self
function TASK_BASE:RemoveProcesses( TaskUnit )
function TASK_BASE:RemoveProcesses( TaskUnit, FailProcesses )
local TaskUnitName = TaskUnit:GetName()
for _, Process in pairs( self.Processes[TaskUnitName] ) do
for _, ProcessData in pairs( self.Processes[TaskUnitName] ) do
local Process = ProcessData -- Process#PROCESS
if FailProcesses then
Process.Fsm:Fail()
end
Process:StopEvents()
Process = nil
self.Processes[TaskUnitName][_] = nil
self:E( self.Processes[TaskUnitName][_] )
end
self.Processes[TaskUnitName] = nil
end
--- Add a FiniteStateMachine to @{Task} with key @{Unit}
@ -83,7 +97,20 @@ function TASK_BASE:RemoveStateMachines( TaskUnit )
local TaskUnitName = TaskUnit:GetName()
for _, Fsm in pairs( self.Fsm[TaskUnitName] ) do
Fsm = nil
self.Fsm[TaskUnitName][_] = nil
self:E( self.Fsm[TaskUnitName][_] )
end
self.Fsm[TaskUnitName] = nil
end
--- Checks if there is a FiniteStateMachine assigned to @{Unit} for @{Task}
-- @param #TASK_BASE self
-- @param Unit#UNIT TaskUnit
-- @return #TASK_BASE self
function TASK_BASE:HasStateMachine( TaskUnit )
local TaskUnitName = TaskUnit:GetName()
self:F( { TaskUnitName, self.Fsm[TaskUnitName] ~= nil } )
return ( self.Fsm[TaskUnitName] ~= nil )
end
@ -94,10 +121,173 @@ end
-- @param Unit#UNIT TaskUnit
-- @return #TASK_BASE self
function TASK_BASE:AssignToUnit( TaskUnit )
self:F( TaskUnit:GetName() )
return nil
end
--- UnAssign the @{Task} from an alive @{Unit}.
-- @param #TASK_BASE self
-- @param Unit#UNIT TaskUnit
-- @return #TASK_BASE self
function TASK_BASE:UnAssignFromUnit( TaskUnit, FailProcesses )
self:F( TaskUnit:GetName() )
if self:HasStateMachine( TaskUnit ) == true then
self:RemoveStateMachines( TaskUnit )
self:RemoveProcesses( TaskUnit, FailProcesses )
end
return self
end
--- Register a potential new assignment for a new spawned @{Unit}.
-- Tasks only get assigned if there are players in it.
-- @param #TASK_BASE self
-- @param Event#EVENTDATA Event
-- @return #TASK_BASE self
function TASK_BASE:_EventAssignUnit( Event )
if Event.IniUnit then
self:F( Event )
local TaskUnit = Event.IniUnit
if TaskUnit:IsAlive() then
local TaskPlayerName = TaskUnit:GetPlayerName()
if TaskPlayerName ~= nil then
if not self:HasStateMachine( TaskUnit ) then
self:AssignToUnit( TaskUnit )
end
end
end
end
return nil
end
--- UnAssigns a @{Unit} that is left by a player, crashed, dead, ....
-- There are only assignments if there are players in it.
-- @param #TASK_BASE self
-- @param Event#EVENTDATA Event
-- @return #TASK_BASE self
function TASK_BASE:_EventUnAssignUnit( Event )
self:F( Event )
if Event.IniUnit then
local TaskUnit = Event.IniUnit
self:F( TaskUnit:GetName() )
self:UnAssignFromUnit( TaskUnit, true )
end
return nil
end
--- Gets the scoring of the task
-- @param #TASK_BASE self
-- @return Scoring#SCORING Scoring
function TASK_BASE:GetScoring()
return self.Mission:GetScoring()
end
--- Sets the name of the task
-- @param #TASK_BASE self
-- @param #string TaskName
-- @return Scoring#SCORING Scoring
function TASK_BASE:SetName( TaskName )
self.TaskName = TaskName
end
--- Gets the name of the task
-- @param #TASK_BASE self
-- @return Scoring#SCORING Scoring
function TASK_BASE:GetName()
return self.TaskName
end
--- Sets a @{Task} to status **Success**.
-- @param #TASK_BASE self
function TASK_BASE:StateSuccess()
self:SetState( self, "State", "Success" )
end
--- Is the @{Task} status **Success**.
-- @param #TASK_BASE self
function TASK_BASE:IsStateSuccess()
return self:GetStateString() == "Success"
end
--- Sets a @{Task} to status **Failed**.
-- @param #TASK_BASE self
function TASK_BASE:StateFailed()
self:SetState( self, "State", "Failed" )
end
--- Is the @{Task} status **Failed**.
-- @param #TASK_BASE self
function TASK_BASE:IsStateFailed()
return self:GetStateString() == "Failed"
end
--- Sets a @{Task} to status **Planned**.
-- @param #TASK_BASE self
function TASK_BASE:StatePlanned()
self:SetState( self, "State", "Planned" )
end
--- Is the @{Task} status **Planned**.
-- @param #TASK_BASE self
function TASK_BASE:IsStatePlanned()
return self:GetStateString() == "Planned"
end
--- Sets a @{Task} to status **Assigned**.
-- @param #TASK_BASE self
function TASK_BASE:StateAssigned()
self:SetState( self, "State", "Assigned" )
end
--- Is the @{Task} status **Assigned**.
-- @param #TASK_BASE self
function TASK_BASE:IsStateAssigned()
return self:GetStateString() == "Assigned"
end
--- Sets a @{Task} to status **Hold**.
-- @param #TASK_BASE self
function TASK_BASE:StateHold()
self:SetState( self, "State", "Hold" )
end
--- Is the @{Task} status **Hold**.
-- @param #TASK_BASE self
function TASK_BASE:IsStateHold()
return self:GetStateString() == "Hold"
end
--- Sets a @{Task} to status **Replanned**.
-- @param #TASK_BASE self
function TASK_BASE:StateReplanned()
self:SetState( self, "State", "Replanned" )
end
--- Is the @{Task} status **Replanned**.
-- @param #TASK_BASE self
function TASK_BASE:IsStateReplanned()
return self:GetStateString() == "Replanned"
end
--- Gets the @{Task} status.
-- @param #TASK_BASE self
function TASK_BASE:GetStateString()
return self:GetState( self, "State" )
end
--- Sets a @{Task} briefing.
-- @param #TASK_BASE self
-- @param #string TaskBriefing
-- @return self
function TASK_BASE:SetBriefing( TaskBriefing )
self.TaskBriefing = TaskBriefing
return self
end
--- @param #TASK_BASE self
function TASK_BASE:_Schedule()

View File

@ -9,15 +9,24 @@ TASK_SEAD = {
--- Instantiates a new TASK_SEAD. Should never be used. Interface Class.
-- @param #TASK_SEAD self
-- @param Mission#MISSION Mission
-- @param Set#SET_UNIT UnitSetTargets
-- @param Zone#ZONE_BASE TargetZone
-- @return #TASK_SEAD self
function TASK_SEAD:New( TargetSetUnit, TargetZone )
local self = BASE:Inherit( self, BASE:New() )
function TASK_SEAD:New( Mission, TargetSetUnit, TargetZone )
local self = BASE:Inherit( self, TASK_BASE:New( Mission, "SEAD" ) )
self:F()
self.TargetSetUnit= TargetSetUnit
self.TargetSetUnit = TargetSetUnit
self.TargetZone = TargetZone
_EVENTDISPATCHER:OnBirth( self._EventAssignUnit, self )
_EVENTDISPATCHER:OnPlayerEnterUnit(self._EventAssignUnit, self )
_EVENTDISPATCHER:OnPlayerLeaveUnit(self._EventUnAssignUnit, self )
_EVENTDISPATCHER:OnCrash(self._EventUnAssignUnit, self )
_EVENTDISPATCHER:OnDead(self._EventUnAssignUnit, self )
_EVENTDISPATCHER:OnPilotDead(self._EventUnAssignUnit, self )
return self
end
@ -26,33 +35,55 @@ end
-- @param Unit#UNIT TaskUnit
-- @return #TASK_SEAD self
function TASK_SEAD:AssignToUnit( TaskUnit )
self:F( TaskUnit:GetName() )
local ProcessAssign = self:AddProcess( TaskUnit, PROCESS_ASSIGN:New( self, TaskUnit, self.TaskBriefing ) )
local ProcessRoute = self:AddProcess( TaskUnit, PROCESS_ROUTE:New( self, TaskUnit, self.TargetZone ) )
local ProcessSEAD = self:AddProcess( TaskUnit, PROCESS_SEAD:New( self, TaskUnit, self.TargetUnitSet ) )
local ProcessSEAD = self:AddProcess( TaskUnit, PROCESS_SEAD:New( self, TaskUnit, self.TargetSetUnit ) )
local Process = self:AddStateMachine( TaskUnit, STATEMACHINE:New( {
local Process = self:AddStateMachine( TaskUnit, STATEMACHINE_TASK:New( self, {
initial = 'None',
events = {
{ name = 'Start', from = 'None', to = 'Assigned' },
{ name = 'Next', from = 'Unassigned', to = 'Assigned' },
{ name = 'Next', from = 'None', to = 'Planned' },
{ name = 'Next', from = 'Planned', to = 'Assigned' },
{ name = 'Reject', from = 'Planned', to = 'Rejected' },
{ name = 'Next', from = 'Assigned', to = 'Success' },
{ name = 'Fail', from = 'Assigned', to = 'Failed' },
{ name = 'Fail', from = 'Arrived', to = 'Failed' }
},
callbacks = {
onNext = self.OnNext,
onRemove = self.OnRemove,
},
subs = {
Route = { onstateparent = 'Assigned', oneventparent = 'Start', fsm = ProcessRoute.Fsm, event = 'Route' },
Assign = { onstateparent = 'Planned', oneventparent = 'Next', fsm = ProcessAssign.Fsm, event = 'Menu', returnevents = { 'Next', 'Reject' } },
Route = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessRoute.Fsm, event = 'Route' },
Sead = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessSEAD.Fsm, event = 'Await', returnevents = { 'Next' } }
}
} ) )
---Task_Client_Sead:AddScore( "Destroy", "Destroyed RADAR", 25 )
---Task_Client_Sead:AddScore( "Success", "Destroyed all radars!!!", 100 )
ProcessRoute:AddScore( "Failed", "failed to destroy a radar", -100 )
ProcessSEAD:AddScore( "Destroy", "destroyed a radar", 25 )
ProcessSEAD:AddScore( "Failed", "failed to destroy a radar", -100 )
Process:Start()
Process:Next()
return self
end
--- StateMachine callback function for a TASK
-- @param #TASK_SEAD self
-- @param StateMachine#STATEMACHINE_TASK Fsm
-- @param #string Event
-- @param #string From
-- @param #string To
-- @param Event#EVENTDATA Event
function TASK_SEAD:OnNext( Fsm, Event, From, To, Event )
self:SetState( self, "State", To )
end
--- @param #TASK_SEAD self
function TASK_SEAD:_Schedule()
self:F2()

View File

@ -179,6 +179,24 @@ function UNIT:IsActive()
return nil
end
--- Destroys the @{Unit}.
-- @param Unit#UNIT self
-- @return #nil The DCS Unit is not existing or alive.
function UNIT:Destroy()
self:F2( self.UnitName )
local DCSUnit = self:GetDCSObject()
if DCSUnit then
DCSUnit:destroy()
end
return nil
end
--- Returns the Unit's callsign - the localized string.
-- @param Unit#UNIT self
-- @return #string The Callsign of the Unit.

View File

@ -1,15 +1,16 @@
local Mission = MISSION:New( 'SEAD Targets', "Strategic", "SEAD the enemy", "RUSSIA" )
local Mission = MISSION:New( 'SEAD Targets', "Strategic", "SEAD the enemy", coalition.side.RED )
local Scoring = SCORING:New( "SEAD" )
Mission:AddScoring( Scoring )
local Client = CLIENT:FindByName( "Test SEAD" )
local SEADGroup = GROUP:FindByName( "Test SEAD" )
local TargetSet = SET_UNIT:New():FilterPrefixes( "US Hawk SR" ):FilterStart()
local TargetZone = ZONE:New( "Target Zone" )
local Task_SEAD = TASK_SEAD:New( TargetSet, TargetZone )
local TaskSEAD = TASK_SEAD:New( Mission, TargetSet, TargetZone ):SetName( "SEAD Radars" ):AssignToGroup( SEADGroup )