From 764266d5527954fd4615c8a43e307d9c79e18165 Mon Sep 17 00:00:00 2001 From: FlightControl Date: Sun, 6 Nov 2016 11:34:32 +0100 Subject: [PATCH] Got SEAD tasking working now with new Process Templates... --- Moose Development/Moose/Fsm/Cargo.lua | 122 ++++++------ Moose Development/Moose/Fsm/Patrol.lua | 2 +- Moose Development/Moose/Fsm/Process.lua | 45 ++++- Moose Development/Moose/Fsm/Process_Smoke.lua | 109 ---------- Moose Development/Moose/Moose.lua | 12 +- .../Moose/{Fsm => Process}/Account.lua | 90 ++++----- .../Moose/{Fsm => Process}/Assign.lua | 116 +++++------ .../Moose/{Fsm => Process}/Route.lua | 86 ++++---- Moose Development/Moose/Process/Smoke.lua | 188 ++++++++++++++++++ Moose Development/Moose/Tasking/Task.lua | 7 +- Moose Development/Moose/Tasking/Task_A2G.lua | 19 +- Moose Development/Moose/Tasking/Task_SEAD.lua | 20 +- .../Moose/Wrapper/Controllable.lua | 2 +- Moose Development/Old/Stage.lua | 8 +- .../Moose_Test_Task_SEAD.lua | 7 +- .../Moose_Test_Task_SEAD.miz | Bin 25232 -> 26171 bytes .../DCS World - MOOSE - Tasking - SEAD.pptx | Bin 2747476 -> 2752651 bytes 17 files changed, 477 insertions(+), 356 deletions(-) delete mode 100644 Moose Development/Moose/Fsm/Process_Smoke.lua rename Moose Development/Moose/{Fsm => Process}/Account.lua (77%) rename Moose Development/Moose/{Fsm => Process}/Assign.lua (68%) rename Moose Development/Moose/{Fsm => Process}/Route.lua (78%) create mode 100644 Moose Development/Moose/Process/Smoke.lua diff --git a/Moose Development/Moose/Fsm/Cargo.lua b/Moose Development/Moose/Fsm/Cargo.lua index f43de4acb..56aa7e12b 100644 --- a/Moose Development/Moose/Fsm/Cargo.lua +++ b/Moose Development/Moose/Fsm/Cargo.lua @@ -20,15 +20,15 @@ -- The CARGO_BASE is a state machine: it manages the different events and states of the cargo. -- All derived classes from CARGO_BASE follow the same state machine, expose the same cargo event functions, and provide the same cargo states. -- --- ## 1.2.1) CARBO_BASE Events: +-- ## 1.2.1) CARGO_BASE Events: -- --- * @{#CARBO_BASE.Board}( ToCarrier ): Boards the cargo to a carrier. --- * @{#CARBO_BASE.Load}( ToCarrier ): Loads the cargo into a carrier, regardless of its position. --- * @{#CARBO_BASE.UnBoard}( ToPointVec2 ): UnBoard the cargo from a carrier. This will trigger a movement of the cargo to the option ToPointVec2. --- * @{#CARBO_BASE.UnLoad}( ToPointVec2 ): UnLoads the cargo from a carrier. --- * @{#CARBO_BASE.Dead}( Controllable ): The cargo is dead. The cargo process will be ended. +-- * @{#CARGO_BASE.Board}( ToCarrier ): Boards the cargo to a carrier. +-- * @{#CARGO_BASE.Load}( ToCarrier ): Loads the cargo into a carrier, regardless of its position. +-- * @{#CARGO_BASE.UnBoard}( ToPointVec2 ): UnBoard the cargo from a carrier. This will trigger a movement of the cargo to the option ToPointVec2. +-- * @{#CARGO_BASE.UnLoad}( ToPointVec2 ): UnLoads the cargo from a carrier. +-- * @{#CARGO_BASE.Dead}( Controllable ): The cargo is dead. The cargo process will be ended. -- --- ## 1.2.2) CARBO_BASE States: +-- ## 1.2.2) CARGO_BASE States: -- -- * **UnLoaded**: The cargo is unloaded from a carrier. -- * **Boarding**: The cargo is currently boarding (= running) into a carrier. @@ -37,7 +37,7 @@ -- * **Dead**: The cargo is dead ... -- * **End**: The process has come to an end. -- --- ## 1.2.3) CARBO_BASE state transition methods: +-- ## 1.2.3) CARGO_BASE state transition methods: -- -- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state. -- There are 2 moments when state transition methods will be called by the state machine: @@ -72,14 +72,14 @@ --- Boards the cargo to a Carrier. The event will create a movement (= running or driving) of the cargo to the Carrier. -- The cargo must be in the **UnLoaded** state. --- @function [parent=#CARBO_BASE] Board --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] Board +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE ToCarrier The Carrier that will hold the cargo. --- Boards the cargo to a Carrier. The event will create a movement (= running or driving) of the cargo to the Carrier. -- The cargo must be in the **UnLoaded** state. --- @function [parent=#CARBO_BASE] __Board --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] __Board +-- @param #CARGO_BASE self -- @param #number DelaySeconds The amount of seconds to delay the action. -- @param Controllable#CONTROLLABLE ToCarrier The Carrier that will hold the cargo. @@ -88,14 +88,14 @@ --- UnBoards the cargo to a Carrier. The event will create a movement (= running or driving) of the cargo from the Carrier. -- The cargo must be in the **Loaded** state. --- @function [parent=#CARBO_BASE] UnBoard --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] UnBoard +-- @param #CARGO_BASE self -- @param Point#POINT_VEC2 ToPointVec2 (optional) @{Point#POINT_VEC2) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location. --- UnBoards the cargo to a Carrier. The event will create a movement (= running or driving) of the cargo from the Carrier. -- The cargo must be in the **Loaded** state. --- @function [parent=#CARBO_BASE] __UnBoard --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] __UnBoard +-- @param #CARGO_BASE self -- @param #number DelaySeconds The amount of seconds to delay the action. -- @param Point#POINT_VEC2 ToPointVec2 (optional) @{Point#POINT_VEC2) to where the cargo should run after onboarding. If not provided, the cargo will run to 60 meters behind the Carrier location. @@ -104,14 +104,14 @@ --- Loads the cargo to a Carrier. The event will load the cargo into the Carrier regardless of its position. There will be no movement simulated of the cargo loading. -- The cargo must be in the **UnLoaded** state. --- @function [parent=#CARBO_BASE] Load --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] Load +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE ToCarrier The Carrier that will hold the cargo. --- Loads the cargo to a Carrier. The event will load the cargo into the Carrier regardless of its position. There will be no movement simulated of the cargo loading. -- The cargo must be in the **UnLoaded** state. --- @function [parent=#CARBO_BASE] __Load --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] __Load +-- @param #CARGO_BASE self -- @param #number DelaySeconds The amount of seconds to delay the action. -- @param Controllable#CONTROLLABLE ToCarrier The Carrier that will hold the cargo. @@ -120,14 +120,14 @@ --- UnLoads the cargo to a Carrier. The event will unload the cargo from the Carrier. There will be no movement simulated of the cargo loading. -- The cargo must be in the **Loaded** state. --- @function [parent=#CARBO_BASE] UnLoad --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] UnLoad +-- @param #CARGO_BASE self -- @param Point#POINT_VEC2 ToPointVec2 (optional) @{Point#POINT_VEC2) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location. --- UnLoads the cargo to a Carrier. The event will unload the cargo from the Carrier. There will be no movement simulated of the cargo loading. -- The cargo must be in the **Loaded** state. --- @function [parent=#CARBO_BASE] __UnLoad --- @param #CARBO_BASE self +-- @function [parent=#CARGO_BASE] __UnLoad +-- @param #CARGO_BASE self -- @param #number DelaySeconds The amount of seconds to delay the action. -- @param Point#POINT_VEC2 ToPointVec2 (optional) @{Point#POINT_VEC2) to where the cargo will be placed after unloading. If not provided, the cargo will be placed 60 meters behind the Carrier location. @@ -135,46 +135,46 @@ -- UnLoaded ---- @function [parent=#CARBO_BASE] OnBeforeUnLoaded --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnBeforeUnLoaded +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable -- @return #boolean ---- @function [parent=#CARBO_BASE] OnAfterUnLoaded --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnAfterUnLoaded +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable -- Loaded ---- @function [parent=#CARBO_BASE] OnBeforeLoaded --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnBeforeLoaded +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable -- @return #boolean ---- @function [parent=#CARBO_BASE] OnAfterLoaded --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnAfterLoaded +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable -- Boarding ---- @function [parent=#CARBO_BASE] OnBeforeBoarding --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnBeforeBoarding +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable -- @return #boolean ---- @function [parent=#CARBO_BASE] OnAfterBoarding --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnAfterBoarding +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable -- UnBoarding ---- @function [parent=#CARBO_BASE] OnBeforeUnBoarding --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnBeforeUnBoarding +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable -- @return #boolean ---- @function [parent=#CARBO_BASE] OnAfterUnBoarding --- @param #CARBO_BASE self +--- @function [parent=#CARGO_BASE] OnAfterUnBoarding +-- @param #CARGO_BASE self -- @param Controllable#CONTROLLABLE Controllable @@ -182,9 +182,9 @@ CARGOS = {} -do -- CARBO_BASE +do -- CARGO_BASE - --- @type CARBO_BASE + --- @type CARGO_BASE -- @extends StateMachine#STATEMACHINE_PROCESS -- @field #string Type A string defining the type of the cargo. eg. Engineers, Equipment, Screwdrivers. -- @field #string Name A string defining the name of the cargo. The name is the unique identifier of the cargo. @@ -197,8 +197,8 @@ do -- CARBO_BASE -- @field #boolean Moveable This flag defines if the cargo is moveable. -- @field #boolean Representable This flag defines if the cargo can be represented by a DCS Unit. -- @field #boolean Containable This flag defines if the cargo can be contained within a DCS Unit. - CARBO_BASE = { - ClassName = "CARBO_BASE", + CARGO_BASE = { + ClassName = "CARGO_BASE", Type = nil, Name = nil, Weight = nil, @@ -210,19 +210,19 @@ do -- CARBO_BASE Containable = false, } ---- @type CARBO_BASE.CargoObjects +--- @type CARGO_BASE.CargoObjects -- @map < #string, Positionable#POSITIONABLE > The alive POSITIONABLE objects representing the the cargo. ---- CARBO_BASE Constructor. This class is an abstract class and should not be instantiated. --- @param #CARBO_BASE self +--- CARGO_BASE Constructor. This class is an abstract class and should not be instantiated. +-- @param #CARGO_BASE self -- @param #string Type -- @param #string Name -- @param #number Weight -- @param #number ReportRadius (optional) -- @param #number NearRadius (optional) --- @return #CARBO_BASE -function CARBO_BASE:New( Type, Name, Weight, ReportRadius, NearRadius ) +-- @return #CARGO_BASE +function CARGO_BASE:New( Type, Name, Weight, ReportRadius, NearRadius ) FSMT = { initial = 'UnLoaded', @@ -238,7 +238,7 @@ function CARBO_BASE:New( Type, Name, Weight, ReportRadius, NearRadius ) }, } - local self = BASE:Inherit( self, STATEMACHINE_PROCESS:New( FSMT ) ) -- #CARBO_BASE + local self = BASE:Inherit( self, STATEMACHINE_PROCESS:New( FSMT ) ) -- #CARGO_BASE self:F( { Type, Name, Weight, ReportRadius, NearRadius } ) @@ -263,20 +263,20 @@ function CARBO_BASE:New( Type, Name, Weight, ReportRadius, NearRadius ) end ---- Template method to spawn a new representation of the CARBO_BASE in the simulator. --- @param #CARBO_BASE self --- @return #CARBO_BASE -function CARBO_BASE:Spawn( PointVec2 ) +--- Template method to spawn a new representation of the CARGO_BASE in the simulator. +-- @param #CARGO_BASE self +-- @return #CARGO_BASE +function CARGO_BASE:Spawn( PointVec2 ) self:F() end --- Check if CargoCarrier is near the Cargo to be Loaded. --- @param #CARBO_BASE self +-- @param #CARGO_BASE self -- @param Point#POINT_VEC2 PointVec2 -- @return #boolean -function CARBO_BASE:IsNear( PointVec2 ) +function CARGO_BASE:IsNear( PointVec2 ) self:F( { PointVec2 } ) local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) @@ -294,7 +294,7 @@ end do -- CARGO_REPRESENTABLE --- @type CARGO_REPRESENTABLE - -- @extends #CARBO_BASE + -- @extends #CARGO_BASE CARGO_REPRESENTABLE = { ClassName = "CARGO_REPRESENTABLE" } @@ -309,7 +309,7 @@ do -- CARGO_REPRESENTABLE -- @param #number NearRadius (optional) -- @return #CARGO_REPRESENTABLE function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, Weight, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARBO_BASE:New( Type, Name, Weight, ReportRadius, NearRadius ) ) -- #CARBO_BASE + local self = BASE:Inherit( self, CARGO_BASE:New( Type, Name, Weight, ReportRadius, NearRadius ) ) -- #CARGO_BASE self:F( { Type, Name, Weight, ReportRadius, NearRadius } ) @@ -338,7 +338,7 @@ function CARGO_REPRESENTABLE:RouteTo( ToPointVec2, Speed ) return self end -end -- CARBO_BASE +end -- CARGO_BASE do -- CARGO_UNIT @@ -816,7 +816,7 @@ end do -- CARGO_GROUP --- @type CARGO_GROUP - -- @extends Cargo#CARBO_BASE + -- @extends Cargo#CARGO_BASE -- @field Set#SET_BASE CargoSet A set of cargo objects. -- @field #string Name A string defining the name of the cargo group. The name is the unique identifier of the cargo. CARGO_GROUP = { @@ -833,7 +833,7 @@ do -- CARGO_GROUP -- @param #number NearRadius (optional) -- @return #CARGO_GROUP function CARGO_GROUP:New( CargoSet, Type, Name, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARBO_BASE:New( Type, Name, 0, ReportRadius, NearRadius ) ) -- #CARGO_GROUP + local self = BASE:Inherit( self, CARGO_BASE:New( Type, Name, 0, ReportRadius, NearRadius ) ) -- #CARGO_GROUP self:F( { Type, Name, ReportRadius, NearRadius } ) self.CargoSet = CargoSet diff --git a/Moose Development/Moose/Fsm/Patrol.lua b/Moose Development/Moose/Fsm/Patrol.lua index 183e730e5..5a50f78ec 100644 --- a/Moose Development/Moose/Fsm/Patrol.lua +++ b/Moose Development/Moose/Fsm/Patrol.lua @@ -349,7 +349,7 @@ function PATROLZONE:onenterRoute() self.Controllable:SetState( self.Controllable, "PatrolZone", self ) self.Controllable:WayPointFunction( #PatrolRoute, 1, "_NewPatrolRoute" ) - --- NOW ROUTE THE GROUP! + --- NOW PROCESS_ROUTE THE GROUP! self.Controllable:WayPointExecute( 1 ) self:__Patrol( 30 ) diff --git a/Moose Development/Moose/Fsm/Process.lua b/Moose Development/Moose/Fsm/Process.lua index 2429f58e1..a93a17552 100644 --- a/Moose Development/Moose/Fsm/Process.lua +++ b/Moose Development/Moose/Fsm/Process.lua @@ -2,9 +2,9 @@ --- The PROCESS class -- @type PROCESS +-- @field Task#TASK_BASE ProcessTask -- @field Group#GROUP ProcessGroup -- @field Menu#MENU_GROUP MissionMenu --- @field Task#TASK_BASE Task -- @field #string ProcessName -- @extends StateMachine#STATEMACHINE_CONTROLLABLE PROCESS = { @@ -16,8 +16,8 @@ PROCESS = { --- Instantiates a new TASK Base. Should never be used. Interface Class. -- @param #PROCESS self -- @param #string ProcessName --- @param Unit#UNIT ProcessUnit --- @return #PROCESS self +-- @param Unit#UNIT ProcessUnit (Optional) If provided, it defines the UNIT for which the process is running. +-- @return #PROCESS function PROCESS:New( FSMT, ProcessName, ProcessUnit ) local self = BASE:Inherit( self, STATEMACHINE_CONTROLLABLE:New( FSMT, ProcessUnit ) ) self:F() @@ -32,13 +32,50 @@ function PROCESS:New( FSMT, ProcessName, ProcessUnit ) return self end +--- Gets the Group of the process. +-- @param #PROCESS self +-- @return Group#GROUP +function PROCESS:GetGroup() + + return self.ProcessGroup +end + +--- Sets the task of the process. +-- @param #PROCESS self +-- @param Tasking.Task#TASK_BASE ProcessTask +-- @return #PROCESS +function PROCESS:SetTask( ProcessTask ) + + self.ProcessTask = ProcessTask + + return self +end + +--- Gets the task of the process. +-- @param #PROCESS self +-- @return Task#TASK_BASE +function PROCESS:GetTask() + + return self.ProcessTask +end + +--- Gets the mission of the process. +-- @param #PROCESS self +-- @return Mission#MISSION +function PROCESS:GetMission() + + return self.ProcessTask.Mission +end + --- Assign the process to a @{Unit} and activate the process. -- @param #PROCESS self -- @param Unit#UNIT ProcessUnit -- @return #PROCESS self -function PROCESS:Assign( ProcessUnit ) +function PROCESS:Assign( ProcessTask, ProcessUnit ) self:SetControllable( ProcessUnit ) + self:SetTask( ProcessTask ) + self.ProcessGroup = ProcessUnit:GetGroup() --self:Activate() diff --git a/Moose Development/Moose/Fsm/Process_Smoke.lua b/Moose Development/Moose/Fsm/Process_Smoke.lua deleted file mode 100644 index 4bcf480f7..000000000 --- a/Moose Development/Moose/Fsm/Process_Smoke.lua +++ /dev/null @@ -1,109 +0,0 @@ ---- @module Process_Smoke - -do -- PROCESS_SMOKE_TARGETS - - --- PROCESS_SMOKE_TARGETS class - -- @type PROCESS_SMOKE_TARGETS - -- @field Task#TASK_BASE Task - -- @field Unit#UNIT ProcessUnit - -- @field Set#SET_UNIT TargetSetUnit - -- @field Zone#ZONE_BASE TargetZone - -- @extends Task2#TASK2 - PROCESS_SMOKE_TARGETS = { - ClassName = "PROCESS_SMOKE_TARGETS", - } - - - --- 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_SMOKE_TARGETS self - -- @param Task#TASK Task - -- @param Unit#UNIT Unit - -- @return #PROCESS_SMOKE_TARGETS self - function PROCESS_SMOKE_TARGETS:New( Task, ProcessUnit, TargetSetUnit, TargetZone ) - - local FSMT = { - initial = 'None', - events = { - { name = 'Start', from = 'None', to = 'AwaitSmoke' }, - { name = 'Next', from = 'AwaitSmoke', to = 'Smoking' }, - { name = 'Next', from = 'Smoking', to = 'AwaitSmoke' }, - { name = 'Fail', from = 'Smoking', to = 'Failed' }, - { name = 'Fail', from = 'AwaitSmoke', to = 'Failed' }, - { name = 'Fail', from = 'None', to = 'Failed' }, - }, - callbacks = { - onStart = self.OnStart, - onNext = self.OnNext, - onSmoking = self.OnSmoking, - }, - endstates = { - }, - } - - -- Inherits from BASE - local self = BASE:Inherit( self, PROCESS:New( FSMT, ProcessUnit, "SMOKE_TARGETS" ) ) -- #PROCESS_SMOKE_TARGETS - - self.TargetSetUnit = TargetSetUnit - self.TargetZone = TargetZone - - - return self - end - - --- StateMachine callback function - -- @param #PROCESS_SMOKE_TARGETS self - -- @param Controllable#CONTROLLABLE ProcessUnit - -- @param #string Event - -- @param #string From - -- @param #string To - function PROCESS_SMOKE_TARGETS:OnStart( ProcessUnit, Event, From, To ) - self:E( { Event, From, To, ProcessUnit.UnitName} ) - - self:E("Set smoke menu") - - local ProcessGroup = ProcessUnit:GetGroup() - --local MissionMenu = self.Task.Mission:GetMissionMenu( ProcessGroup ) - - local function MenuSmoke( MenuParam ) - self:E( MenuParam ) - local self = MenuParam.self - local SmokeColor = MenuParam.SmokeColor - self.SmokeColor = SmokeColor - self:__Next( 1 ) - end - - --self.Menu = MENU_GROUP:New( ProcessGroup, "Target acquisition", MissionMenu ) - --self.MenuSmokeBlue = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop blue smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Blue } ) - --self.MenuSmokeGreen = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop green smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Green } ) - --self.MenuSmokeOrange = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop Orange smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Orange } ) - --self.MenuSmokeRed = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop Red smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Red } ) - --self.MenuSmokeWhite = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop White smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.White } ) - end - - --- StateMachine callback function - -- @param #PROCESS_SMOKE_TARGETS self - -- @param Controllable#CONTROLLABLE ProcessUnit - -- @param #string Event - -- @param #string From - -- @param #string To - function PROCESS_SMOKE_TARGETS:OnSmoking( ProcessUnit, Event, From, To ) - self:E( { Event, From, To, ProcessUnit.UnitName} ) - - self.TargetSetUnit:ForEachUnit( - --- @param Unit#UNIT SmokeUnit - function( SmokeUnit ) - if math.random( 1, ( 100 * self.TargetSetUnit:Count() ) / 4 ) <= 100 then - SCHEDULER:New( self, - function() - if SmokeUnit:IsAlive() then - SmokeUnit:Smoke( self.SmokeColor, 150 ) - end - end, {}, math.random( 10, 60 ) - ) - end - end - ) - - end - -end \ No newline at end of file diff --git a/Moose Development/Moose/Moose.lua b/Moose Development/Moose/Moose.lua index cf72666e0..685876f1c 100644 --- a/Moose Development/Moose/Moose.lua +++ b/Moose Development/Moose/Moose.lua @@ -39,16 +39,18 @@ Include.File( "Functional/AirbasePolice" ) Include.File( "Functional/Detection" ) Include.File( "Functional/AIBalancer" ) ---- Process Classes +--- Fsm Classes Include.File( "Fsm/Process" ) -Include.File( "Fsm/Assign" ) -Include.File( "Fsm/Route" ) -Include.File( "Fsm/Process_Smoke" ) -Include.File( "Fsm/Account" ) Include.File( "Fsm/Process_JTAC" ) Include.File( "Fsm/Patrol" ) Include.File( "Fsm/Cargo" ) +--- Process Classes +Include.File( "Process/Assign" ) +Include.File( "Process/Route" ) +Include.File( "Process/Account" ) +Include.File( "Process/Smoke" ) + --- Task Handling Classes Include.File( "Tasking/Mission" ) Include.File( "Tasking/Task" ) diff --git a/Moose Development/Moose/Fsm/Account.lua b/Moose Development/Moose/Process/Account.lua similarity index 77% rename from Moose Development/Moose/Fsm/Account.lua rename to Moose Development/Moose/Process/Account.lua index 736e46872..5be525333 100644 --- a/Moose Development/Moose/Fsm/Account.lua +++ b/Moose Development/Moose/Process/Account.lua @@ -2,16 +2,16 @@ -- -- === -- --- # @{#ACCOUNT} FSM class, extends @{Process#PROCESS} +-- # @{#PROCESS_ACCOUNT} FSM class, extends @{Process#PROCESS} -- --- ## ACCOUNT state machine: +-- ## PROCESS_ACCOUNT state machine: -- -- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur. -- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below. -- Each derived class follows exactly the same process, using the same events and following the same state transitions, -- but will have **different implementation behaviour** upon each event or state transition. -- --- ### ACCOUNT **Events**: +-- ### PROCESS_ACCOUNT **Events**: -- -- These are the events defined in this class: -- @@ -21,7 +21,7 @@ -- * **More**: There are more DCS events that need to be accounted for. The process will go back into the Report state. -- * **NoMore**: There are no more DCS events that need to be accounted for. The process will go into the Success state. -- --- ### ACCOUNT **Event methods**: +-- ### PROCESS_ACCOUNT **Event methods**: -- -- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process. -- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine: @@ -29,7 +29,7 @@ -- * **Immediate**: The event method has exactly the name of the event. -- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed. -- --- ### ACCOUNT **States**: +-- ### PROCESS_ACCOUNT **States**: -- -- * **Assigned**: The player is assigned to the task. This is the initialization state for the process. -- * **Waiting**: the process is waiting for a DCS event to occur within the simulator. This state is set automatically. @@ -40,7 +40,7 @@ -- -- (*) End states of the process. -- --- ### ACCOUNT state transition methods: +-- ### PROCESS_ACCOUNT state transition methods: -- -- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state. -- There are 2 moments when state transition methods will be called by the state machine: @@ -55,38 +55,38 @@ -- The state transition method needs to start with the name **OnAfter + the name of the state**. -- These state transition methods need to provide a return value, which is specified at the function description. -- --- # 1) @{#ACCOUNT_DEADS} FSM class, extends @{Account#ACCOUNT} +-- # 1) @{#PROCESS_ACCOUNT_DEADS} FSM class, extends @{Account#PROCESS_ACCOUNT} -- --- The ACCOUNT_DEADS class accounts (detects, counts and reports) successful kills of DCS units. +-- The PROCESS_ACCOUNT_DEADS class accounts (detects, counts and reports) successful kills of DCS units. -- The process is given a @{Set} of units that will be tracked upon successful destruction. -- The process will end after each target has been successfully destroyed. -- Each successful dead will trigger an Account state transition that can be scored, modified or administered. -- -- --- ## ACCOUNT_DEADS constructor: +-- ## PROCESS_ACCOUNT_DEADS constructor: -- --- * @{#ACCOUNT_DEADS.New}(): Creates a new ACCOUNT_DEADS object. +-- * @{#PROCESS_ACCOUNT_DEADS.New}(): Creates a new PROCESS_ACCOUNT_DEADS object. -- -- === -- -- @module Account -do -- ACCOUNT +do -- PROCESS_ACCOUNT - --- ACCOUNT class - -- @type ACCOUNT + --- PROCESS_ACCOUNT class + -- @type PROCESS_ACCOUNT -- @field Set#SET_UNIT TargetSetUnit - -- @extends Process#PROCESS - ACCOUNT = { - ClassName = "ACCOUNT", + -- @extends Fsm.Process#PROCESS + PROCESS_ACCOUNT = { + ClassName = "PROCESS_ACCOUNT", TargetSetUnit = nil, } --- Creates a new DESTROY process. - -- @param #ACCOUNT self - -- @return #ACCOUNT - function ACCOUNT:New() + -- @param #PROCESS_ACCOUNT self + -- @return #PROCESS_ACCOUNT + function PROCESS_ACCOUNT:New() local FSMT = { initial = 'Assigned', @@ -103,7 +103,7 @@ do -- ACCOUNT } -- Inherits from BASE - local self = BASE:Inherit( self, PROCESS:New( FSMT, "ACCOUNT" ) ) -- #ACCOUNT + local self = BASE:Inherit( self, PROCESS:New( FSMT, "PROCESS_ACCOUNT" ) ) -- #PROCESS_ACCOUNT self.DisplayInterval = 30 self.DisplayCount = 30 @@ -117,23 +117,23 @@ do -- ACCOUNT --- Process Events --- StateMachine callback function - -- @param #ACCOUNT self + -- @param #PROCESS_ACCOUNT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ACCOUNT:onafterStart( ProcessUnit, Event, From, To ) + function PROCESS_ACCOUNT:onafterStart( ProcessUnit, Event, From, To ) self:__Wait( 1 ) end --- StateMachine callback function - -- @param #ACCOUNT self + -- @param #PROCESS_ACCOUNT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ACCOUNT:onenterWaiting( ProcessUnit, Event, From, To ) + function PROCESS_ACCOUNT:onenterWaiting( ProcessUnit, Event, From, To ) if self.DisplayCount >= self.DisplayInterval then self:Report() @@ -146,39 +146,39 @@ do -- ACCOUNT end --- StateMachine callback function - -- @param #ACCOUNT self + -- @param #PROCESS_ACCOUNT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ACCOUNT:onafterEvent( ProcessUnit, Event, From, To, Event ) + function PROCESS_ACCOUNT:onafterEvent( ProcessUnit, Event, From, To, Event ) self:__NoMore( 1 ) end -end -- ACCOUNT +end -- PROCESS_ACCOUNT -do -- ACCOUNT_DEADS +do -- PROCESS_ACCOUNT_DEADS - --- ACCOUNT_DEADS class - -- @type ACCOUNT_DEADS + --- PROCESS_ACCOUNT_DEADS class + -- @type PROCESS_ACCOUNT_DEADS -- @field Set#SET_UNIT TargetSetUnit -- @extends Process#PROCESS - ACCOUNT_DEADS = { - ClassName = "ACCOUNT_DEADS", + PROCESS_ACCOUNT_DEADS = { + ClassName = "PROCESS_ACCOUNT_DEADS", TargetSetUnit = nil, } --- Creates a new DESTROY process. - -- @param #ACCOUNT_DEADS self + -- @param #PROCESS_ACCOUNT_DEADS self -- @param Set#SET_UNIT TargetSetUnit -- @param #string TaskName - -- @return #ACCOUNT_DEADS self - function ACCOUNT_DEADS:New( TargetSetUnit, TaskName ) + -- @return #PROCESS_ACCOUNT_DEADS self + function PROCESS_ACCOUNT_DEADS:New( TargetSetUnit, TaskName ) -- Inherits from BASE - local self = BASE:Inherit( self, ACCOUNT:New() ) -- #ACCOUNT_DEADS + local self = BASE:Inherit( self, PROCESS_ACCOUNT:New() ) -- #PROCESS_ACCOUNT_DEADS self.TargetSetUnit = TargetSetUnit self.TaskName = TaskName @@ -191,12 +191,12 @@ do -- ACCOUNT_DEADS --- Process Events --- StateMachine callback function - -- @param #ASSIGN_MENU_ACCEPT self + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ACCOUNT_DEADS:onenterReport( ProcessUnit, Event, From, To ) + function PROCESS_ACCOUNT_DEADS:onenterReport( ProcessUnit, Event, From, To ) local TaskGroup = ProcessUnit:GetGroup() MESSAGE:New( "Your group with assigned " .. self.TaskName .. " task has " .. self.TargetSetUnit:GetUnitTypesText() .. " targets left to be destroyed.", 5, "HQ" ):ToGroup( TaskGroup ) @@ -204,12 +204,12 @@ do -- ACCOUNT_DEADS --- StateMachine callback function - -- @param #ASSIGN_MENU_ACCEPT self + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ACCOUNT_DEADS:onenterAccount( ProcessUnit, Event, From, To, Event ) + function PROCESS_ACCOUNT_DEADS:onenterAccount( ProcessUnit, Event, From, To, Event ) self.TargetSetUnit:Flush() @@ -221,12 +221,12 @@ do -- ACCOUNT_DEADS end --- StateMachine callback function - -- @param #ASSIGN_MENU_ACCEPT self + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ACCOUNT_DEADS:onafterEvent( ProcessUnit, Event, From, To, Event ) + function PROCESS_ACCOUNT_DEADS:onafterEvent( ProcessUnit, Event, From, To, Event ) if self.TargetSetUnit:Count() > 0 then self:__More( 1 ) @@ -237,13 +237,13 @@ do -- ACCOUNT_DEADS --- DCS Events - --- @param #ACCOUNT_DEADS self + --- @param #PROCESS_ACCOUNT_DEADS self -- @param Event#EVENTDATA Event - function ACCOUNT_DEADS:EventDead( Event ) + function PROCESS_ACCOUNT_DEADS:EventDead( Event ) if Event.IniDCSUnit then self:__Event( 1 ) end end -end -- ACCOUNT DEADS \ No newline at end of file +end -- PROCESS_ACCOUNT DEADS \ No newline at end of file diff --git a/Moose Development/Moose/Fsm/Assign.lua b/Moose Development/Moose/Process/Assign.lua similarity index 68% rename from Moose Development/Moose/Fsm/Assign.lua rename to Moose Development/Moose/Process/Assign.lua index 7d5da4baf..4cc51bd00 100644 --- a/Moose Development/Moose/Fsm/Assign.lua +++ b/Moose Development/Moose/Process/Assign.lua @@ -2,16 +2,16 @@ -- -- === -- --- # @{#ASSIGN} FSM class, extends @{Process#PROCESS} +-- # @{#PROCESS_ASSIGN} FSM class, extends @{Process#PROCESS} -- --- ## ASSIGN state machine: +-- ## PROCESS_ASSIGN state machine: -- -- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur. -- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below. -- Each derived class follows exactly the same process, using the same events and following the same state transitions, -- but will have **different implementation behaviour** upon each event or state transition. -- --- ### ASSIGN **Events**: +-- ### PROCESS_ASSIGN **Events**: -- -- These are the events defined in this class: -- @@ -19,7 +19,7 @@ -- * **Assign**: Assign the task. -- * **Reject**: Reject the task.. -- --- ### ASSIGN **Event methods**: +-- ### PROCESS_ASSIGN **Event methods**: -- -- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process. -- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine: @@ -27,7 +27,7 @@ -- * **Immediate**: The event method has exactly the name of the event. -- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed. -- --- ### ASSIGN **States**: +-- ### PROCESS_ASSIGN **States**: -- -- * **UnAssigned**: The player has not accepted the task. -- * **Assigned (*)**: The player has accepted the task. @@ -37,7 +37,7 @@ -- -- (*) End states of the process. -- --- ### ASSIGN state transition methods: +-- ### PROCESS_ASSIGN state transition methods: -- -- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state. -- There are 2 moments when state transition methods will be called by the state machine: @@ -54,49 +54,49 @@ -- -- === -- --- # 1) @{#ASSIGN_ACCEPT} class, extends @{Assign#ASSIGN} +-- # 1) @{#PROCESS_ASSIGN_ACCEPT} class, extends @{Assign#PROCESS_ASSIGN} -- --- The ASSIGN_ACCEPT class accepts by default a task for a player. No player intervention is allowed to reject the task. +-- The PROCESS_ASSIGN_ACCEPT class accepts by default a task for a player. No player intervention is allowed to reject the task. -- --- ## 1.1) ASSIGN_ACCEPT constructor: +-- ## 1.1) PROCESS_ASSIGN_ACCEPT constructor: -- --- * @{#ASSIGN_ACCEPT.New}(): Creates a new ASSIGN_ACCEPT object. +-- * @{#PROCESS_ASSIGN_ACCEPT.New}(): Creates a new PROCESS_ASSIGN_ACCEPT object. -- -- === -- --- # 2) @{#ASSIGN_MENU_ACCEPT} class, extends @{Assign#ASSIGN} +-- # 2) @{#PROCESS_ASSIGN_MENU_ACCEPT} class, extends @{Assign#PROCESS_ASSIGN} -- --- The ASSIGN_MENU_ACCEPT class accepts a task when the player accepts the task through an added menu option. +-- The PROCESS_ASSIGN_MENU_ACCEPT class accepts a task when the player accepts the task through an added menu option. -- This assignment type is useful to conditionally allow the player to choose whether or not he would accept the task. -- The assignment type also allows to reject the task. -- --- ## 2.1) ASSIGN_MENU_ACCEPT constructor: +-- ## 2.1) PROCESS_ASSIGN_MENU_ACCEPT constructor: -- ----------------------------------------- -- --- * @{#ASSIGN_MENU_ACCEPT.New}(): Creates a new ASSIGN_MENU_ACCEPT object. +-- * @{#PROCESS_ASSIGN_MENU_ACCEPT.New}(): Creates a new PROCESS_ASSIGN_MENU_ACCEPT object. -- -- === -- -- @module Assign -do -- ASSIGN +do -- PROCESS_ASSIGN - --- ASSIGN class - -- @type ASSIGN + --- PROCESS_ASSIGN class + -- @type PROCESS_ASSIGN -- @field Task#TASK_BASE Task -- @field Unit#UNIT ProcessUnit -- @field Zone#ZONE_BASE TargetZone - -- @extends Process#PROCESS - ASSIGN = { - ClassName = "ASSIGN", + -- @extends Fsm.Process#PROCESS + PROCESS_ASSIGN = { + ClassName = "PROCESS_ASSIGN", } --- Creates a new task assignment state machine. The process will accept the task by default, no player intervention accepted. - -- @param #ASSIGN self - -- @return #ASSIGN The task acceptance process. - function ASSIGN:New() + -- @param #PROCESS_ASSIGN self + -- @return #PROCESS_ASSIGN The task acceptance process. + function PROCESS_ASSIGN:New() local FSMT = { initial = 'UnAssigned', @@ -112,36 +112,36 @@ do -- ASSIGN } -- Inherits from BASE - local self = BASE:Inherit( self, PROCESS:New( FSMT, "ASSIGN" ) ) -- #ASSIGN + local self = BASE:Inherit( self, PROCESS:New( FSMT, "PROCESS_ASSIGN" ) ) -- #PROCESS_ASSIGN return self end -end -- ASSIGN +end -- PROCESS_ASSIGN -do -- ASSIGN_ACCEPT +do -- PROCESS_ASSIGN_ACCEPT - --- ASSIGN_ACCEPT class - -- @type ASSIGN_ACCEPT + --- PROCESS_ASSIGN_ACCEPT class + -- @type PROCESS_ASSIGN_ACCEPT -- @field Task#TASK_BASE Task -- @field Unit#UNIT ProcessUnit -- @field Zone#ZONE_BASE TargetZone -- @extends Process#PROCESS - ASSIGN_ACCEPT = { - ClassName = "ASSIGN_ACCEPT", + PROCESS_ASSIGN_ACCEPT = { + ClassName = "PROCESS_ASSIGN_ACCEPT", } --- Creates a new task assignment state machine. The process will accept the task by default, no player intervention accepted. - -- @param #ASSIGN_ACCEPT self + -- @param #PROCESS_ASSIGN_ACCEPT self -- @param #string TaskBriefing - -- @return #ASSIGN_ACCEPT The task acceptance process. - function ASSIGN_ACCEPT:New( TaskBriefing ) + -- @return #PROCESS_ASSIGN_ACCEPT The task acceptance process. + function PROCESS_ASSIGN_ACCEPT:New( TaskBriefing ) -- Inherits from BASE - local self = BASE:Inherit( self, ASSIGN:New() ) -- #ASSIGN_ACCEPT + local self = BASE:Inherit( self, PROCESS_ASSIGN:New() ) -- #PROCESS_ASSIGN_ACCEPT self.TaskBriefing = TaskBriefing @@ -150,12 +150,12 @@ do -- ASSIGN_ACCEPT --- StateMachine callback function - -- @param #ASSIGN_ACCEPT self + -- @param #PROCESS_ASSIGN_ACCEPT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ASSIGN_ACCEPT:onafterStart( ProcessUnit, Event, From, To ) + function PROCESS_ASSIGN_ACCEPT:onafterStart( ProcessUnit, Event, From, To ) self:E( { ProcessUnit, Event, From, To } ) MESSAGE:New( self.TaskBriefing, 30, "Task Assignment" ):ToGroup( ProcessUnit:GetGroup() ) @@ -163,31 +163,31 @@ do -- ASSIGN_ACCEPT self:__Assign( 1 ) end -end -- ASSIGN_ACCEPT +end -- PROCESS_ASSIGN_ACCEPT -do -- ASSIGN_MENU_ACCEPT +do -- PROCESS_ASSIGN_MENU_ACCEPT - --- ASSIGN_MENU_ACCEPT class - -- @type ASSIGN_MENU_ACCEPT + --- PROCESS_ASSIGN_MENU_ACCEPT class + -- @type PROCESS_ASSIGN_MENU_ACCEPT -- @field Task#TASK_BASE Task -- @field Unit#UNIT ProcessUnit -- @field Zone#ZONE_BASE TargetZone - -- @extends Task2#TASK2 - ASSIGN_MENU_ACCEPT = { - ClassName = "ASSIGN_MENU_ACCEPT", + -- @extends #PROCESS_ASSIGN + PROCESS_ASSIGN_MENU_ACCEPT = { + ClassName = "PROCESS_ASSIGN_MENU_ACCEPT", } --- 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 #ASSIGN_MENU_ACCEPT self + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self -- @param #string TaskName -- @param #string TaskBriefing - -- @return #ASSIGN_MENU_ACCEPT self - function ASSIGN_MENU_ACCEPT:New( TaskName, TaskBriefing ) + -- @return #PROCESS_ASSIGN_MENU_ACCEPT self + function PROCESS_ASSIGN_MENU_ACCEPT:New( TaskName, TaskBriefing ) -- Inherits from BASE - local self = BASE:Inherit( self, ASSIGN:New() ) -- #ASSIGN_MENU_ACCEPT + local self = BASE:Inherit( self, PROCESS_ASSIGN:New() ) -- #PROCESS_ASSIGN_MENU_ACCEPT self.TaskBriefing = TaskBriefing self.TaskName = TaskName @@ -196,12 +196,12 @@ do -- ASSIGN_MENU_ACCEPT end --- StateMachine callback function - -- @param #ASSIGN_MENU_ACCEPT self + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ASSIGN_MENU_ACCEPT:onafterStart( ProcessUnit, Event, From, To ) + function PROCESS_ASSIGN_MENU_ACCEPT:onafterStart( ProcessUnit, Event, From, To ) self:E( { ProcessUnit, Event, From, To } ) MESSAGE:New( self.TaskBriefing .. "\nAccess the radio menu to accept the task. You have 30 seconds or the assignment will be cancelled.", 30, "Task Assignment" ):ToGroup( ProcessUnit:GetGroup() ) @@ -214,40 +214,40 @@ do -- ASSIGN_MENU_ACCEPT end --- Menu function. - -- @param #ASSIGN_MENU_ACCEPT self - function ASSIGN_MENU_ACCEPT:MenuAssign() + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self + function PROCESS_ASSIGN_MENU_ACCEPT:MenuAssign() self:E( ) self:__Assign( 1 ) end --- Menu function. - -- @param #ASSIGN_MENU_ACCEPT self - function ASSIGN_MENU_ACCEPT:MenuReject() + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self + function PROCESS_ASSIGN_MENU_ACCEPT:MenuReject() self:E( ) self:__Reject( 1 ) end --- StateMachine callback function - -- @param #ASSIGN_MENU_ACCEPT self + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ASSIGN_MENU_ACCEPT:onafterAssign( ProcessUnit, Event, From, To ) + function PROCESS_ASSIGN_MENU_ACCEPT:onafterAssign( ProcessUnit, Event, From, To ) self:E( { ProcessUnit.UnitNameEvent, From, To } ) self.Menu:Remove() end --- StateMachine callback function - -- @param #ASSIGN_MENU_ACCEPT self + -- @param #PROCESS_ASSIGN_MENU_ACCEPT self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ASSIGN_MENU_ACCEPT:onafterReject( ProcessUnit, Event, From, To ) + function PROCESS_ASSIGN_MENU_ACCEPT:onafterReject( ProcessUnit, Event, From, To ) self:E( { ProcessUnit.UnitName, Event, From, To } ) self.Menu:Remove() @@ -256,4 +256,4 @@ do -- ASSIGN_MENU_ACCEPT ProcessUnit:Destroy() end -end -- ASSIGN_MENU_ACCEPT +end -- PROCESS_ASSIGN_MENU_ACCEPT diff --git a/Moose Development/Moose/Fsm/Route.lua b/Moose Development/Moose/Process/Route.lua similarity index 78% rename from Moose Development/Moose/Fsm/Route.lua rename to Moose Development/Moose/Process/Route.lua index 69287d868..482f070a4 100644 --- a/Moose Development/Moose/Fsm/Route.lua +++ b/Moose Development/Moose/Process/Route.lua @@ -2,16 +2,16 @@ -- -- === -- --- # @{#ROUTE} FSM class, extends @{Process#PROCESS} +-- # @{#PROCESS_ROUTE} FSM class, extends @{Process#PROCESS} -- --- ## ROUTE state machine: +-- ## PROCESS_ROUTE state machine: -- -- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur. -- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below. -- Each derived class follows exactly the same process, using the same events and following the same state transitions, -- but will have **different implementation behaviour** upon each event or state transition. -- --- ### ROUTE **Events**: +-- ### PROCESS_ROUTE **Events**: -- -- These are the events defined in this class: -- @@ -23,7 +23,7 @@ -- * **More**: There are more route points that need to be followed. The process will go back into the Report state. -- * **NoMore**: There are no more route points that need to be followed. The process will go into the Success state. -- --- ### ROUTE **Event methods**: +-- ### PROCESS_ROUTE **Event methods**: -- -- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process. -- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine: @@ -31,7 +31,7 @@ -- * **Immediate**: The event method has exactly the name of the event. -- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed. -- --- ### ROUTE **States**: +-- ### PROCESS_ROUTE **States**: -- -- * **None**: The controllable did not receive route commands. -- * **Arrived (*)**: The controllable has arrived at a route point. @@ -43,7 +43,7 @@ -- -- (*) End states of the process. -- --- ### ROUTE state transition methods: +-- ### PROCESS_ROUTE state transition methods: -- -- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state. -- There are 2 moments when state transition methods will be called by the state machine: @@ -60,38 +60,38 @@ -- -- === -- --- # 1) @{#ROUTE_ZONE} class, extends @{Route#ROUTE} +-- # 1) @{#PROCESS_ROUTE_ZONE} class, extends @{Route#PROCESS_ROUTE} -- --- The ROUTE_ZONE class implements the core functions to route an AIR @{Controllable} player @{Unit} to a @{Zone}. +-- The PROCESS_ROUTE_ZONE class implements the core functions to route an AIR @{Controllable} player @{Unit} to a @{Zone}. -- The player receives on perioding times messages with the coordinates of the route to follow. -- Upon arrival at the zone, a confirmation of arrival is sent, and the process will be ended. -- --- # 1.1) ROUTE_ZONE constructor: +-- # 1.1) PROCESS_ROUTE_ZONE constructor: -- --- * @{#ROUTE_ZONE.New}(): Creates a new ROUTE_ZONE object. +-- * @{#PROCESS_ROUTE_ZONE.New}(): Creates a new PROCESS_ROUTE_ZONE object. -- -- === -- -- @module Route -do -- ROUTE +do -- PROCESS_ROUTE - --- ROUTE class - -- @type ROUTE + --- PROCESS_ROUTE class + -- @type PROCESS_ROUTE -- @field Task#TASK TASK -- @field Unit#UNIT ProcessUnit -- @field Zone#ZONE_BASE TargetZone - -- @extends Task2#TASK2 - ROUTE = { - ClassName = "ROUTE", + -- @extends Fsm.Process#PROCESS + PROCESS_ROUTE = { + ClassName = "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 #ROUTE self - -- @return #ROUTE self - function ROUTE:New() + --- Creates a new routing state machine. The process will route a CLIENT to a ZONE until the CLIENT is within that ZONE. + -- @param #PROCESS_ROUTE self + -- @return #PROCESS_ROUTE self + function PROCESS_ROUTE:New() local FSMT = { @@ -112,7 +112,7 @@ do -- ROUTE } -- Inherits from BASE - local self = BASE:Inherit( self, PROCESS:New( FSMT, "ROUTE" ) ) -- #ROUTE + local self = BASE:Inherit( self, PROCESS:New( FSMT, "PROCESS_ROUTE" ) ) -- #PROCESS_ROUTE self.DisplayInterval = 30 self.DisplayCount = 30 @@ -126,31 +126,31 @@ do -- ROUTE --- Task Events --- StateMachine callback function - -- @param #ROUTE self + -- @param #PROCESS_ROUTE self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ROUTE:onafterStart( ProcessUnit, Event, From, To ) + function PROCESS_ROUTE:onafterStart( ProcessUnit, Event, From, To ) self:__Route( 1 ) end --- Check if the controllable has arrived. - -- @param #ROUTE self + -- @param #PROCESS_ROUTE self -- @param Controllable#CONTROLLABLE ProcessUnit -- @return #boolean - function ROUTE:HasArrived( ProcessUnit ) + function PROCESS_ROUTE:HasArrived( ProcessUnit ) return false end --- StateMachine callback function - -- @param #ROUTE self + -- @param #PROCESS_ROUTE self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ROUTE:onafterRoute( ProcessUnit, Event, From, To ) + function PROCESS_ROUTE:onafterRoute( ProcessUnit, Event, From, To ) if ProcessUnit:IsAlive() then local HasArrived = self:HasArrived( ProcessUnit ) @@ -174,30 +174,30 @@ do -- ROUTE end -end -- ROUTE +end -- PROCESS_ROUTE -do -- ROUTE_ZONE +do -- PROCESS_ROUTE_ZONE - --- ROUTE_ZONE class - -- @type ROUTE_ZONE + --- PROCESS_ROUTE_ZONE class + -- @type PROCESS_ROUTE_ZONE -- @field Task#TASK TASK -- @field Unit#UNIT ProcessUnit -- @field Zone#ZONE_BASE TargetZone - -- @extends Task2#TASK2 - ROUTE_ZONE = { - ClassName = "ROUTE_ZONE", + -- @extends Process.Route#PROCESS_ROUTE + PROCESS_ROUTE_ZONE = { + ClassName = "PROCESS_ROUTE_ZONE", } --- Creates a new routing state machine. The task will route a controllable to a ZONE until the controllable is within that ZONE. - -- @param #ROUTE_ZONE self + -- @param #PROCESS_ROUTE_ZONE self -- @param Zone#ZONE_BASE TargetZone - -- @return #ROUTE_ZONE self - function ROUTE_ZONE:New( TargetZone ) + -- @return #PROCESS_ROUTE_ZONE self + function PROCESS_ROUTE_ZONE:New( TargetZone ) - local self = BASE:Inherit( self, ROUTE:New() ) -- #ROUTE_ZONE + local self = BASE:Inherit( self, PROCESS_ROUTE:New() ) -- #PROCESS_ROUTE_ZONE self.TargetZone = TargetZone @@ -205,22 +205,22 @@ do -- ROUTE_ZONE end --- Method override to check if the controllable has arrived. - -- @param #ROUTE self + -- @param #PROCESS_ROUTE self -- @param Controllable#CONTROLLABLE ProcessUnit -- @return #boolean - function ROUTE_ZONE:HasArrived( ProcessUnit ) + function PROCESS_ROUTE_ZONE:HasArrived( ProcessUnit ) return ProcessUnit:IsInZone( self.TargetZone ) end --- Task Events --- StateMachine callback function - -- @param #ROUTE_ZONE self + -- @param #PROCESS_ROUTE_ZONE self -- @param Controllable#CONTROLLABLE ProcessUnit -- @param #string Event -- @param #string From -- @param #string To - function ROUTE_ZONE:onenterReporting( ProcessUnit, Event, From, To ) + function PROCESS_ROUTE_ZONE:onenterReporting( ProcessUnit, Event, From, To ) local ZoneVec2 = self.TargetZone:GetVec2() local ZonePointVec2 = POINT_VEC2:New( ZoneVec2.x, ZoneVec2.y ) @@ -230,4 +230,4 @@ do -- ROUTE_ZONE MESSAGE:New( RouteText, self.DisplayTime, self.DisplayCategory ):ToGroup( ProcessUnit:GetGroup() ) end -end -- ROUTE_ZONE +end -- PROCESS_ROUTE_ZONE diff --git a/Moose Development/Moose/Process/Smoke.lua b/Moose Development/Moose/Process/Smoke.lua new file mode 100644 index 000000000..c203e08f9 --- /dev/null +++ b/Moose Development/Moose/Process/Smoke.lua @@ -0,0 +1,188 @@ +--- (SP) (MP) (FSM) Route AI or players through waypoints or to zones. +-- +-- === +-- +-- # @{#PROCESS_SMOKE} FSM class, extends @{Process#PROCESS} +-- +-- ## PROCESS_SMOKE state machine: +-- +-- This class is a state machine: it manages a process that is triggered by events causing state transitions to occur. +-- All derived classes from this class will start with the class name, followed by a \_. See the relevant derived class descriptions below. +-- Each derived class follows exactly the same process, using the same events and following the same state transitions, +-- but will have **different implementation behaviour** upon each event or state transition. +-- +-- ### PROCESS_SMOKE **Events**: +-- +-- These are the events defined in this class: +-- +-- * **Start**: The process is started. +-- * **Next**: The process is smoking the targets in the given zone. +-- +-- ### PROCESS_SMOKE **Event methods**: +-- +-- Event methods are available (dynamically allocated by the state machine), that accomodate for state transitions occurring in the process. +-- There are two types of event methods, which you can use to influence the normal mechanisms in the state machine: +-- +-- * **Immediate**: The event method has exactly the name of the event. +-- * **Delayed**: The event method starts with a __ + the name of the event. The first parameter of the event method is a number value, expressing the delay in seconds when the event will be executed. +-- +-- ### PROCESS_SMOKE **States**: +-- +-- * **None**: The controllable did not receive route commands. +-- * **AwaitSmoke (*)**: The process is awaiting to smoke the targets in the zone. +-- * **Smoking (*)**: The process is smoking the targets in the zone. +-- * **Failed (*)**: The process has failed. +-- +-- (*) End states of the process. +-- +-- ### PROCESS_SMOKE state transition methods: +-- +-- State transition functions can be set **by the mission designer** customizing or improving the behaviour of the state. +-- There are 2 moments when state transition methods will be called by the state machine: +-- +-- * **Before** the state transition. +-- The state transition method needs to start with the name **OnBefore + the name of the state**. +-- If the state transition method returns false, then the processing of the state transition will not be done! +-- If you want to change the behaviour of the AIControllable at this event, return false, +-- but then you'll need to specify your own logic using the AIControllable! +-- +-- * **After** the state transition. +-- The state transition method needs to start with the name **OnAfter + the name of the state**. +-- These state transition methods need to provide a return value, which is specified at the function description. +-- +-- === +-- +-- # 1) @{#PROCESS_SMOKE_TARGETS_ZONE} class, extends @{Route#PROCESS_SMOKE} +-- +-- The PROCESS_SMOKE_TARGETS_ZONE class implements the core functions to smoke targets in a @{Zone}. +-- The targets are smoked within a certain range around each target, simulating a realistic smoking behaviour. +-- At random intervals, a new target is smoked. +-- +-- # 1.1) PROCESS_SMOKE_TARGETS_ZONE constructor: +-- +-- * @{#PROCESS_SMOKE_TARGETS_ZONE.New}(): Creates a new PROCESS_SMOKE_TARGETS_ZONE object. +-- +-- === +-- +-- @module Smoke + +do -- PROCESS_SMOKE + + --- PROCESS_SMOKE class + -- @type PROCESS_SMOKE + -- @extends Fsm.Process#PROCESS + PROCESS_SMOKE = { + ClassName = "PROCESS_SMOKE", + } + + --- 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. + -- @param #PROCESS_SMOKE self + -- @return #PROCESS_SMOKE + function PROCESS_SMOKE:New() + + local FSMT = { + initial = 'None', + events = { + { name = 'Start', from = 'None', to = 'AwaitSmoke' }, + { name = 'Next', from = 'AwaitSmoke', to = 'Smoking' }, + { name = 'Next', from = 'Smoking', to = 'AwaitSmoke' }, + { name = 'Stop', from = '*', to = 'Success' }, + { name = 'Fail', from = 'Smoking', to = 'Failed' }, + { name = 'Fail', from = 'AwaitSmoke', to = 'Failed' }, + { name = 'Fail', from = 'None', to = 'Failed' }, + }, + endstates = { + 'Failed', 'Success' + }, + } + + -- Inherits from BASE + local self = BASE:Inherit( self, PROCESS:New( FSMT, "PROCESS_SMOKE" ) ) -- #PROCESS_SMOKE + + return self + end + + --- Task Events + + --- StateMachine callback function + -- @param #PROCESS_SMOKE self + -- @param Controllable#CONTROLLABLE ProcessUnit + -- @param #string Event + -- @param #string From + -- @param #string To + function PROCESS_SMOKE:onafterStart( ProcessUnit, Event, From, To ) + + local ProcessGroup = self:GetGroup() + local MissionMenu = self:GetMission():GetMissionMenu( ProcessGroup ) + + local function MenuSmoke( MenuParam ) + self:E( MenuParam ) + local self = MenuParam.self + local SmokeColor = MenuParam.SmokeColor + self.SmokeColor = SmokeColor + self:__Next( 1 ) + end + + self.Menu = MENU_GROUP:New( ProcessGroup, "Target acquisition", MissionMenu ) + self.MenuSmokeBlue = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop blue smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Blue } ) + self.MenuSmokeGreen = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop green smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Green } ) + self.MenuSmokeOrange = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop Orange smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Orange } ) + self.MenuSmokeRed = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop Red smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.Red } ) + self.MenuSmokeWhite = MENU_GROUP_COMMAND:New( ProcessGroup, "Drop White smoke on targets", self.Menu, MenuSmoke, { self = self, SmokeColor = SMOKECOLOR.White } ) + end + +end + +do -- PROCESS_SMOKE_TARGETS_ZONE + + --- PROCESS_SMOKE_TARGETS_ZONE class + -- @type PROCESS_SMOKE_TARGETS_ZONE + -- @field Set#SET_UNIT TargetSetUnit + -- @field Zone#ZONE_BASE TargetZone + -- @extends #PROCESS_SMOKE + PROCESS_SMOKE_TARGETS_ZONE = { + ClassName = "PROCESS_SMOKE_TARGETS_ZONE", + } + + + --- 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. + -- @param #PROCESS_SMOKE_TARGETS_ZONE self + -- @param Set#SET_UNIT TargetSetUnit + -- @param Zone#ZONE_BASE TargetZone + -- @return #PROCESS_SMOKE_TARGETS_ZONE self + function PROCESS_SMOKE_TARGETS_ZONE:New( TargetSetUnit, TargetZone ) + + local self = BASE:Inherit( self, PROCESS_SMOKE:New() ) -- #PROCESS_SMOKE + + self.TargetSetUnit = TargetSetUnit + self.TargetZone = TargetZone + + return self + end + + --- StateMachine callback function + -- @param #PROCESS_SMOKE_TARGETS_ZONE self + -- @param Controllable#CONTROLLABLE ProcessUnit + -- @param #string Event + -- @param #string From + -- @param #string To + function PROCESS_SMOKE_TARGETS_ZONE:onenterSmoking( ProcessUnit, Event, From, To ) + + self.TargetSetUnit:ForEachUnit( + --- @param Unit#UNIT SmokeUnit + function( SmokeUnit ) + if math.random( 1, ( 100 * self.TargetSetUnit:Count() ) / 4 ) <= 100 then + SCHEDULER:New( self, + function() + if SmokeUnit:IsAlive() then + SmokeUnit:Smoke( self.SmokeColor, 150 ) + end + end, {}, math.random( 10, 60 ) + ) + end + end + ) + + end + +end \ No newline at end of file diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index 686e92c3d..1744c7a99 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -55,7 +55,7 @@ -- @field Mission#MISSION Mission -- @field StateMachine#STATEMACHINE Fsm -- @field Set#SET_GROUP SetGroup The Set of Groups assigned to the Task --- @extends Base#BASE +-- @extends Core.Base#BASE TASK_BASE = { ClassName = "TASK_BASE", TaskScheduler = nil, @@ -418,8 +418,9 @@ function TASK_BASE:AssignProcess( ProcessUnit, ProcessName ) ProcessTemplate = self:GetProcessTemplate( ProcessName ) self:E( "Deepcopy" ) - local Process = UTILS.DeepCopy( ProcessTemplate ) -- Process#PROCESS - Process:Assign( ProcessUnit ) + -- This statement copies the process template assigned to the task and creates a new process. + local Process = UTILS.DeepCopy( ProcessTemplate ) -- Fsm.Process#PROCESS + Process:Assign( self, ProcessUnit ) self.Processes = self.Processes or {} self.Processes[ProcessUnitName] = self.Processes[ProcessUnitName] or {} diff --git a/Moose Development/Moose/Tasking/Task_A2G.lua b/Moose Development/Moose/Tasking/Task_A2G.lua index ec1a94e01..8dad3d9cf 100644 --- a/Moose Development/Moose/Tasking/Task_A2G.lua +++ b/Moose Development/Moose/Tasking/Task_A2G.lua @@ -23,7 +23,7 @@ do -- TASK_A2G --- The TASK_A2G class -- @type TASK_A2G - -- @extends Task#TASK_BASE + -- @extends Tasking.Task#TASK_BASE TASK_A2G = { ClassName = "TASK_A2G", } @@ -45,6 +45,13 @@ do -- TASK_A2G self.TargetZone = TargetZone self.FACUnit = FACUnit + self:SetProcessTemplate( "PROCESS_ASSIGN", PROCESS_ASSIGN_ACCEPT:New( self.TaskBriefing ) ) + self:SetProcessTemplate( "PROCESS_ROUTE", PROCESS_ROUTE_ZONE:New( self.TargetZone ) ) + self:SetProcessTemplate( "PROCESS_ACCOUNT", PROCESS_ACCOUNT_DEADS:New( self.TargetSetUnit, "A2G" ) ) + + local ProcessSmoke = self:AddProcess( TaskUnit, PROCESS_SMOKE_TARGETS_ZONE:New( self, TaskUnit, self.TargetSetUnit, self.TargetZone ) ) + local ProcessJTAC = self:AddProcess( TaskUnit, PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) ) + _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self ) _EVENTDISPATCHER:OnDead( self._EventDead, self ) _EVENTDISPATCHER:OnCrash( self._EventDead, self ) @@ -71,11 +78,11 @@ do -- TASK_A2G function TASK_A2G:AssignToUnit( TaskUnit ) self:F( TaskUnit:GetName() ) - local ProcessAssign = self:AddProcess( TaskUnit, PROCESS_ASSIGN_ACCEPT:New( self, TaskUnit, self.TaskBriefing ) ) - local ProcessRoute = self:AddProcess( TaskUnit, PROCESS_ROUTE:New( self, TaskUnit, self.TargetZone ) ) - local ProcessDestroy = self:AddProcess( TaskUnit, PROCESS_DESTROY:New( self, self.TaskType, TaskUnit, self.TargetSetUnit ) ) - local ProcessSmoke = self:AddProcess( TaskUnit, PROCESS_SMOKE_TARGETS:New( self, TaskUnit, self.TargetSetUnit, self.TargetZone ) ) - local ProcessJTAC = self:AddProcess( TaskUnit, PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) ) + local ProcessAssign = self:AssignProcess( TaskUnit, "PROCESS_ASSIGN" ) + local ProcessRoute = self:AssignProcess( TaskUnit, "PROCESS_ROUTE" ) + local ProcessDestroy = self:AssignProcess( TaskUnit, "PROCESS_ACCOUNT" ) + --local ProcessSmoke = self:AddProcess( TaskUnit, PROCESS_SMOKE_TARGETS_ZONE:New( self, TaskUnit, self.TargetSetUnit, self.TargetZone ) ) + --local ProcessJTAC = self:AddProcess( TaskUnit, PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) ) local Process = self:AddStateMachine( TaskUnit, STATEMACHINE_TASK:New( self, TaskUnit, { initial = 'None', diff --git a/Moose Development/Moose/Tasking/Task_SEAD.lua b/Moose Development/Moose/Tasking/Task_SEAD.lua index 8cd4fce1b..3e6a46e10 100644 --- a/Moose Development/Moose/Tasking/Task_SEAD.lua +++ b/Moose Development/Moose/Tasking/Task_SEAD.lua @@ -25,7 +25,7 @@ do -- TASK_SEAD --- The TASK_SEAD class -- @type TASK_SEAD -- @field Set#SET_UNIT TargetSetUnit - -- @extends Task#TASK_BASE + -- @extends Tasking.Task#TASK_BASE TASK_SEAD = { ClassName = "TASK_SEAD", } @@ -45,13 +45,11 @@ do -- TASK_SEAD self.TargetSetUnit = TargetSetUnit self.TargetZone = TargetZone - self:SetProcessTemplate( "ASSIGN", ASSIGN_ACCEPT:New( self.TaskBriefing ) ) - self:SetProcessTemplate( "ROUTE", ROUTE_ZONE:New( self.TargetZone ) ) - self:SetProcessTemplate( "ACCOUNT", ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ) ) + self:SetProcessTemplate( "ASSIGN", PROCESS_ASSIGN_ACCEPT:New( self.TaskBriefing ) ) + self:SetProcessTemplate( "ROUTE", PROCESS_ROUTE_ZONE:New( self.TargetZone ) ) + self:SetProcessTemplate( "ACCOUNT", PROCESS_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ) ) + self:SetProcessTemplate( "SMOKE", PROCESS_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) ) - -- SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) - --self:SetProcessClass( "SMOKE", SMOKE_TARGETS_ZONE, self.TargetSetUnit, self.TargetZone ) - _EVENTDISPATCHER:OnPlayerLeaveUnit( self._EventPlayerLeaveUnit, self ) _EVENTDISPATCHER:OnDead( self._EventDead, self ) _EVENTDISPATCHER:OnCrash( self._EventDead, self ) @@ -81,8 +79,8 @@ do -- TASK_SEAD local ProcessAssign = self:AssignProcess( TaskUnit, "ASSIGN" ) local ProcessRoute = self:AssignProcess( TaskUnit, "ROUTE" ) - local ProcessSEAD = self:AssignProcess( TaskUnit, "ACCOUNT" ) - --local ProcessSmoke = self:AssignProcess( TaskUnit, "SMOKE" ) + local ProcessAccount = self:AssignProcess( TaskUnit, "ACCOUNT" ) + local ProcessSmoke = self:AssignProcess( TaskUnit, "SMOKE" ) local FSMT = { initial = 'None', @@ -97,8 +95,8 @@ do -- TASK_SEAD subs = { Assign = { onstateparent = 'Planned', oneventparent = 'Next', fsm = ProcessAssign, event = 'Start', returnevents = { 'Next', 'Reject' } }, Route = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessRoute, event = 'Start' }, - Sead = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessSEAD, event = 'Start', returnevents = { 'Next' } }, - --Smoke = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessSmoke, event = 'Start', } + Sead = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessAccount, event = 'Start', returnevents = { 'Next' } }, + Smoke = { onstateparent = 'Assigned', oneventparent = 'Next', fsm = ProcessSmoke, event = 'Start', } } } diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 36374374b..dc91512e7 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -968,7 +968,7 @@ function CONTROLLABLE:TaskFAC_AttackGroup( AttackGroup, WeaponType, Designation, return DCSTask end --- EN-ROUTE TASKS FOR AIRBORNE CONTROLLABLES +-- EN-PROCESS_ROUTE TASKS FOR AIRBORNE CONTROLLABLES --- (AIR) Engaging targets of defined types. -- @param #CONTROLLABLE self diff --git a/Moose Development/Old/Stage.lua b/Moose Development/Old/Stage.lua index 2a08e1820..b283eab03 100644 --- a/Moose Development/Old/Stage.lua +++ b/Moose Development/Old/Stage.lua @@ -915,7 +915,7 @@ end _TransportStage: Defines the different stages of which of transport missions can be in. This table is internal and is used to control the sequence of messages, actions and flow. - _TransportStage.START - - _TransportStage.ROUTE + - _TransportStage.PROCESS_ROUTE - _TransportStage.LAND - _TransportStage.EXECUTE - _TransportStage.DONE @@ -924,7 +924,7 @@ end _TransportStage = { HOLD = "HOLD", START = "START", - ROUTE = "ROUTE", + PROCESS_ROUTE = "PROCESS_ROUTE", LANDING = "LANDING", LANDED = "LANDED", EXECUTING = "EXECUTING", @@ -937,7 +937,7 @@ _TransportStage = { _TransportStageMsgTime = { HOLD = 10, START = 60, - ROUTE = 5, + PROCESS_ROUTE = 5, LANDING = 10, LANDED = 30, EXECUTING = 30, @@ -950,7 +950,7 @@ _TransportStageMsgTime = { _TransportStageTime = { HOLD = 10, START = 5, - ROUTE = 5, + PROCESS_ROUTE = 5, LANDING = 1, LANDED = 1, EXECUTING = 5, 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 3bfb57142..c644de7cc 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 @@ -15,13 +15,10 @@ local TaskSEAD = TASK_SEAD TaskSEAD:AddScore( "Success", "Destroyed all target radars", 250 ) TaskSEAD:AddScore( "Failed", "Failed to destroy all target radars", -100 ) --- ASSIGN_MENU_ACCEPT:New(TaskName,TaskBriefing) -local AssignProcess = TaskSEAD:SetProcessTemplate( "ASSIGN", ASSIGN_MENU_ACCEPT:New( "SEAD", "Hello World" ) ) ---local AssignProcess = TaskSEAD:SetProcessClass( "ASSIGN", ASSIGN_MENU_ACCEPT, "SEAD", "Hello World" ) +local AssignProcess = TaskSEAD:SetProcessTemplate( "ASSIGN", PROCESS_ASSIGN_MENU_ACCEPT:New( "SEAD", "Hello World" ) ) AssignProcess:AddScore( TaskSEAD, "Assign", "You are assigned to the task", 10 ) --- ACCOUNT_DEADS:New(ProcessUnit,TargetSetUnit,TaskName) -local AccountProcess = TaskSEAD:SetProcessTemplate( "ACCOUNT", ACCOUNT_DEADS:New( TargetSet, "SEAD" ) ) +local AccountProcess = TaskSEAD:SetProcessTemplate( "ACCOUNT", PROCESS_ACCOUNT_DEADS:New( TargetSet, "SEAD" ) ) AccountProcess:AddScore( TaskSEAD, "Account", "destroyed a radar", 25 ) AccountProcess:AddScore( TaskSEAD, "Failed", "failed to destroy a radar", -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 7e044d3771e7f0703d531e75f01d47f8ec42beec..c2735ea44a0e5856ecdb23d073f409cd537be205 100644 GIT binary patch delta 24026 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 diff --git a/Moose Training/Presentations/DCS World - MOOSE - Tasking - SEAD.pptx b/Moose Training/Presentations/DCS World - MOOSE - Tasking - SEAD.pptx index 9faf970254865b718d8654357bbaf4b68ceffb77..08ab811527b55672622337f443fda4b5b606ff1b 100644 GIT binary patch delta 12891 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 delta 7984 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 OeCh!U6aEVZ)cyxzKsV_C