diff --git a/Moose Development/Moose/Core/StateMachine.lua b/Moose Development/Moose/Core/StateMachine.lua index 1cdf636d7..429916fec 100644 --- a/Moose Development/Moose/Core/StateMachine.lua +++ b/Moose Development/Moose/Core/StateMachine.lua @@ -40,49 +40,28 @@ function STATEMACHINE:New( FsmT ) --setmetatable( self, MT ) --self.__index = self - for TransitionID, Transition in pairs( FsmT:GetTransitions() ) do - self:AddAction( Transition.From, Transition.Event, Transition.To ) - self.FsmT:CopyCallHandler( self, "onenter", Transition.From ) - self.FsmT:CopyCallHandler( self, "onleave", Transition.From ) - self.FsmT:CopyCallHandler( self, "onenter", Transition.To ) - self.FsmT:CopyCallHandler( self, "onleave", Transition.To ) - self.FsmT:CopyCallHandler( self, "onbefore", Transition.Event ) - self.FsmT:CopyCallHandler( self, "onafter", Transition.Event ) - end - - for ProcessID, Process in pairs( self.FsmT:GetProcesses() ) do - self:E( Process ) - local FsmProcess = self:AddProcess(Process.From, Process.Event, Process.Process:New( unpack( Process.Arguments ) ), Process.ReturnEvents ) - self.FsmT:CopyCallHandler( FsmProcess, "onenter", Process.From ) - self.FsmT:CopyCallHandler( FsmProcess, "onleave", Process.From ) - self.FsmT:CopyCallHandler( FsmProcess, "onbefore", Process.Event ) - self.FsmT:CopyCallHandler( FsmProcess, "onafter", Process.Event ) - - end - - for EndStateID, EndState in pairs( FsmT:EndStates() ) do - self:E( EndState ) - self:AddEndState( EndState ) - end - - self:SetStartState( FsmT:GetStartState() ) - - self.options = options or {} self.options.subs = self.options.subs or {} self.current = self.options.initial or 'none' self.events = {} self.subs = {} self.endstates = {} + + self.Scores = {} + FsmT = FsmT or STATEMACHINE_TEMPLATE:New( "" ) + + self:SetStartState( FsmT:GetStartState() ) + + for TransitionID, Transition in pairs( FsmT:GetTransitions() ) do + self:AddTransition( Transition.From, Transition.Event, Transition.To ) + end + + self:CopyCallHandlers( FsmT ) + return self end -function STATEMACHINE:SetInitialState( State ) - self.current = State -end - - function STATEMACHINE:AddTransition( From, Event, To ) @@ -110,13 +89,9 @@ function STATEMACHINE:AddProcess( From, Event, Process, ReturnEvents ) sub.event = "Start" sub.ReturnEvents = ReturnEvents - -- Make the reference table weak. - -- setmetatable( self.options.subs, { __mode = "v" } ) - self.options.subs[Event] = sub - self:_submap( self.subs, sub, nil ) - self:AddAction( From, Event, From ) + self:AddTransition( From, Event, From ) return Process end @@ -125,6 +100,10 @@ function STATEMACHINE:AddEndState( State ) self.endstates[State] = State end +function STATEMACHINE:SetStartState( State ) + self.current = State +end + function STATEMACHINE:GetSubs() return self.options.subs @@ -157,7 +136,7 @@ function STATEMACHINE:_submap( subs, sub, name ) subs[sub.FromParent][sub.EventParent] = subs[sub.FromParent][sub.EventParent] or {} -- Make the reference table weak. - setmetatable( subs[sub.FromParent][sub.EventParent], { __mode = "k" } ) + -- setmetatable( subs[sub.FromParent][sub.EventParent], { __mode = "k" } ) subs[sub.FromParent][sub.EventParent][sub] = {} subs[sub.FromParent][sub.EventParent][sub].fsm = sub.fsm @@ -325,6 +304,27 @@ function STATEMACHINE:cannot(e) return not self:can(e) end +function STATEMACHINE:CopyCallHandlers( FsmT ) + + local Parent = BASE:GetParent( FsmT ) + if Parent then + self:CopyCallHandlers( Parent ) + end + for ElementID, Element in pairs( FsmT ) do + self:E( { ElementID = ElementID } ) + if type( Element ) == "function" then + if ElementID.find( ElementID, "^onbefore" ) or + ElementID.find( ElementID, "^onafter" ) or + ElementID.find( ElementID, "^onenter" ) or + ElementID.find( ElementID, "^onleave" ) or + ElementID.find( ElementID, "^onfunc" ) then + self[ ElementID ] = Element + end + end + end +end + + function STATEMACHINE:todot(filename) local dotfile = io.open(filename,'w') dotfile:write('digraph {\n') @@ -388,9 +388,21 @@ function STATEMACHINE_CONTROLLABLE:GetControllable() end function STATEMACHINE_CONTROLLABLE:_call_handler( handler, params ) + + local ErrorHandler = function( errmsg ) + + env.info( "Error in SCHEDULER function:" .. errmsg ) + if debug ~= nil then + env.info( debug.traceback() ) + end + + return errmsg + end + if self[handler] then self:E( "Calling " .. handler ) - return self[handler]( self, self.Controllable, unpack( params ) ) + return xpcall( function() return self[handler]( self, self.Controllable, unpack( params ) ) end, ErrorHandler ) + --return self[handler]( self, self.Controllable, unpack( params ) ) end end @@ -406,9 +418,26 @@ STATEMACHINE_PROCESS = { --- Creates a new STATEMACHINE_PROCESS object. -- @param #STATEMACHINE_PROCESS self -- @return #STATEMACHINE_PROCESS -function STATEMACHINE_PROCESS:New( FSMT ) +function STATEMACHINE_PROCESS:New( FsmT, Controllable, Task ) - local self = BASE:Inherit( self, STATEMACHINE_CONTROLLABLE:New( FSMT ) ) -- StateMachine#STATEMACHINE_PROCESS + local self = BASE:Inherit( self, STATEMACHINE_CONTROLLABLE:New( FsmT ) ) -- StateMachine#STATEMACHINE_PROCESS + + self:Assign( Controllable, Task ) + self.ClassName = FsmT._Name + + for ParameterID, Parameter in pairs( FsmT:GetParameters() ) do + self[ ParameterID ] = Parameter + end + + for ProcessID, Process in pairs( FsmT:GetProcesses() ) do + self:E( Process ) + local FsmProcess = self:AddProcess(Process.From, Process.Event, STATEMACHINE_PROCESS:New( Process.Process, Controllable, Task ), Process.ReturnEvents ) + end + + for EndStateID, EndState in pairs( FsmT:GetEndStates() ) do + self:E( EndState ) + self:AddEndState( EndState ) + end return self end @@ -442,21 +471,17 @@ end --- Assign the process to a @{Unit} and activate the process. --- @param #PROCESS self +-- @param #STATEMACHINE_PROCESS self -- @param Task.Tasking#TASK_BASE Task -- @param Wrapper.Unit#UNIT ProcessUnit --- @return #PROCESS self -function STATEMACHINE_PROCESS:Assign( Task, ProcessUnit ) +-- @return #STATEMACHINE_PROCESS self +function STATEMACHINE_PROCESS:Assign( ProcessUnit, Task ) self:E( { Task, ProcessUnit } ) self:SetControllable( ProcessUnit ) self:SetTask( Task ) - self.ProcessGroup = ProcessUnit:GetGroup() - --Task:RemoveMenuForGroup( self.ProcessGroup ) - --Task:SetAssignedMenuForGroup( self.ProcessGroup ) - - --self:Activate() + --self.ProcessGroup = ProcessUnit:GetGroup() return self end @@ -486,7 +511,7 @@ end -- @param #string From -- @param #string To function STATEMACHINE_PROCESS:onstatechange( ProcessUnit, Event, From, To, Dummy ) - self:E( { ProcessUnit, Event, From, To, Dummy } ) + self:E( { ProcessUnit, Event, From, To, Dummy, self:IsTrace() } ) if self:IsTrace() then MESSAGE:New( "Process " .. self.ProcessName .. " : " .. Event .. " changed to state " .. To, 15 ):ToAll() @@ -601,12 +626,13 @@ function STATEMACHINE_TEMPLATE:New( Name ) -- Inherits from BASE local self = BASE:Inherit( self, BASE:New() ) -- #STATEMACHINE_TEMPLATE - self._Transitions = self.Transitions or {} - self._Processes = self.Processes or {} - self._EndStates = self.EndStates or {} self._StartState = "none" + self._Transitions = {} + self._Processes = {} + self._EndStates = {} + self._Scores = {} - self._Name = Name + self._Name = Name or "" return self end @@ -623,20 +649,24 @@ end function STATEMACHINE_TEMPLATE:GetTransitions() - return self._Transitions + return self._Transitions or {} end --- Set the default @{Process} template with key ProcessName providing the ProcessClass and the process object when it is assigned to a @{Controllable} by the task. -- @return Process#PROCESS -function STATEMACHINE_TEMPLATE:AddProcess( From, Event, ProcessTemplate, ProcessArguments, ReturnEvents ) +function STATEMACHINE_TEMPLATE:AddProcess( From, Event, ProcessTemplate, ReturnEvents ) + + self:E( { ProcessTemplate = ProcessTemplate } ) local Process = {} Process.From = From Process.Event = Event Process.Process = ProcessTemplate - Process.Arguments = ProcessArguments + Process.Parameters = ProcessTemplate:GetParameters() Process.ReturnEvents = ReturnEvents + self:E( { From = Process.From, Event = Process.Event, Process = Process.Process._Name, Parameters = Process.Parameters, ReturnEvents = Process.ReturnEvents } ) + -- Make the reference table weak. -- setmetatable( self.options.subs, { __mode = "v" } ) self._Processes[Process] = Process @@ -646,27 +676,48 @@ end function STATEMACHINE_TEMPLATE:GetProcesses() - return self._Processes + return self._Processes or {} end +function STATEMACHINE_TEMPLATE:GetProcess( From, Event ) + + for ProcessID, Process in pairs( self:GetProcesses() ) do + if Process.From == From and Process.Event == Event then + self:E( Process ) + return Process.Process + end + end + + error( "Sub-Process from state " .. From .. " with event " .. Event .. " not found!" ) +end + +function STATEMACHINE_TEMPLATE:SetParameters( Parameters ) + self._Parameters = Parameters +end + +function STATEMACHINE_TEMPLATE:GetParameters() + return self._Parameters or {} +end + + function STATEMACHINE_TEMPLATE:AddEndState( State ) - self._EndStates[EndState] = EndState + self._EndStates[State] = State end function STATEMACHINE_TEMPLATE:GetEndStates() - return self._EndStates + return self._EndStates or {} end -function STATEMACHINE_TEMPLATE:AddStartState() +function STATEMACHINE_TEMPLATE:SetStartState( State ) - self._StartState = StartState + self._StartState = State end function STATEMACHINE_TEMPLATE:GetStartState() - return self._StartState + return self._StartState or {} end --- Adds a score for the STATEMACHINE_PROCESS to be achieved. @@ -678,16 +729,31 @@ end function STATEMACHINE_TEMPLATE:AddScore( State, ScoreText, Score ) self:F2( { State, ScoreText, Score } ) - self.Scores[State] = self.Scores[State] or {} - self.Scores[State].ScoreText = ScoreText - self.Scores[State].Score = Score + self._Scores[State] = self._Scores[State] or {} + self._Scores[State].ScoreText = ScoreText + self._Scores[State].Score = Score return self end -function STATEMACHINE_TEMPLATE:CopyCallHandler( Fsm, OnAction, Transition ) - self:E( { Fsm.ClassName, OnAction, Transition } ) - if OnAction and Transition and self[OnAction .. Transition] then - Fsm[OnAction .. Transition] = self[OnAction .. Transition] - end +--- Adds a score for the STATEMACHINE_PROCESS to be achieved. +-- @param #STATEMACHINE_TEMPLATE self +-- @param #string From is the From State of the main process. +-- @param #string Event is the Event of the main process. +-- @param #string State is the state of the process when the score needs to be given. (See the relevant state descriptions of the process). +-- @param #string ScoreText is a text describing the score that is given according the status. +-- @param #number Score is a number providing the score of the status. +-- @return #STATEMACHINE_TEMPLATE self +function STATEMACHINE_TEMPLATE:AddScoreProcess( From, Event, State, ScoreText, Score ) + self:F2( { Event, State, ScoreText, Score } ) + + local Process = self:GetProcess( From, Event ) + + self:E( { Process = Process._Name, Scores = Process._Scores, State = State, ScoreText = ScoreText, Score = Score } ) + Process._Scores[State] = Process._Scores[State] or {} + Process._Scores[State].ScoreText = ScoreText + Process._Scores[State].Score = Score + + return Process end + diff --git a/Moose Development/Moose/Process/Account.lua b/Moose Development/Moose/Process/Account.lua index 4fc0774e7..769607aee 100644 --- a/Moose Development/Moose/Process/Account.lua +++ b/Moose Development/Moose/Process/Account.lua @@ -102,7 +102,7 @@ do -- PROCESS_ACCOUNT self:AddEndState( "Accounted" ) self:AddEndState( "Failed" ) - self:AddStartState( "Assigned" ) + self:SetStartState( "Assigned" ) return self end @@ -117,14 +117,7 @@ do -- PROCESS_ACCOUNT -- @param #string To function PROCESS_ACCOUNT:onafterStart( ProcessUnit, Event, From, To ) - -- TODO: need to generalize the timing. - self.DisplayInterval = 30 - self.DisplayCount = 30 - self.DisplayMessage = true - self.DisplayTime = 10 -- 10 seconds is the default - self.DisplayCategory = "HQ" -- Targets is the default display category - - self:EventOnDead( self.EventDead ) + self:EventOnDead( self.onfuncEventDead ) self:__Wait( 1 ) end @@ -181,23 +174,20 @@ do -- PROCESS_ACCOUNT_DEADS -- Inherits from BASE local self = BASE:Inherit( self, PROCESS_ACCOUNT:New() ) -- #PROCESS_ACCOUNT_DEADS - return self, { TargetSetUnit, TaskName } - end - - - --- Creates a new DESTROY process. - -- @param #PROCESS_ACCOUNT_DEADS self - -- @param Set#SET_UNIT TargetSetUnit - -- @param #string TaskName - -- @return #PROCESS_ACCOUNT_DEADS self - function PROCESS_ACCOUNT_DEADS:Init( TargetSetUnit, TaskName ) - - self.TargetSetUnit = TargetSetUnit - self.TaskName = TaskName + self:SetParameters( { + TargetSetUnit = TargetSetUnit, + TaskName = TaskName, + DisplayInterval = 30, + DisplayCount = 30, + DisplayMessage = true, + DisplayTime = 10, -- 10 seconds is the default + DisplayCategory = "HQ", -- Targets is the default display category + } ) return self end + function PROCESS_ACCOUNT_DEADS:_Destructor() self:E("_Destructor") @@ -260,7 +250,7 @@ do -- PROCESS_ACCOUNT_DEADS --- @param #PROCESS_ACCOUNT_DEADS self -- @param Event#EVENTDATA EventData - function PROCESS_ACCOUNT_DEADS:EventDead( EventData ) + function PROCESS_ACCOUNT_DEADS:onfuncEventDead( EventData ) self:T( { "EventDead", EventData } ) if EventData.IniDCSUnit then diff --git a/Moose Development/Moose/Process/Assign.lua b/Moose Development/Moose/Process/Assign.lua index ac7ef2c0b..64fc918bc 100644 --- a/Moose Development/Moose/Process/Assign.lua +++ b/Moose Development/Moose/Process/Assign.lua @@ -110,7 +110,7 @@ do -- PROCESS_ASSIGN self:AddEndState( "Rejected" ) self:AddEndState( "Failed" ) - self:AddStartState( "UnAssigned" ) + self:SetStartState( "UnAssigned" ) return self end @@ -136,26 +136,14 @@ do -- PROCESS_ASSIGN_ACCEPT -- @param #PROCESS_ASSIGN_ACCEPT self -- @param #string TaskBriefing function PROCESS_ASSIGN_ACCEPT:New( TaskBriefing ) - -- Inherits from BASE + local self = BASE:Inherit( self, PROCESS_ASSIGN:New() ) -- #PROCESS_ASSIGN_ACCEPT - return self, { TaskBriefing } - end - - - --- Creates a new task assignment state machine. The process will accept the task by default, no player intervention accepted. - -- @param #PROCESS_ASSIGN_ACCEPT self - -- @param #string TaskBriefing - -- @return #PROCESS_ASSIGN_ACCEPT The task acceptance process. - function PROCESS_ASSIGN_ACCEPT:Init( TaskBriefing ) - - - self.TaskBriefing = TaskBriefing + self:SetParameters( { TaskBriefing = TaskBriefing } ) return self end - --- StateMachine callback function -- @param #PROCESS_ASSIGN_ACCEPT self -- @param Wrapper.Unit#UNIT ProcessUnit @@ -178,6 +166,7 @@ do -- PROCESS_ASSIGN_ACCEPT -- @param #string From -- @param #string To function PROCESS_ASSIGN_ACCEPT:onenterAssigned( ProcessUnit, Event, From, To ) + env.info( "in here" ) self:E( { ProcessUnit, Event, From, To } ) local ProcessGroup = ProcessUnit:GetGroup() @@ -211,8 +200,10 @@ do -- PROCESS_ASSIGN_MENU_ACCEPT -- Inherits from BASE local self = BASE:Inherit( self, PROCESS_ASSIGN:New() ) -- #PROCESS_ASSIGN_MENU_ACCEPT + + self:SetParameters( { TaskName = TaskName, TaskBriefing = TaskBriefing } ) - return self, { TaskName, TaskBriefing } + return self end diff --git a/Moose Development/Moose/Process/Route.lua b/Moose Development/Moose/Process/Route.lua index bd9ed812b..21b55e44b 100644 --- a/Moose Development/Moose/Process/Route.lua +++ b/Moose Development/Moose/Process/Route.lua @@ -110,7 +110,7 @@ do -- PROCESS_ROUTE self:AddEndState( "Arrived" ) self:AddEndState( "Failed" ) - self:AddStartState( "None" ) + self:SetStartState( "None" ) return self end @@ -125,11 +125,6 @@ do -- PROCESS_ROUTE -- @param #string To function PROCESS_ROUTE:onafterStart( ProcessUnit, Event, From, To ) - self.DisplayInterval = 30 - self.DisplayCount = 30 - self.DisplayMessage = true - self.DisplayTime = 10 -- 10 seconds is the default - self.DisplayCategory = "HQ" -- Route is the default display category self:__Route( 1 ) end @@ -138,7 +133,7 @@ do -- PROCESS_ROUTE -- @param #PROCESS_ROUTE self -- @param Controllable#CONTROLLABLE ProcessUnit -- @return #boolean - function PROCESS_ROUTE:HasArrived( ProcessUnit ) + function PROCESS_ROUTE:onfuncHasArrived( ProcessUnit ) return false end @@ -151,7 +146,7 @@ do -- PROCESS_ROUTE function PROCESS_ROUTE:onbeforeRoute( ProcessUnit, Event, From, To ) if ProcessUnit:IsAlive() then - local HasArrived = self:HasArrived( ProcessUnit ) -- Polymorphic + local HasArrived = self:onfuncHasArrived( ProcessUnit ) -- Polymorphic if self.DisplayCount >= self.DisplayInterval then self:T( { HasArrived = HasArrived } ) if not HasArrived then @@ -200,26 +195,23 @@ do -- PROCESS_ROUTE_ZONE function PROCESS_ROUTE_ZONE:New( TargetZone ) local self = BASE:Inherit( self, PROCESS_ROUTE:New() ) -- #PROCESS_ROUTE_ZONE - return self, { TargetZone } - end - - - --- Creates a new routing state machine. The task will route a controllable to a ZONE until the controllable is within that ZONE. - -- @param #PROCESS_ROUTE_ZONE self - -- @param Zone#ZONE_BASE TargetZone - -- @return #PROCESS_ROUTE_ZONE self - function PROCESS_ROUTE_ZONE:New( TargetZone ) - - self.TargetZone = TargetZone + self:SetParameters( { + TargetZone = TargetZone, + DisplayInterval = 30, + DisplayCount = 30, + DisplayMessage = true, + DisplayTime = 10, -- 10 seconds is the default + DisplayCategory = "HQ", -- Route is the default display category + } ) return self end - + --- Method override to check if the controllable has arrived. -- @param #PROCESS_ROUTE self -- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit -- @return #boolean - function PROCESS_ROUTE_ZONE:HasArrived( ProcessUnit ) + function PROCESS_ROUTE_ZONE:onfuncHasArrived( ProcessUnit ) if ProcessUnit:IsInZone( self.TargetZone ) then local RouteText = ProcessUnit:GetCallsign() .. ": You have arrived within the zone!" diff --git a/Moose Development/Moose/Process/Smoke.lua b/Moose Development/Moose/Process/Smoke.lua index 653d27ca2..6b8017815 100644 --- a/Moose Development/Moose/Process/Smoke.lua +++ b/Moose Development/Moose/Process/Smoke.lua @@ -92,7 +92,7 @@ do -- PROCESS_SMOKE self:AddEndState( "Failed" ) self:AddEndState( "Success" ) - self:AddStartState( "None" ) + self:SetStartState( "None" ) return self end @@ -153,7 +153,9 @@ do -- PROCESS_SMOKE_TARGETS_ZONE function PROCESS_SMOKE_TARGETS_ZONE:New( TargetSetUnit, TargetZone ) local self = BASE:Inherit( self, PROCESS_SMOKE:New() ) -- #PROCESS_SMOKE - return self, { TargetSetUnit, TargetZone } + self:SetParameters( { TargetSetUnit, TargetZone } ) + + return self end --- Creates a new target smoking state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator. diff --git a/Moose Development/Moose/Tasking/Mission.lua b/Moose Development/Moose/Tasking/Mission.lua index 0af1475f8..78db18589 100644 --- a/Moose Development/Moose/Tasking/Mission.lua +++ b/Moose Development/Moose/Tasking/Mission.lua @@ -30,15 +30,6 @@ MISSION = { _GoalTasks = {} } ---- @type MISSION.Clients --- @list - -function MISSION:Meta() - - - return self -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 self -- @param Tasking.CommandCenter#COMMANDCENTER CommandCenter @@ -50,6 +41,12 @@ end function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefing, MissionCoalition ) local self = BASE:Inherit( self, STATEMACHINE:New() ) -- Core.StateMachine#STATEMACHINE + + self:SetStartState( "Idle" ) + + self:AddTransition( "Idle", "Start", "Ongoing" ) + self:AddTransition( "Ongoing", "Stop", "Idle" ) + self:AddTransition( "Ongoing", "Finish", "Finished" ) self:T( { MissionName, MissionPriority, MissionBriefing, MissionCoalition } ) @@ -66,10 +63,6 @@ function MISSION:New( CommandCenter, MissionName, MissionPriority, MissionBriefi -- Build the Fsm for the mission. - self:SetInitialState( "Idle" ) - self:AddAction( "Idle", "Start", "Ongoing" ) - self:AddAction( "Ongoing", "Stop", "Idle" ) - self:AddAction( "Ongoing", "Finish", "Finished" ) return self end diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index 7670b2d28..e7b6897b9 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -77,13 +77,12 @@ TASK_BASE = { -- @return #TASK_BASE self function TASK_BASE:New( Mission, SetGroupAssign, TaskName, TaskType ) + local self = BASE:Inherit( self, STATEMACHINE_TASK:New() ) -- Core.StateMachine#STATEMACHINE_TASK - local self = BASE:Inherit( self, STATEMACHINE_TASK:New( {} ) ) -- Core.StateMachine#STATEMACHINE_TASK - - self:SetInitialState( "Planned" ) - self:AddAction( "Planned", "Assign", "Assigned" ) - self:AddAction( "Assigned", "Success", "Success" ) - self:AddAction( "*", "Fail", "Failed" ) + self:SetStartState( "Planned" ) + self:AddTransition( "Planned", "Assign", "Assigned" ) + self:AddTransition( "Assigned", "Success", "Success" ) + self:AddTransition( "*", "Fail", "Failed" ) self:E( "New TASK " .. TaskName ) @@ -99,7 +98,7 @@ function TASK_BASE:New( Mission, SetGroupAssign, TaskName, TaskType ) self.TaskBriefing = "You are invited for the task: " .. self.TaskName .. "." - self.FsmTemplate = self.FsmTemplate or STATEMACHINE_TEMPLATE:New( {} ) + self.FsmTemplate = self.FsmTemplate or STATEMACHINE_TEMPLATE:New( "MAIN" ) -- Handle the birth of new planes within the assigned set. self:EventOnPlayerEnterUnit( @@ -186,33 +185,9 @@ function TASK_BASE:AssignToUnit( TaskUnit ) self:F( TaskUnit:GetName() ) -- Assign a new FsmUnit to TaskUnit. - local FsmUnit = self:SetStateMachine( TaskUnit, STATEMACHINE_PROCESS:New( self:GetFsmTemplate() ) ) -- Core.StateMachine#STATEMACHINE_PROCESS + local FsmUnit = self:SetStateMachine( TaskUnit, STATEMACHINE_PROCESS:New( self:GetFsmTemplate(), TaskUnit, self ) ) -- Core.StateMachine#STATEMACHINE_PROCESS self:E({"Address FsmUnit", tostring( FsmUnit ) } ) - --TODO: need to check all this with templates ... - FsmUnit:Assign( self, TaskUnit ) - - for TransitionID, Transition in pairs( self.FsmTemplate:GetTransitions() ) do - FsmUnit:AddAction( Transition.From, Transition.Event, Transition.To ) - self.FsmTemplate:CopyCallHandler( FsmUnit, "onenter", Transition.From ) - self.FsmTemplate:CopyCallHandler( FsmUnit, "onleave", Transition.From ) - self.FsmTemplate:CopyCallHandler( FsmUnit, "onenter", Transition.To ) - self.FsmTemplate:CopyCallHandler( FsmUnit, "onleave", Transition.To ) - self.FsmTemplate:CopyCallHandler( FsmUnit, "onbefore", Transition.Event ) - self.FsmTemplate:CopyCallHandler( FsmUnit, "onafter", Transition.Event ) - end - - for ProcessID, Process in pairs( self.FsmTemplate:GetProcesses() ) do - self:E( Process ) - local FsmProcess = FsmUnit:AddProcess(Process.From, Process.Event, Process.Process:New( unpack( Process.Arguments ) ), Process.ReturnEvents ) - self.FsmTemplate:CopyCallHandler( FsmProcess, "onenter", Process.From ) - self.FsmTemplate:CopyCallHandler( FsmProcess, "onleave", Process.From ) - self.FsmTemplate:CopyCallHandler( FsmProcess, "onbefore", Process.Event ) - self.FsmTemplate:CopyCallHandler( FsmProcess, "onafter", Process.Event ) - - FsmProcess:Assign( self, TaskUnit ) - end - -- Set the events FsmUnit:EventOnPilotDead( --- @param Core.Event#EVENTDATA EventData @@ -221,7 +196,7 @@ function TASK_BASE:AssignToUnit( TaskUnit ) end ) - FsmUnit:SetInitialState( "Planned" ) + FsmUnit:SetStartState( "Planned" ) FsmUnit:Accept() -- Each Task needs to start with an Accept event to start the flow. return self diff --git a/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua b/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua index 341b9130d..c5c6dc151 100644 --- a/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua +++ b/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.lua @@ -75,32 +75,32 @@ local FsmSEADTemplate = TaskSEAD:GetFsmTemplate() -- 4.1 When the return state is Assigned, fire the event in the Task FsmSEAD:Route() -- 4.2 When the return state is Rejected, fire the event in the Task FsmSEAD:Eject() -- All other AddProcess calls are working in a similar manner. -FsmSEADTemplate:AddProcess ( "Planned", "Accept", PROCESS_ASSIGN_ACCEPT:Init( "SEAD the Area" ), { Assigned = "Route", Rejected = "Eject" } ) +FsmSEADTemplate:AddProcess ( "Planned", "Accept", PROCESS_ASSIGN_ACCEPT:New( "SEAD the Area" ), { Assigned = "Route", Rejected = "Eject" } ) -- Same, adding a process. -FsmSEADTemplate:AddProcess ( "Assigned", "Route", PROCESS_ROUTE_ZONE:Init( TargetZone, 3000 ), { Arrived = "Update" } ) +FsmSEADTemplate:AddProcess ( "Assigned", "Route", PROCESS_ROUTE_ZONE:New( TargetZone ), { Arrived = "Update" } ) -- Adding a new Action... -- Actions define also the flow of the Task, but the actions will need to be programmed within your script. -- See the state machine explanation for further details. --- The AddAction received a couple of parameters: +-- The AddTransition received a couple of parameters: -- 1. State From "Rejected". When the FsmSEAD is in state "Rejected", the event "Eject" can be fired. -- 2. Event "Eject". This event can be triggered synchronously through FsmSEAD:Eject() or asynchronously through FsmSEAD:__Eject(secs). -- 3. State To "Planned". After the event has been fired, the FsmSEAD will transition to Planned. FsmSEADTemplate:AddTransition ( "Rejected", "Eject", "Planned" ) FsmSEADTemplate:AddTransition ( "Arrived", "Update", "Updated" ) -FsmSEADTemplate:AddProcess ( "Updated", "Account", PROCESS_ACCOUNT_DEADS:Init( TargetSet, "SEAD" ), { Accounted = "Success" } ) -FsmSEADTemplate:AddProcess ( "Updated", "Smoke", PROCESS_SMOKE_TARGETS_ZONE:Init( TargetSet, TargetZone ) ) +FsmSEADTemplate:AddProcess ( "Updated", "Account", PROCESS_ACCOUNT_DEADS:New( TargetSet, "SEAD" ), { Accounted = "Success" } ) +FsmSEADTemplate:AddProcess ( "Updated", "Smoke", PROCESS_SMOKE_TARGETS_ZONE:New( TargetSet, TargetZone ) ) FsmSEADTemplate:AddTransition ( "Accounted", "Success", "Success" ) FsmSEADTemplate:AddTransition ( "*", "Fail", "Failed" ) -TaskSEAD:AddScoreProcess( "Account", "Account", "destroyed a radar", 25 ) -TaskSEAD:AddScoreProcess( "Account", "Failed", "failed to destroy a radar", -10 ) +FsmSEADTemplate:AddScoreProcess( "Updated", "Account", "Account", "destroyed a radar", 25 ) +FsmSEADTemplate:AddScoreProcess( "Updated", "Account", "Failed", "failed to destroy a radar", -10 ) -- Now we will set the SCORING. Scoring is set using the TaskSEAD object. -- Scores can be set on the status of the Task, and on Process level. -FsmSEADTemplate:AddScoreTask( "Success", "Destroyed all target radars", 250 ) -FsmSEADTemplate:AddScoreTask( "Failed", "Failed to destroy all target radars", -100 ) +FsmSEADTemplate:AddScore( "Success", "Destroyed all target radars", 250 ) +FsmSEADTemplate:AddScore( "Failed", "Failed to destroy all target radars", -100 ) diff --git a/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.miz b/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.miz index 8877febb9..e49d55005 100644 Binary files a/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.miz and b/Moose Test Missions/Moose_Test_Tasking/Moose_Test_Task_SEAD/Moose_Test_Task_SEAD.miz differ