Merge remote-tracking branch 'refs/remotes/origin/master' into FlightControl
@ -150,7 +150,7 @@
|
||||
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
|
||||
--
|
||||
-- function FSM:OnAfterEvent( From, Event, To, Amount )
|
||||
-- self:E( { Amount = Amount } )
|
||||
-- self:T( { Amount = Amount } )
|
||||
-- end
|
||||
--
|
||||
-- local Amount = 1
|
||||
@ -198,7 +198,7 @@
|
||||
-- 
|
||||
--
|
||||
-- function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
-- self:E( { From, Event, To, FsmUnit } )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- if From == "Green" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Green)
|
||||
@ -221,7 +221,7 @@
|
||||
--
|
||||
-- For debugging reasons the received parameters are traced within the DCS.log.
|
||||
--
|
||||
-- self:E( { From, Event, To, FsmUnit } )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- The method will check if the From state received is either "Green" or "Red" and will flare the respective color from the FsmUnit.
|
||||
--
|
||||
@ -365,7 +365,7 @@ do -- FSM
|
||||
Transition.Event = Event
|
||||
Transition.To = To
|
||||
|
||||
self:E( Transition )
|
||||
self:T( Transition )
|
||||
|
||||
self._Transitions[Transition] = Transition
|
||||
self:_eventmap( self.Events, Transition )
|
||||
@ -387,7 +387,7 @@ do -- FSM
|
||||
-- @param #table ReturnEvents A table indicating for which returned events of the SubFSM which Event must be triggered in the FSM.
|
||||
-- @return Core.Fsm#FSM_PROCESS The SubFSM.
|
||||
function FSM:AddProcess( From, Event, Process, ReturnEvents )
|
||||
self:E( { From, Event, Process, ReturnEvents } )
|
||||
self:T( { From, Event, Process, ReturnEvents } )
|
||||
|
||||
local Sub = {}
|
||||
Sub.From = From
|
||||
@ -417,7 +417,7 @@ do -- FSM
|
||||
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
if Process.From == From and Process.Event == Event then
|
||||
self:E( Process )
|
||||
self:T( Process )
|
||||
return Process.fsm
|
||||
end
|
||||
end
|
||||
@ -468,7 +468,7 @@ do -- FSM
|
||||
|
||||
local Process = self:GetProcess( From, Event )
|
||||
|
||||
self:E( { Process = Process._Name, Scores = Process._Scores, State = State, ScoreText = ScoreText, Score = Score } )
|
||||
self:T( { 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
|
||||
@ -528,7 +528,7 @@ do -- FSM
|
||||
|
||||
function FSM:_call_handler(handler, params)
|
||||
if self[handler] then
|
||||
self:E( "Calling " .. handler )
|
||||
self:T( "Calling " .. handler )
|
||||
local Value = self[handler]( self, unpack(params) )
|
||||
return Value
|
||||
end
|
||||
@ -547,16 +547,16 @@ do -- FSM
|
||||
local params = { from, EventName, to, ... }
|
||||
|
||||
if self.Controllable then
|
||||
self:E( "FSM Transition for " .. self.Controllable.ControllableName .. " :" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
self:T( "FSM Transition for " .. self.Controllable.ControllableName .. " :" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
else
|
||||
self:E( "FSM Transition:" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
self:T( "FSM Transition:" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
end
|
||||
|
||||
if ( self:_call_handler("onbefore" .. EventName, params) == false )
|
||||
or ( self:_call_handler("OnBefore" .. EventName, params) == false )
|
||||
or ( self:_call_handler("onleave" .. from, params) == false )
|
||||
or ( self:_call_handler("OnLeave" .. from, params) == false ) then
|
||||
self:E( "Cancel Transition" )
|
||||
self:T( "Cancel Transition" )
|
||||
return false
|
||||
end
|
||||
|
||||
@ -570,7 +570,7 @@ do -- FSM
|
||||
-- self:F2( "nextevent = " .. sub.nextevent )
|
||||
-- self[sub.nextevent]( self )
|
||||
--end
|
||||
self:E( "calling sub start event: " .. sub.StartEvent )
|
||||
self:T( "calling sub start event: " .. sub.StartEvent )
|
||||
sub.fsm.fsmparent = self
|
||||
sub.fsm.ReturnEvents = sub.ReturnEvents
|
||||
sub.fsm[sub.StartEvent]( sub.fsm )
|
||||
@ -602,31 +602,29 @@ do -- FSM
|
||||
self:_call_handler("onstatechange", params)
|
||||
end
|
||||
else
|
||||
self:E( "Cannot execute transition." )
|
||||
self:E( { From = self.current, Event = EventName, To = to, Can = Can } )
|
||||
self:T( "Cannot execute transition." )
|
||||
self:T( { From = self.current, Event = EventName, To = to, Can = Can } )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function FSM:_delayed_transition( EventName )
|
||||
self:E( { EventName = EventName } )
|
||||
return function( self, DelaySeconds, ... )
|
||||
self:T( "Delayed Event: " .. EventName )
|
||||
self:T2( "Delayed Event: " .. EventName )
|
||||
local CallID = self.CallScheduler:Schedule( self, self._handler, { EventName, ... }, DelaySeconds or 1 )
|
||||
self:T( { CallID = CallID } )
|
||||
self:T2( { CallID = CallID } )
|
||||
end
|
||||
end
|
||||
|
||||
function FSM:_create_transition( EventName )
|
||||
self:E( { Event = EventName } )
|
||||
return function( self, ... ) return self._handler( self, EventName , ... ) end
|
||||
end
|
||||
|
||||
function FSM:_gosub( ParentFrom, ParentEvent )
|
||||
local fsmtable = {}
|
||||
if self.subs[ParentFrom] and self.subs[ParentFrom][ParentEvent] then
|
||||
self:E( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
|
||||
self:T( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
|
||||
return self.subs[ParentFrom][ParentEvent]
|
||||
else
|
||||
return {}
|
||||
@ -636,17 +634,17 @@ do -- FSM
|
||||
function FSM:_isendstate( Current )
|
||||
local FSMParent = self.fsmparent
|
||||
if FSMParent and self.endstates[Current] then
|
||||
self:E( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
self:T( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
FSMParent.current = Current
|
||||
local ParentFrom = FSMParent.current
|
||||
self:E( ParentFrom )
|
||||
self:E( self.ReturnEvents )
|
||||
self:T( ParentFrom )
|
||||
self:T( self.ReturnEvents )
|
||||
local Event = self.ReturnEvents[Current]
|
||||
self:E( { ParentFrom, Event, self.ReturnEvents } )
|
||||
self:T( { ParentFrom, Event, self.ReturnEvents } )
|
||||
if Event then
|
||||
return FSMParent, Event
|
||||
else
|
||||
self:E( { "Could not find parent event name for state ", ParentFrom } )
|
||||
self:T( { "Could not find parent event name for state ", ParentFrom } )
|
||||
end
|
||||
end
|
||||
|
||||
@ -781,14 +779,14 @@ do -- FSM_PROCESS
|
||||
end
|
||||
|
||||
function FSM_PROCESS:Init( FsmProcess )
|
||||
self:E( "No Initialisation" )
|
||||
self:T( "No Initialisation" )
|
||||
end
|
||||
|
||||
--- Creates a new FSM_PROCESS object based on this FSM_PROCESS.
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @return #FSM_PROCESS
|
||||
function FSM_PROCESS:Copy( Controllable, Task )
|
||||
self:E( { self:GetClassNameAndID() } )
|
||||
self:T( { self:GetClassNameAndID() } )
|
||||
|
||||
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
@ -807,19 +805,19 @@ do -- FSM_PROCESS
|
||||
|
||||
-- Copy Processes
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
self:E( { Process} )
|
||||
self:T( { Process} )
|
||||
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
|
||||
end
|
||||
|
||||
-- Copy End States
|
||||
for EndStateID, EndState in pairs( self:GetEndStates() ) do
|
||||
self:E( EndState )
|
||||
self:T( EndState )
|
||||
NewFsm:AddEndState( EndState )
|
||||
end
|
||||
|
||||
-- Copy the score tables
|
||||
for ScoreID, Score in pairs( self:GetScores() ) do
|
||||
self:E( Score )
|
||||
self:T( Score )
|
||||
NewFsm:AddScore( ScoreID, Score.ScoreText, Score.Score )
|
||||
end
|
||||
|
||||
@ -889,7 +887,7 @@ end
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @return #FSM_PROCESS self
|
||||
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
||||
self:E( { Task, ProcessUnit } )
|
||||
self:T( { Task, ProcessUnit } )
|
||||
|
||||
self:SetControllable( ProcessUnit )
|
||||
self:SetTask( Task )
|
||||
@ -916,19 +914,19 @@ end
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterAssigned( ProcessUnit )
|
||||
self:E( "Assign" )
|
||||
self:T( "Assign" )
|
||||
|
||||
self.Task:Assign()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterFailed( ProcessUnit )
|
||||
self:E( "Failed" )
|
||||
self:T( "Failed" )
|
||||
|
||||
self.Task:Fail()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterSuccess( ProcessUnit )
|
||||
self:E( "Success" )
|
||||
self:T( "Success" )
|
||||
|
||||
self.Task:Success()
|
||||
end
|
||||
@ -940,13 +938,13 @@ end
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function FSM_PROCESS:onstatechange( ProcessUnit, From, Event, To, Dummy )
|
||||
self:E( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
|
||||
self:T( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
|
||||
|
||||
if self:IsTrace() then
|
||||
MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
||||
end
|
||||
|
||||
self:E( self.Scores[To] )
|
||||
self:T( self.Scores[To] )
|
||||
-- TODO: This needs to be reworked with a callback functions allocated within Task, and set within the mission script from the Task Objects...
|
||||
if self.Scores[To] then
|
||||
|
||||
@ -987,7 +985,7 @@ do -- FSM_TASK
|
||||
|
||||
function FSM_TASK:_call_handler( handler, params )
|
||||
if self[handler] then
|
||||
self:E( "Calling " .. handler )
|
||||
self:T( "Calling " .. handler )
|
||||
return self[handler]( self, unpack( params ) )
|
||||
end
|
||||
end
|
||||
|
||||
@ -240,7 +240,7 @@ function COMMANDCENTER:MessageToCoalition( Message )
|
||||
|
||||
local CCCoalition = self:GetPositionable():GetCoalition()
|
||||
--TODO: Fix coalition bug!
|
||||
self:GetPositionable():MessageToBlue( Message , 20, CCCoalition )
|
||||
self:GetPositionable():MessageToCoalition( Message, 20, CCCoalition, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -897,8 +897,8 @@ end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onenterAborted( From, Event, To )
|
||||
|
||||
@ -907,12 +907,29 @@ function TASK:onenterAborted( From, Event, To )
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been aborted! Task may be replanned." )
|
||||
|
||||
self:UnAssignFromGroups()
|
||||
|
||||
self:__Replan( 5 )
|
||||
end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onafterReplan( From, Event, To )
|
||||
|
||||
self:E( "Task Replanned" )
|
||||
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Replanning Task " .. self:GetName() .. "." )
|
||||
|
||||
self:SetMenu()
|
||||
|
||||
end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onenterFailed( From, Event, To )
|
||||
|
||||
|
||||
@ -329,6 +329,7 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
-- @param Dcs.DCScoalition#coalition MessageCoalition The Coalition receiving the message.
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20170122_0705' )
|
||||
env.info( 'Moose Generation Timestamp: 20170123_1416' )
|
||||
local base = _G
|
||||
|
||||
Include = {}
|
||||
@ -10905,7 +10905,7 @@ end
|
||||
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
|
||||
--
|
||||
-- function FSM:OnAfterEvent( From, Event, To, Amount )
|
||||
-- self:E( { Amount = Amount } )
|
||||
-- self:T( { Amount = Amount } )
|
||||
-- end
|
||||
--
|
||||
-- local Amount = 1
|
||||
@ -10953,7 +10953,7 @@ end
|
||||
-- 
|
||||
--
|
||||
-- function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
-- self:E( { From, Event, To, FsmUnit } )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- if From == "Green" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Green)
|
||||
@ -10976,7 +10976,7 @@ end
|
||||
--
|
||||
-- For debugging reasons the received parameters are traced within the DCS.log.
|
||||
--
|
||||
-- self:E( { From, Event, To, FsmUnit } )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- The method will check if the From state received is either "Green" or "Red" and will flare the respective color from the FsmUnit.
|
||||
--
|
||||
@ -11120,7 +11120,7 @@ do -- FSM
|
||||
Transition.Event = Event
|
||||
Transition.To = To
|
||||
|
||||
self:E( Transition )
|
||||
self:T( Transition )
|
||||
|
||||
self._Transitions[Transition] = Transition
|
||||
self:_eventmap( self.Events, Transition )
|
||||
@ -11142,7 +11142,7 @@ do -- FSM
|
||||
-- @param #table ReturnEvents A table indicating for which returned events of the SubFSM which Event must be triggered in the FSM.
|
||||
-- @return Core.Fsm#FSM_PROCESS The SubFSM.
|
||||
function FSM:AddProcess( From, Event, Process, ReturnEvents )
|
||||
self:E( { From, Event, Process, ReturnEvents } )
|
||||
self:T( { From, Event, Process, ReturnEvents } )
|
||||
|
||||
local Sub = {}
|
||||
Sub.From = From
|
||||
@ -11172,7 +11172,7 @@ do -- FSM
|
||||
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
if Process.From == From and Process.Event == Event then
|
||||
self:E( Process )
|
||||
self:T( Process )
|
||||
return Process.fsm
|
||||
end
|
||||
end
|
||||
@ -11223,7 +11223,7 @@ do -- FSM
|
||||
|
||||
local Process = self:GetProcess( From, Event )
|
||||
|
||||
self:E( { Process = Process._Name, Scores = Process._Scores, State = State, ScoreText = ScoreText, Score = Score } )
|
||||
self:T( { 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
|
||||
@ -11283,7 +11283,7 @@ do -- FSM
|
||||
|
||||
function FSM:_call_handler(handler, params)
|
||||
if self[handler] then
|
||||
self:E( "Calling " .. handler )
|
||||
self:T( "Calling " .. handler )
|
||||
local Value = self[handler]( self, unpack(params) )
|
||||
return Value
|
||||
end
|
||||
@ -11302,16 +11302,16 @@ do -- FSM
|
||||
local params = { from, EventName, to, ... }
|
||||
|
||||
if self.Controllable then
|
||||
self:E( "FSM Transition for " .. self.Controllable.ControllableName .. " :" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
self:T( "FSM Transition for " .. self.Controllable.ControllableName .. " :" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
else
|
||||
self:E( "FSM Transition:" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
self:T( "FSM Transition:" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
end
|
||||
|
||||
if ( self:_call_handler("onbefore" .. EventName, params) == false )
|
||||
or ( self:_call_handler("OnBefore" .. EventName, params) == false )
|
||||
or ( self:_call_handler("onleave" .. from, params) == false )
|
||||
or ( self:_call_handler("OnLeave" .. from, params) == false ) then
|
||||
self:E( "Cancel Transition" )
|
||||
self:T( "Cancel Transition" )
|
||||
return false
|
||||
end
|
||||
|
||||
@ -11325,7 +11325,7 @@ do -- FSM
|
||||
-- self:F2( "nextevent = " .. sub.nextevent )
|
||||
-- self[sub.nextevent]( self )
|
||||
--end
|
||||
self:E( "calling sub start event: " .. sub.StartEvent )
|
||||
self:T( "calling sub start event: " .. sub.StartEvent )
|
||||
sub.fsm.fsmparent = self
|
||||
sub.fsm.ReturnEvents = sub.ReturnEvents
|
||||
sub.fsm[sub.StartEvent]( sub.fsm )
|
||||
@ -11357,31 +11357,29 @@ do -- FSM
|
||||
self:_call_handler("onstatechange", params)
|
||||
end
|
||||
else
|
||||
self:E( "Cannot execute transition." )
|
||||
self:E( { From = self.current, Event = EventName, To = to, Can = Can } )
|
||||
self:T( "Cannot execute transition." )
|
||||
self:T( { From = self.current, Event = EventName, To = to, Can = Can } )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function FSM:_delayed_transition( EventName )
|
||||
self:E( { EventName = EventName } )
|
||||
return function( self, DelaySeconds, ... )
|
||||
self:T( "Delayed Event: " .. EventName )
|
||||
self:T2( "Delayed Event: " .. EventName )
|
||||
local CallID = self.CallScheduler:Schedule( self, self._handler, { EventName, ... }, DelaySeconds or 1 )
|
||||
self:T( { CallID = CallID } )
|
||||
self:T2( { CallID = CallID } )
|
||||
end
|
||||
end
|
||||
|
||||
function FSM:_create_transition( EventName )
|
||||
self:E( { Event = EventName } )
|
||||
return function( self, ... ) return self._handler( self, EventName , ... ) end
|
||||
end
|
||||
|
||||
function FSM:_gosub( ParentFrom, ParentEvent )
|
||||
local fsmtable = {}
|
||||
if self.subs[ParentFrom] and self.subs[ParentFrom][ParentEvent] then
|
||||
self:E( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
|
||||
self:T( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
|
||||
return self.subs[ParentFrom][ParentEvent]
|
||||
else
|
||||
return {}
|
||||
@ -11391,17 +11389,17 @@ do -- FSM
|
||||
function FSM:_isendstate( Current )
|
||||
local FSMParent = self.fsmparent
|
||||
if FSMParent and self.endstates[Current] then
|
||||
self:E( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
self:T( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
FSMParent.current = Current
|
||||
local ParentFrom = FSMParent.current
|
||||
self:E( ParentFrom )
|
||||
self:E( self.ReturnEvents )
|
||||
self:T( ParentFrom )
|
||||
self:T( self.ReturnEvents )
|
||||
local Event = self.ReturnEvents[Current]
|
||||
self:E( { ParentFrom, Event, self.ReturnEvents } )
|
||||
self:T( { ParentFrom, Event, self.ReturnEvents } )
|
||||
if Event then
|
||||
return FSMParent, Event
|
||||
else
|
||||
self:E( { "Could not find parent event name for state ", ParentFrom } )
|
||||
self:T( { "Could not find parent event name for state ", ParentFrom } )
|
||||
end
|
||||
end
|
||||
|
||||
@ -11536,14 +11534,14 @@ do -- FSM_PROCESS
|
||||
end
|
||||
|
||||
function FSM_PROCESS:Init( FsmProcess )
|
||||
self:E( "No Initialisation" )
|
||||
self:T( "No Initialisation" )
|
||||
end
|
||||
|
||||
--- Creates a new FSM_PROCESS object based on this FSM_PROCESS.
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @return #FSM_PROCESS
|
||||
function FSM_PROCESS:Copy( Controllable, Task )
|
||||
self:E( { self:GetClassNameAndID() } )
|
||||
self:T( { self:GetClassNameAndID() } )
|
||||
|
||||
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
@ -11562,19 +11560,19 @@ do -- FSM_PROCESS
|
||||
|
||||
-- Copy Processes
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
self:E( { Process} )
|
||||
self:T( { Process} )
|
||||
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
|
||||
end
|
||||
|
||||
-- Copy End States
|
||||
for EndStateID, EndState in pairs( self:GetEndStates() ) do
|
||||
self:E( EndState )
|
||||
self:T( EndState )
|
||||
NewFsm:AddEndState( EndState )
|
||||
end
|
||||
|
||||
-- Copy the score tables
|
||||
for ScoreID, Score in pairs( self:GetScores() ) do
|
||||
self:E( Score )
|
||||
self:T( Score )
|
||||
NewFsm:AddScore( ScoreID, Score.ScoreText, Score.Score )
|
||||
end
|
||||
|
||||
@ -11644,7 +11642,7 @@ end
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @return #FSM_PROCESS self
|
||||
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
||||
self:E( { Task, ProcessUnit } )
|
||||
self:T( { Task, ProcessUnit } )
|
||||
|
||||
self:SetControllable( ProcessUnit )
|
||||
self:SetTask( Task )
|
||||
@ -11671,19 +11669,19 @@ end
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterAssigned( ProcessUnit )
|
||||
self:E( "Assign" )
|
||||
self:T( "Assign" )
|
||||
|
||||
self.Task:Assign()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterFailed( ProcessUnit )
|
||||
self:E( "Failed" )
|
||||
self:T( "Failed" )
|
||||
|
||||
self.Task:Fail()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterSuccess( ProcessUnit )
|
||||
self:E( "Success" )
|
||||
self:T( "Success" )
|
||||
|
||||
self.Task:Success()
|
||||
end
|
||||
@ -11695,13 +11693,13 @@ end
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function FSM_PROCESS:onstatechange( ProcessUnit, From, Event, To, Dummy )
|
||||
self:E( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
|
||||
self:T( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
|
||||
|
||||
if self:IsTrace() then
|
||||
MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
||||
end
|
||||
|
||||
self:E( self.Scores[To] )
|
||||
self:T( self.Scores[To] )
|
||||
-- TODO: This needs to be reworked with a callback functions allocated within Task, and set within the mission script from the Task Objects...
|
||||
if self.Scores[To] then
|
||||
|
||||
@ -11742,7 +11740,7 @@ do -- FSM_TASK
|
||||
|
||||
function FSM_TASK:_call_handler( handler, params )
|
||||
if self[handler] then
|
||||
self:E( "Calling " .. handler )
|
||||
self:T( "Calling " .. handler )
|
||||
return self[handler]( self, unpack( params ) )
|
||||
end
|
||||
end
|
||||
@ -12446,6 +12444,7 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
-- @param Dcs.DCScoalition#coalition MessageCoalition The Coalition receiving the message.
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
@ -28910,7 +28909,7 @@ function COMMANDCENTER:MessageToCoalition( Message )
|
||||
|
||||
local CCCoalition = self:GetPositionable():GetCoalition()
|
||||
--TODO: Fix coalition bug!
|
||||
self:GetPositionable():MessageToBlue( Message , 20, CCCoalition )
|
||||
self:GetPositionable():MessageToCoalition( Message, 20, CCCoalition, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
@ -30800,8 +30799,8 @@ end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onenterAborted( From, Event, To )
|
||||
|
||||
@ -30810,12 +30809,29 @@ function TASK:onenterAborted( From, Event, To )
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been aborted! Task may be replanned." )
|
||||
|
||||
self:UnAssignFromGroups()
|
||||
|
||||
self:__Replan( 5 )
|
||||
end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onafterReplan( From, Event, To )
|
||||
|
||||
self:E( "Task Replanned" )
|
||||
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Replanning Task " .. self:GetName() .. "." )
|
||||
|
||||
self:SetMenu()
|
||||
|
||||
end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onenterFailed( From, Event, To )
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20170122_0705' )
|
||||
env.info( 'Moose Generation Timestamp: 20170123_1416' )
|
||||
local base = _G
|
||||
|
||||
Include = {}
|
||||
@ -10905,7 +10905,7 @@ end
|
||||
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
|
||||
--
|
||||
-- function FSM:OnAfterEvent( From, Event, To, Amount )
|
||||
-- self:E( { Amount = Amount } )
|
||||
-- self:T( { Amount = Amount } )
|
||||
-- end
|
||||
--
|
||||
-- local Amount = 1
|
||||
@ -10953,7 +10953,7 @@ end
|
||||
-- 
|
||||
--
|
||||
-- function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
-- self:E( { From, Event, To, FsmUnit } )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- if From == "Green" then
|
||||
-- FsmUnit:Flare(FLARECOLOR.Green)
|
||||
@ -10976,7 +10976,7 @@ end
|
||||
--
|
||||
-- For debugging reasons the received parameters are traced within the DCS.log.
|
||||
--
|
||||
-- self:E( { From, Event, To, FsmUnit } )
|
||||
-- self:T( { From, Event, To, FsmUnit } )
|
||||
--
|
||||
-- The method will check if the From state received is either "Green" or "Red" and will flare the respective color from the FsmUnit.
|
||||
--
|
||||
@ -11120,7 +11120,7 @@ do -- FSM
|
||||
Transition.Event = Event
|
||||
Transition.To = To
|
||||
|
||||
self:E( Transition )
|
||||
self:T( Transition )
|
||||
|
||||
self._Transitions[Transition] = Transition
|
||||
self:_eventmap( self.Events, Transition )
|
||||
@ -11142,7 +11142,7 @@ do -- FSM
|
||||
-- @param #table ReturnEvents A table indicating for which returned events of the SubFSM which Event must be triggered in the FSM.
|
||||
-- @return Core.Fsm#FSM_PROCESS The SubFSM.
|
||||
function FSM:AddProcess( From, Event, Process, ReturnEvents )
|
||||
self:E( { From, Event, Process, ReturnEvents } )
|
||||
self:T( { From, Event, Process, ReturnEvents } )
|
||||
|
||||
local Sub = {}
|
||||
Sub.From = From
|
||||
@ -11172,7 +11172,7 @@ do -- FSM
|
||||
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
if Process.From == From and Process.Event == Event then
|
||||
self:E( Process )
|
||||
self:T( Process )
|
||||
return Process.fsm
|
||||
end
|
||||
end
|
||||
@ -11223,7 +11223,7 @@ do -- FSM
|
||||
|
||||
local Process = self:GetProcess( From, Event )
|
||||
|
||||
self:E( { Process = Process._Name, Scores = Process._Scores, State = State, ScoreText = ScoreText, Score = Score } )
|
||||
self:T( { 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
|
||||
@ -11283,7 +11283,7 @@ do -- FSM
|
||||
|
||||
function FSM:_call_handler(handler, params)
|
||||
if self[handler] then
|
||||
self:E( "Calling " .. handler )
|
||||
self:T( "Calling " .. handler )
|
||||
local Value = self[handler]( self, unpack(params) )
|
||||
return Value
|
||||
end
|
||||
@ -11302,16 +11302,16 @@ do -- FSM
|
||||
local params = { from, EventName, to, ... }
|
||||
|
||||
if self.Controllable then
|
||||
self:E( "FSM Transition for " .. self.Controllable.ControllableName .. " :" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
self:T( "FSM Transition for " .. self.Controllable.ControllableName .. " :" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
else
|
||||
self:E( "FSM Transition:" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
self:T( "FSM Transition:" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
end
|
||||
|
||||
if ( self:_call_handler("onbefore" .. EventName, params) == false )
|
||||
or ( self:_call_handler("OnBefore" .. EventName, params) == false )
|
||||
or ( self:_call_handler("onleave" .. from, params) == false )
|
||||
or ( self:_call_handler("OnLeave" .. from, params) == false ) then
|
||||
self:E( "Cancel Transition" )
|
||||
self:T( "Cancel Transition" )
|
||||
return false
|
||||
end
|
||||
|
||||
@ -11325,7 +11325,7 @@ do -- FSM
|
||||
-- self:F2( "nextevent = " .. sub.nextevent )
|
||||
-- self[sub.nextevent]( self )
|
||||
--end
|
||||
self:E( "calling sub start event: " .. sub.StartEvent )
|
||||
self:T( "calling sub start event: " .. sub.StartEvent )
|
||||
sub.fsm.fsmparent = self
|
||||
sub.fsm.ReturnEvents = sub.ReturnEvents
|
||||
sub.fsm[sub.StartEvent]( sub.fsm )
|
||||
@ -11357,31 +11357,29 @@ do -- FSM
|
||||
self:_call_handler("onstatechange", params)
|
||||
end
|
||||
else
|
||||
self:E( "Cannot execute transition." )
|
||||
self:E( { From = self.current, Event = EventName, To = to, Can = Can } )
|
||||
self:T( "Cannot execute transition." )
|
||||
self:T( { From = self.current, Event = EventName, To = to, Can = Can } )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function FSM:_delayed_transition( EventName )
|
||||
self:E( { EventName = EventName } )
|
||||
return function( self, DelaySeconds, ... )
|
||||
self:T( "Delayed Event: " .. EventName )
|
||||
self:T2( "Delayed Event: " .. EventName )
|
||||
local CallID = self.CallScheduler:Schedule( self, self._handler, { EventName, ... }, DelaySeconds or 1 )
|
||||
self:T( { CallID = CallID } )
|
||||
self:T2( { CallID = CallID } )
|
||||
end
|
||||
end
|
||||
|
||||
function FSM:_create_transition( EventName )
|
||||
self:E( { Event = EventName } )
|
||||
return function( self, ... ) return self._handler( self, EventName , ... ) end
|
||||
end
|
||||
|
||||
function FSM:_gosub( ParentFrom, ParentEvent )
|
||||
local fsmtable = {}
|
||||
if self.subs[ParentFrom] and self.subs[ParentFrom][ParentEvent] then
|
||||
self:E( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
|
||||
self:T( { ParentFrom, ParentEvent, self.subs[ParentFrom], self.subs[ParentFrom][ParentEvent] } )
|
||||
return self.subs[ParentFrom][ParentEvent]
|
||||
else
|
||||
return {}
|
||||
@ -11391,17 +11389,17 @@ do -- FSM
|
||||
function FSM:_isendstate( Current )
|
||||
local FSMParent = self.fsmparent
|
||||
if FSMParent and self.endstates[Current] then
|
||||
self:E( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
self:T( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
FSMParent.current = Current
|
||||
local ParentFrom = FSMParent.current
|
||||
self:E( ParentFrom )
|
||||
self:E( self.ReturnEvents )
|
||||
self:T( ParentFrom )
|
||||
self:T( self.ReturnEvents )
|
||||
local Event = self.ReturnEvents[Current]
|
||||
self:E( { ParentFrom, Event, self.ReturnEvents } )
|
||||
self:T( { ParentFrom, Event, self.ReturnEvents } )
|
||||
if Event then
|
||||
return FSMParent, Event
|
||||
else
|
||||
self:E( { "Could not find parent event name for state ", ParentFrom } )
|
||||
self:T( { "Could not find parent event name for state ", ParentFrom } )
|
||||
end
|
||||
end
|
||||
|
||||
@ -11536,14 +11534,14 @@ do -- FSM_PROCESS
|
||||
end
|
||||
|
||||
function FSM_PROCESS:Init( FsmProcess )
|
||||
self:E( "No Initialisation" )
|
||||
self:T( "No Initialisation" )
|
||||
end
|
||||
|
||||
--- Creates a new FSM_PROCESS object based on this FSM_PROCESS.
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @return #FSM_PROCESS
|
||||
function FSM_PROCESS:Copy( Controllable, Task )
|
||||
self:E( { self:GetClassNameAndID() } )
|
||||
self:T( { self:GetClassNameAndID() } )
|
||||
|
||||
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
@ -11562,19 +11560,19 @@ do -- FSM_PROCESS
|
||||
|
||||
-- Copy Processes
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
self:E( { Process} )
|
||||
self:T( { Process} )
|
||||
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
|
||||
end
|
||||
|
||||
-- Copy End States
|
||||
for EndStateID, EndState in pairs( self:GetEndStates() ) do
|
||||
self:E( EndState )
|
||||
self:T( EndState )
|
||||
NewFsm:AddEndState( EndState )
|
||||
end
|
||||
|
||||
-- Copy the score tables
|
||||
for ScoreID, Score in pairs( self:GetScores() ) do
|
||||
self:E( Score )
|
||||
self:T( Score )
|
||||
NewFsm:AddScore( ScoreID, Score.ScoreText, Score.Score )
|
||||
end
|
||||
|
||||
@ -11644,7 +11642,7 @@ end
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @return #FSM_PROCESS self
|
||||
function FSM_PROCESS:Assign( ProcessUnit, Task )
|
||||
self:E( { Task, ProcessUnit } )
|
||||
self:T( { Task, ProcessUnit } )
|
||||
|
||||
self:SetControllable( ProcessUnit )
|
||||
self:SetTask( Task )
|
||||
@ -11671,19 +11669,19 @@ end
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterAssigned( ProcessUnit )
|
||||
self:E( "Assign" )
|
||||
self:T( "Assign" )
|
||||
|
||||
self.Task:Assign()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterFailed( ProcessUnit )
|
||||
self:E( "Failed" )
|
||||
self:T( "Failed" )
|
||||
|
||||
self.Task:Fail()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterSuccess( ProcessUnit )
|
||||
self:E( "Success" )
|
||||
self:T( "Success" )
|
||||
|
||||
self.Task:Success()
|
||||
end
|
||||
@ -11695,13 +11693,13 @@ end
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function FSM_PROCESS:onstatechange( ProcessUnit, From, Event, To, Dummy )
|
||||
self:E( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
|
||||
self:T( { ProcessUnit, From, Event, To, Dummy, self:IsTrace() } )
|
||||
|
||||
if self:IsTrace() then
|
||||
MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
||||
end
|
||||
|
||||
self:E( self.Scores[To] )
|
||||
self:T( self.Scores[To] )
|
||||
-- TODO: This needs to be reworked with a callback functions allocated within Task, and set within the mission script from the Task Objects...
|
||||
if self.Scores[To] then
|
||||
|
||||
@ -11742,7 +11740,7 @@ do -- FSM_TASK
|
||||
|
||||
function FSM_TASK:_call_handler( handler, params )
|
||||
if self[handler] then
|
||||
self:E( "Calling " .. handler )
|
||||
self:T( "Calling " .. handler )
|
||||
return self[handler]( self, unpack( params ) )
|
||||
end
|
||||
end
|
||||
@ -12446,6 +12444,7 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
-- @param Dcs.DCScoalition#coalition MessageCoalition The Coalition receiving the message.
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
@ -28910,7 +28909,7 @@ function COMMANDCENTER:MessageToCoalition( Message )
|
||||
|
||||
local CCCoalition = self:GetPositionable():GetCoalition()
|
||||
--TODO: Fix coalition bug!
|
||||
self:GetPositionable():MessageToBlue( Message , 20, CCCoalition )
|
||||
self:GetPositionable():MessageToCoalition( Message, 20, CCCoalition, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
@ -30800,8 +30799,8 @@ end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onenterAborted( From, Event, To )
|
||||
|
||||
@ -30810,12 +30809,29 @@ function TASK:onenterAborted( From, Event, To )
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " has been aborted! Task may be replanned." )
|
||||
|
||||
self:UnAssignFromGroups()
|
||||
|
||||
self:__Replan( 5 )
|
||||
end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onafterReplan( From, Event, To )
|
||||
|
||||
self:E( "Task Replanned" )
|
||||
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Replanning Task " .. self:GetName() .. "." )
|
||||
|
||||
self:SetMenu()
|
||||
|
||||
end
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
function TASK:onenterFailed( From, Event, To )
|
||||
|
||||
|
||||
171
README.md
@ -1,168 +1,17 @@
|
||||
# Context
|
||||
# MOOSE framework
|
||||
|
||||
MOOSE is a **M**ission **O**bject **O**riented **S**cripting **E**nvironment, and is meant for mission designers and mission hosters.
|
||||
It allows to quickly setup complex missions using pre-scripted scenarios using the available classes within the MOOSE Framework.
|
||||
MOOSE is currently still in alpha version, but will evolve over time. Right now, it has been updated to work with DCS world 1.5. and 2.0.
|
||||
MOOSE works with DCS world 1.5. and 2.0.
|
||||
|
||||
You can find the source of MOOSE here on GITHUB. It is free for download:
|
||||
https://github.com/FlightControl-Master/MOOSE/
|
||||
## MOOSE framework goal
|
||||
|
||||
Note: MOOSE is complementary to [MIST](https://github.com/mrSkortch/MissionScriptingTools/releases), so if you use MIST in parallel with MOOSE objects, this should work.
|
||||
The goal of MOOSE is to allow mission designers to enhance their scripting with mission orchestration objects, which can be instantiated from defined classes within the framework. This will allow to write mission scripts with minimal code embedded. Of course, the richness of the framework will determine the richness of the misson scenarios.
|
||||
The MOOSE is a service that is produced while being consumed ... , it will evolve further as more classes are developed for the framework, and as more users are using it.
|
||||
MOOSE is meant to be a one-man show, it is meant to evolve within a growing community around the framework.
|
||||
Within the community, key users will start supporting, documenting, explaining and even creating new classes for the framework.
|
||||
It is the ambition to grow this framework as a de-facto standard for mission designers to use.
|
||||
|
||||
# Goals
|
||||
## MOOSE main site
|
||||
|
||||
The goal of MOOSE is to allow mission designers to enhance their scripting with mission orchestration objects, which can be instantiated from defined classes within the framework. This will allow to write mission scripts with minimal code embedded. Of course, the richness of the framework will determine the richness of the misson scenarios. We can expect that MOOSE will evolve over time, as more missions will be designed within the framework.
|
||||
|
||||
# MOOSE Directory Structure
|
||||
|
||||
* Moose Development: Contains the collection of lua files that define the MOOSE classes. You can use this directory to build the dynamic luadoc documentation intellisense in your eclipse development environment.
|
||||
* Moose Mission Setup: Contains the Moose.lua file to be included in your scripts when using MOOSE classes (see below the point Mission Design with Moose).
|
||||
* Moose Test Missions: Contains a directory structure with Moose Test Missions and examples. In each directory, you will find a miz file and a lua file containing the main mission script.
|
||||
* Moose Training: Contains the documentation of Moose generated with luadoc from the Moose source code. The presentations used during the videos in my [youtube channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg), are also to be found here.
|
||||
|
||||
# Mission Design with Moose
|
||||
|
||||
In order to create a mission using MOOSE, you'll have to include a file named **Moose.lua**:
|
||||
|
||||
1. Create a new mission in the DCS World Mission Editor.
|
||||
2. In the mission editor, create a new trigger.
|
||||
3. Name the trigger Moose Load and let it execute only at MISSION START.
|
||||
4. Add an action DO SCRIPT FILE (without a condition, so the middle column must be empty).
|
||||
5. In the action, browse to the **[Moose.lua](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Mission%20Setup)** file in the **Moose Mission Setup** directory, and include this file within your mission.
|
||||
6. Make sure that the "Moose Load" trigger is completely at the top of your mission.
|
||||
|
||||
Voila, MOOSE is now included in your mission. During the execution of this mission, all MOOSE classes will be loaded, and all MOOSE initializations will be exectuted before any other mission action is executed.
|
||||
|
||||
IMPORTANT NOTE: When a new version of MOOSE is released, you'll have to UPDATE the Moose.lua file in EACH OF YOUR MISSION.
|
||||
This can be a tedious task, and for this purpose, a tool has been developed that will update the Moose.lua files automatically within your missions.
|
||||
Refer to the tool at [Moose Mission Setup\Moose Mission Update](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Mission%20Setup/Moose%20Mission%20Update) directory for further information included in the [READ.ME]() file.
|
||||
|
||||
|
||||
# MOOSE Classes
|
||||
|
||||
The following classes are currently embedded within MOOSE and can be included within your mission scripts:
|
||||
|
||||
## MOOSE Core Classes
|
||||
|
||||
These classes define the base building blocks of the MOOSE framework. These classes are heavily used within the MOOSE framework.
|
||||
|
||||
* [BASE](Documentation/Base.html): The main class from which all MOOSE classes are derived from. The BASE class contains essential functions to support inheritance and MOOSE object execution tracing (logging within the DCS.log file in the saved games folder of the user).
|
||||
|
||||
* [DATABASE](Documentation/Database.html): Creates a collection of GROUPS[], UNITS[], CLIENTS[] and managed these sets automatically. Provides an API set to retrieve a GROUP, UNIT or CLIENT instance from the _DATABASE object using defined APIs. The collections are maintained dynamically during the execution of the mission, so when players join, leave, when units are created or destroyed, the collections are dynamically updated.
|
||||
|
||||
* [EVENT](Documentation/Event.html): Provides the Event Dispatcher base class to handle DCS Events, being fired upon registered events within the DCS simulator. Note that EVENT is used by BASE, exposing OnEvent() methods to catch these DCS events.
|
||||
|
||||
* [FSM](Documentation/Fsm.html): The main FSM class can be used to build a Finite State Machine. The derived FSM_ classes provide Finite State Machine building capability for CONTROLLABLEs, ACT_ (Task Actions) classes, TASKs and SETs.
|
||||
|
||||
* [MENU](Documentation/Menu.html): Set Menu options (F10) for All Players, Coalitions, Groups, Clients. MENU also manages the recursive removal of menus, which is a big asset!
|
||||
|
||||
* [SETS](Documentation/Set.html): Create SETs of MOOSE objects. SETs can be created for GROUPs, UNITs, AIRBASEs, ...
|
||||
The SET can be filtered with defined filter criteria.
|
||||
Iterators are available that iterate through the GROUPSET, calling a function for each object within the SET.
|
||||
|
||||
* [MESSAGE](Documentation/Message.html): A message publishing system, displaying messages to Clients, Coalitions or All players.
|
||||
|
||||
* [POINTS](Documentation/Point.html): A set of point classes to manage the 2D or 3D simulation space, through an extensive method library.
|
||||
The POINT_VEC3 class manages the 3D simulation space, while the POINT_VEC2 class manages the 2D simulation space.
|
||||
|
||||
* [ZONES](Documentation/Zone.html): A set of zone classes that provide the functionality to validate the presence of GROUPS, UNITS, CLIENTS, STATICS within a certain ZONE. The zones can take various forms and can be movable.
|
||||
|
||||
* [SCHEDULER](Documentation/Scheduler.html): This class implements a timer scheduler that will call at optional specified intervals repeatedly or just one time a scheduled function.
|
||||
|
||||
|
||||
## MOOSE Wrapper Classes
|
||||
|
||||
MOOSE Wrapper Classes provide an object oriented hierarchical mechanism to manage the DCS objects within the simulator.
|
||||
Wrapper classes provide another easier mechanism to control Groups, Units, Statics, Airbases and other objects.
|
||||
|
||||
* **[OBJECT](Documentation/Object.html)**: This class provides the base for MOOSE objects.
|
||||
|
||||
* **[IDENTIFIABLE](Documentation/Identifiable.html)**: This class provides the base for MOOSE identifiable objects, which is every object within the simulator :-).
|
||||
|
||||
* **[POSITIONABLE](Documentation/Positionable.html)**: This class provides the base for MOOSE positionable objects. These are AIRBASEs, STATICs, GROUPs, UNITs ...
|
||||
|
||||
* **[CONTROLLABLE](Documentation/Controllable.html)**: This class provides the base for MOOSE controllable objects. These are GROUPs, UNITs, CLIENTs.
|
||||
|
||||
* **[AIRBASE](Documentation/Airbase.html)**: This class wraps a DCS Airbase object within the simulator.
|
||||
|
||||
* **[GROUP](Documentation/Group.html)**: This class wraps a DCS Group objects within the simulator, which are currently alive.
|
||||
It provides a more extensive API set.
|
||||
It takes an abstraction of the complexity to give tasks, commands and set various options to DCS Groups.
|
||||
Additionally, the GROUP class provides a much richer API to identify various properties of the DCS Group.
|
||||
For each DCS Group created object within a running mission, a GROUP object will be created automatically, beging managed within the DATABASE.
|
||||
|
||||
* **[UNIT](Documentation/Unit.html)**: This class wraps a DCS Unit object within the simulator, which are currently alive. It provides a more extensive API set, as well takes an abstraction of the complexity to give commands and set various options to DCS Units. Additionally, the UNIT class provides a much richer API to identify various properties of the DCS Unit. For each DCS Unit object created within a running mission, a UNIT object will be created automatically, that is stored within the DATABASE, under the _DATABASE object.
|
||||
the UNIT class provides a more extensive API set, taking an abstraction of the complexity to give tasks, commands and set various options to DCS Units.
|
||||
For each DCS Unit created object within a running mission, a UNIT object will be created automatically, beging managed within the DATABASE.
|
||||
|
||||
* **[CLIENT](Documentation/Client.html)**: This class wraps a DCS Unit object within the simulator, which has a skill Client or Player.
|
||||
The CLIENT class derives from the UNIT class, thus contains the complete UNIT API set, and additionally, the CLIENT class provides an API set to manage players joining or leaving clients, sending messages to players, and manage the state of units joined by players. For each DCS Unit object created within a running mission that can be joined by a player, a CLIENT object will be created automatically, that is stored within the DATABASE, under the _DATABASE object.
|
||||
|
||||
* **[STATIC](Documentation/Static.html)**: This class wraps a DCS StaticObject object within the simulator.
|
||||
The STATIC class derives from the POSITIONABLE class, thus contains also the position API set.
|
||||
|
||||
|
||||
## MOOSE Functional Classes
|
||||
|
||||
* [SPAWN](Documentation/Spawn.html): Spawn new groups (and units) during mission execution.
|
||||
|
||||
* [ESCORT](Moose Training/Documentation/Escort.html): Makes groups consisting of helicopters, airplanes, ground troops or ships within a mission joining your flight. You can control these groups through the ratio menu during your flight. Available commands are around: Navigation, Position Hold, Reporting (Target Detection), Attacking, Assisted Attacks, ROE, Evasion, Mission Execution and more ...
|
||||
|
||||
* [MISSILETRAINER](Moose Training/Documentation/MissileTrainer.html): Missile trainer, it destroys missiles when they are within a certain range of player airplanes, displays tracking and alert messages of missile launches; approach; destruction, and configure with radio menu commands. Various APIs available to configure the trainer.
|
||||
|
||||
* [DETECTION](Moose Training/Documentation/Detection.html): Detect other units using the available sensors of the detection unit. The DETECTION_BASE derived classes will provide different methods how the sets of detected objects are built.
|
||||
|
||||
## MOOSE AI Controlling Classes
|
||||
|
||||
* [AI_BALANCER](Documentation/AI_Balancer.html): Compensate in a multi player mission the abscence of players with dynamically spawned AI air units. When players join CLIENTS, the AI will either be destroyed, or will fly back to the home or nearest friendly airbase.
|
||||
|
||||
* [AI_PATROLZONE](Documentation/AI_PatrolZone.html): Make an alive AI Group patrol a zone derived from the ZONE_BASE class. Manage out-of-fuel events and set altitude and speed ranges for the patrol.
|
||||
|
||||
* [FAC](Moose Training/Documentation/Fac.html): Using the DETECTION_BASE derived classes, detected objects can be reported in different ways to a set of clients (SET_CLIENT). FAC_BASE derived classes will provide target detection reporting and control using the radio menu.
|
||||
|
||||
* [FOLLOW](Moose Training/Documentation/Follow.html): Build large air formations using the FOLLOW class.
|
||||
|
||||
# MOOSE Tutorials and Examples
|
||||
|
||||
You can download [test missions](https://github.com/FlightControl-Master/MOOSE/tree/master/Test%20Missions) to have examples and learn the syntax and usage of the MOOSE classes.
|
||||
|
||||
There are [Video Tutorials](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg) on my YOUTUBE channel on which you can learn some coding aspects with mission execution demos, as well as some of the tooling and internal mechanisms within MOOSE.
|
||||
|
||||
|
||||
In the triggers section, there is a flag (9999) that will decide how MOOSE will be loaded. When flag 9999 is set, MOOSE will be dynamically loaded. When flag 9999 is off, MOOSE will be loaded embedded. Note that when loaded embedded, **your mission must include the last Moose_Embedded.lua file**. So, ensure that the last file is included in the DO SCRIPT section when MOOSE got an update!
|
||||
|
||||
# Credits
|
||||
|
||||
Note that the framework is based on code i've written myself, but some of it is also based on code that i've seen as great scripting code and ideas, and which i've revised. I see this framework evolving towards a broader public, and the ownership may dissapear (or parts of it). Consider this code public domain. Therefore a list of credits to all who have or are contributing (this list will increase over time): Grimes, Prof_Hilactic, xcom, the 476 virtual squadron team, ...
|
||||
|
||||
You'll notice that within this framework, there are functions used from mist. I've taken the liberty to copy those atomic mist functions that are very nice and useful, and used those.
|
||||
|
||||
**Grimes**
|
||||
Without the effort of Grimes with MIST and his continuous documentation, the development of MOOSE would not have been possible. MOOSE is not replacing MIST, but is compensating it.
|
||||
|
||||
**Prof_hilactic**
|
||||
SEAD Defenses. I've taken the script, and reworded it to fit within MOOSE. The script within MOOSE is hardly recognizable anymore from the original. Find here the posts: http://forums.eagle.ru/showpost.php?...59&postcount=1
|
||||
|
||||
**xcom**
|
||||
His contribution is related to the Event logging system. I've analyzed and studied his scripts, and reworked it a bit to use it also within the framework (I've also tweaked it a bit). Find his post here: http://forums.eagle.ru/showpost.php?...73&postcount=1
|
||||
|
||||
**Dutch_Baron (James)**
|
||||
Working together with James has resulted in the creation of the AIBALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
|
||||
**Stuka (Danny)**
|
||||
Working together with Danny has resulted in the MISSILETRAINER class. Stuka has shared his ideas and together we made a design. Together with the 476 virtual team, we tested this CLASS, and got much positive feedback!
|
||||
|
||||
**Mechanic (G<>bor)**
|
||||
Worked together with G<>bor to create the concept of the DETECTION and FAC classes. Mechanic shared his ideas and concepts to group detected targets into sets within detection zones... Will continue to work with G<>bor to workout the DETECTION and FAC classes.
|
||||
|
||||
**Shadoh**
|
||||
Interacted on the eagle dynamics forum to build the FOLLOW class to build large WWII airplane formations.
|
||||
|
||||
For the rest I also would like to thank the numerous feedback and help and assistance of the moose community at SLACK.COM.
|
||||
Note that there is a vast amount of other scripts out there.
|
||||
I may contact you personally to ask for your contribution / permission if i can use your idea or script to tweak it to the framework.
|
||||
Parts of these scripts will have to be redesigned to fit it into an OO framework.
|
||||
|
||||
The rest of the framework functions and class definitions were my own developments, especially the core of MOOSE.
|
||||
Trust I've spent hours and hours investigating, trying and writing and documenting code building this framework.
|
||||
Hope you think the idea is great and useful.
|
||||
[Click on this link to browse to the MOOSE main web page.](http://flightcontrol-master.github.io/MOOSE)
|
||||
|
||||
40
docs/Communities.md
Normal file
@ -0,0 +1,40 @@
|
||||
# 3) MOOSE framework support channels
|
||||
|
||||
MOOSE is broadcasted, documented and supported through various social media channels.
|
||||
|
||||
## 3.1) MOOSE broadcast channels on YouTube
|
||||
|
||||
MOOSE has a [broadcast channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg/playlists) on youtube.
|
||||
These videos are grouped into playlists, which explain specific MOOSE capabilities,
|
||||
and gradually build up the "understanding" and "what is possible" to do with the MOOSE framework.
|
||||
I really, really encourage all to watch the explanation videos.
|
||||
|
||||
Some mandatory videos to watch are:
|
||||
|
||||
* [MOOSE Introduction](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1JEtVcyf9sazUV5_fGICz4)
|
||||
|
||||
* [MOOSE Setup](https://www.youtube.com/watch?v=-Hxae3mTCE8&t=159s&index=1&list=PL7ZUrU4zZUl0riB9ULVh-bZvFlw1_Wym2)
|
||||
* [MOOSE Spawning](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1jirWIo4t4YxqN-HxjqRkL)
|
||||
* [MOOSE Tasking](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3CgxN2iAViiGLTPpQ-Ajdg)
|
||||
* [MOOSE Task Dispatching](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3I6ieFM-cjey-rncF1ktNI)
|
||||
|
||||
## 3.2) MOOSE on Eagle Dynamics forums
|
||||
|
||||
This is a default thread at the Eagle Dynamics forums where the MOOSE framework can be discussed and supported.
|
||||
The thread is called [MOOSE - Mission Object Oriented Scripting Framework](https://forums.eagle.ru/showthread.php?t=138043).
|
||||
|
||||
## 3.3) MOOSE on GITHUB.
|
||||
|
||||
I encourage that you create also a user at GITHUB.
|
||||
On the MOOSE framework GITHUB site, you can register issues, feedback and comments in the issues section of the site.
|
||||
This allows to track this feedback and issues, in order to provide a structured support and create a milestone plan.
|
||||
In other words, treat this development as a project.
|
||||
|
||||
## 3.4) MOOSE on slack.com
|
||||
|
||||
Slack is a team community site. It is a great environment to discuss online the framework.
|
||||
Various channels are allocated in the environment to discuss specific topics.
|
||||
A channel exists per MOOSE class, so that a focused discuss is possible.
|
||||
|
||||

|
||||
|
||||
BIN
docs/Communities/Slack.JPG
Normal file
|
After Width: | Height: | Size: 169 KiB |
@ -240,7 +240,7 @@ Processing will just continue. Synchronous Event Trigger methods are useful to c
|
||||
<p>The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.</p>
|
||||
|
||||
<pre><code> function FSM:OnAfterEvent( From, Event, To, Amount )
|
||||
self:E( { Amount = Amount } )
|
||||
self:T( { Amount = Amount } )
|
||||
end
|
||||
|
||||
local Amount = 1
|
||||
@ -292,7 +292,7 @@ The next code implements this through the event handling method <strong>OnAfterS
|
||||
<p><img src="..\Presentations\FSM\Dia7.JPG" alt="Transition Flow"/></p>
|
||||
|
||||
<pre><code> function FsmDemo:OnAfterSwitch( From, Event, To, FsmUnit )
|
||||
self:E( { From, Event, To, FsmUnit } )
|
||||
self:T( { From, Event, To, FsmUnit } )
|
||||
|
||||
if From == "Green" then
|
||||
FsmUnit:Flare(FLARECOLOR.Green)
|
||||
@ -317,7 +317,7 @@ and one additional parameter that was given when the event was triggered, which
|
||||
|
||||
<p>For debugging reasons the received parameters are traced within the DCS.log.</p>
|
||||
|
||||
<pre><code> self:E( { From, Event, To, FsmUnit } )
|
||||
<pre><code> self:T( { From, Event, To, FsmUnit } )
|
||||
</code></pre>
|
||||
|
||||
<p>The method will check if the From state received is either "Green" or "Red" and will flare the respective color from the FsmUnit.</p>
|
||||
|
||||
@ -231,7 +231,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(POSITIONABLE).MessageToCoalition">POSITIONABLE:MessageToCoalition(Message, Duration, Name, MessageCoalition)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(POSITIONABLE).MessageToCoalition">POSITIONABLE:MessageToCoalition(Message, Duration, MessageCoalition, Name)</a></td>
|
||||
<td class="summary">
|
||||
<p>Send a message to a coalition.</p>
|
||||
</td>
|
||||
@ -851,7 +851,7 @@ The client object receiving the message.</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(POSITIONABLE).MessageToCoalition" >
|
||||
<strong>POSITIONABLE:MessageToCoalition(Message, Duration, Name, MessageCoalition)</strong>
|
||||
<strong>POSITIONABLE:MessageToCoalition(Message, Duration, MessageCoalition, Name)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -877,13 +877,14 @@ The duration of the message.</p>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Name </em></code>:
|
||||
(optional) The Name of the sender. If not provided, the Name is the type of the Positionable.</p>
|
||||
<p><code><em><a href="Dcs.DCScoalition.html##(coalition)">Dcs.DCScoalition#coalition</a> MessageCoalition </em></code>:
|
||||
The Coalition receiving the message.</p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em> MessageCoalition </em></code>: </p>
|
||||
<p><code><em>#string Name </em></code>:
|
||||
(optional) The Name of the sender. If not provided, the Name is the type of the Positionable.</p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@ -2171,7 +2171,7 @@ when nothing was spawned.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<em>#number</em>
|
||||
<a id="#(SPAWN).SpawnMaxGroups" >
|
||||
<strong>SPAWN.SpawnMaxGroups</strong>
|
||||
</a>
|
||||
@ -2188,7 +2188,7 @@ when nothing was spawned.</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<em></em>
|
||||
<em>#number</em>
|
||||
<a id="#(SPAWN).SpawnMaxUnitsAlive" >
|
||||
<strong>SPAWN.SpawnMaxUnitsAlive</strong>
|
||||
</a>
|
||||
|
||||
@ -639,7 +639,13 @@ Use the method <a href="##(TASK).AddScore">TASK.AddScore</a>() to add scores whe
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).onenterAborted">TASK:onenterAborted(Event, From, To)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).onafterReplan">TASK:onafterReplan(From, Event, To)</a></td>
|
||||
<td class="summary">
|
||||
<p>FSM function for a TASK</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).onenterAborted">TASK:onenterAborted(From, Event, To)</a></td>
|
||||
<td class="summary">
|
||||
<p>FSM function for a TASK</p>
|
||||
</td>
|
||||
@ -651,7 +657,7 @@ Use the method <a href="##(TASK).AddScore">TASK.AddScore</a>() to add scores whe
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).onenterFailed">TASK:onenterFailed(Event, From, To)</a></td>
|
||||
<td class="name" nowrap="nowrap"><a href="##(TASK).onenterFailed">TASK:onenterFailed(From, Event, To)</a></td>
|
||||
<td class="summary">
|
||||
<p>FSM function for a TASK</p>
|
||||
</td>
|
||||
@ -2311,8 +2317,8 @@ self</p>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).onenterAborted" >
|
||||
<strong>TASK:onenterAborted(Event, From, To)</strong>
|
||||
<a id="#(TASK).onafterReplan" >
|
||||
<strong>TASK:onafterReplan(From, Event, To)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -2323,16 +2329,47 @@ self</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string From </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string To </em></code>: </p>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).onenterAborted" >
|
||||
<strong>TASK:onenterAborted(From, Event, To)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<p>FSM function for a TASK</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string From </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string To </em></code>: </p>
|
||||
|
||||
</li>
|
||||
@ -2374,7 +2411,7 @@ self</p>
|
||||
<dt>
|
||||
|
||||
<a id="#(TASK).onenterFailed" >
|
||||
<strong>TASK:onenterFailed(Event, From, To)</strong>
|
||||
<strong>TASK:onenterFailed(From, Event, To)</strong>
|
||||
</a>
|
||||
</dt>
|
||||
<dd>
|
||||
@ -2385,12 +2422,12 @@ self</p>
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
<p><code><em>#string From </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<p><code><em>#string From </em></code>: </p>
|
||||
<p><code><em>#string Event </em></code>: </p>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
81
docs/Installation.md
Normal file
@ -0,0 +1,81 @@
|
||||
# 2) Installation of the MOOSE Environment.
|
||||
|
||||
This document describes how to install your MOOSE development environment, enhancing the mission design experience for your missions in DCS World.
|
||||
|
||||
## 2.1) Install Eclipse LDT, a lua advanced editor
|
||||
|
||||
Install [Eclipse LDT](https://eclipse.org/ldt) on your Windows 64 bit system.
|
||||
This is a free lua editor based on the Eclipse ecosystem.
|
||||
The advantage of LDT is that it greatly enhances your lua development environment with intellisense, better search capabilities etc.
|
||||
You may have to install [java](https://www.java.com/en/download) first.
|
||||
Ensure you install the **64-bit versions** of both Eclipse LDT and java!
|
||||
|
||||
## 2.2) Get your MOOSE repository installed on your PC and linked with GITHUB
|
||||
|
||||
### 2.2.1) Install GITHUB desktop
|
||||
|
||||
Install [GITHUB](https://desktop.github.com) desktop.
|
||||
We use GITHUB desktop to sync the moose repository to your system.
|
||||
|
||||
### 2.2.2) Link the MOOSE repository
|
||||
|
||||
Link the MOOSE repository on GITHUB to your freshly installed GITHUB desktop.
|
||||
Do this by browing to the MOOSE repository at GITHUB, and select the green button **Clone or Download** -> **Open in Desktop**.
|
||||
Specify a local directory on your PC where you want to store the MOOSE repository contents.
|
||||
Sync the MOOSE repository to a defined local MOOSE directory on your PC using GITHUB desktop (press the sync button).
|
||||
|
||||
### 2.2.3) Sync the Dcs folder in the MOOSE repository
|
||||
|
||||
On your local MOOSE directory, execute the batch file [DCS_Folder_Sync.bat](https://github.com/FlightControl-Master/MOOSE/blob/master/DCS_Folder_Sync.bat).
|
||||
This will sync the dcs folder in the MOOSE repository from the submodule DCS API.
|
||||
The Dcs folder is what we call a GITHUB submodule, which needs to be synced separately.
|
||||
You will be notified when you need to re-sync the Dcs folder through GITHUB channels.
|
||||
|
||||
** As a result, you have installed the MOOSE repository on your PC, and it is fully synced. **
|
||||
|
||||
## 2.3) Configuration of the Eclipse LDT to work with MOOSE and activate your intellisense etc.
|
||||
|
||||
The section explains how to setup your Eclipse LDT environment, link it with the MOOSE respository.
|
||||
This will enable you to start developing mission scripts in lua, which will be fully intellisense enabled!!!
|
||||
|
||||
### 2.3.1) Create a new **Workspace** in LDT.
|
||||
|
||||
The LDT editor has a concept of "workspaces", this contains all your settings of your editing environment, like views, menu options etc.
|
||||
I suggest you create a workspace at your user id, the default location when you first start LDT.
|
||||
|
||||
1. Open Eclipse LDT.
|
||||
2. Select the workspace to be stored at your user id.
|
||||
|
||||
### 2.3.2) Create a new **Project** in LDT.
|
||||
|
||||
Here we will create a new project called "Moose_Framework" in your LDT environment.
|
||||
The project details are already defined within the MOOSE framework repository, which is installed on your local MOOSE directory on your PC.
|
||||
We will link into that directory and load the Project properties.
|
||||
|
||||
1. Select from the Menu: File -> New -> Lua Project.
|
||||
|
||||

|
||||
|
||||
2. A "New Project" dialog box is shown.
|
||||
|
||||

|
||||
|
||||
3. Type the Project Name: **Moose_Framework**.
|
||||
4. In the sub-box "Project Contents", select the option Create Project at existing location (from existing source).
|
||||
5. Browse to the local MOOSE directory (press on the Browse button) and select the root directory of your local MO.OSE directory on your PC. Press OK.
|
||||
6. You're back at the "New Project" dialog box. Press the **Next** button below the dialog box.
|
||||
__(All the other settings are by default ok)__.
|
||||
7. You should see now a dialog box with the following properties.
|
||||
Note that the Moose Development/Moose directory is flagged as the **Source Directory*. (It is listed totally on top.)
|
||||
This is important because it will search in the files in this directory and sub directories for lua documentator enabled lua files.
|
||||
This will enable the intellisense of the MOOSE repository!
|
||||
|
||||

|
||||
|
||||
8. Press the **Finish** button.
|
||||
|
||||
As a result, when you browse to the Script Explorer, you'll see the following:
|
||||
|
||||

|
||||
|
||||
**Congratulations! You have now setup your Moose_Framework project LDT environment!**
|
||||
BIN
docs/Installation/LDT_Moose_Framework_Finish.JPG
Normal file
|
After Width: | Height: | Size: 54 KiB |
BIN
docs/Installation/LDT_New_Project.JPG
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
docs/Installation/LDT_Project.JPG
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
docs/Installation/LDT_Project_Source_Directory.JPG
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
docs/Installation/LDT_Script_Explorer.JPG
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
docs/Installation/Originals/LDT_Moose_Framework_Finish.JPG
Normal file
|
After Width: | Height: | Size: 66 KiB |
BIN
docs/Installation/Originals/LDT_New_Project.JPG
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
docs/Installation/Originals/LDT_Project.JPG
Normal file
|
After Width: | Height: | Size: 71 KiB |
BIN
docs/Installation/Originals/LDT_Project_Source_Directory.JPG
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
docs/Installation/Originals/LDT_Script_Explorer.JPG
Normal file
|
After Width: | Height: | Size: 36 KiB |
266
docs/Installation/README.md
Normal file
@ -0,0 +1,266 @@
|
||||
# Context
|
||||
|
||||
|
||||
MOOSE is a **M**ission **O**bject **O**riented **S**cripting **E**nvironment, and is meant for mission designers and mission hosters.
|
||||
It allows to quickly setup complex missions using pre-scripted scenarios using the available classes within the MOOSE Framework.
|
||||
MOOSE is designed to work with DCS world 1.5. and 2.0.
|
||||
|
||||

|
||||
|
||||
# Goals
|
||||
|
||||
The goal of MOOSE is to allow mission designers to enhance their scripting with mission orchestration objects, which can be instantiated from defined classes within the framework. This will allow to write mission scripts with minimal code embedded. Of course, the richness of the framework will determine the richness of the misson scenarios. We can expect that MOOSE will evolve over time, as more missions will be designed within the framework.
|
||||
|
||||
## GitHub Repository
|
||||
|
||||
You can find the source of [MOOSE on GITHUB](https://github.com/FlightControl-Master/MOOSE/). It is free for download.
|
||||
|
||||
# Installation of tools and sync the MOOSE repository.
|
||||
|
||||
1. Install [Eclipse LDT](https://eclipse.org/ldt) on your Windows 64 bit system. This is a free lua editor based on the Eclipse ecosystem. The advantage of LDT is that it greatly enhances your lua development environment with intellisense, better search capabilities etc. You may have to install [java](https://www.java.com/en/download) first. Ensure you install the **64-bit versions** of both Eclipse LDT and java!
|
||||
2. Install [GITHUB](https://desktop.github.com) desktop. We use GITHUB desktop to sync the moose repository to your system.
|
||||
3. Link the MOOSE repository on GITHUB to your freshly installed GITHUB desktop. Do this by browing to the MOOSE repository at GITHUB, and select the green button **Clone or Download** -> **Open in Desktop**.
|
||||
4. Specify a local directory on your PC where you want to store the MOOSE repository contents.
|
||||
5. Sync the MOOSE repository to a defined local MOOSE directory on your PC using GITHUB desktop (press the sync button).
|
||||
6. On your local MOOOSE directory, execute the batch file [DCS_Folder_Sync.bat](https://github.com/FlightControl-Master/MOOSE/blob/master/DCS_Folder_Sync.bat). This will sync the dcs folder in the MOOSE repository from the submodule DCS API.
|
||||
|
||||
As a result, you have installed the MOOSE repository on your PC, and it is fully synced.
|
||||
|
||||
# Setup Eclipse LDT to work with MOOSE and activate your intellisense etc.
|
||||
|
||||
1. Open Eclipse LDT.
|
||||
2. Select the workspace to be stored at your user id.
|
||||
3. Select from the Menu: File -> New -> Lua Project.
|
||||
|
||||

|
||||
|
||||
4. A dialog box is shown.
|
||||
|
||||

|
||||
|
||||
5. Type the Project Name: Moose_Framework
|
||||
6. In the sub-box Project Contents, select the option Create Project at existing location (from existing source). Browse to the local MOOSE directory and select the root directory of MOOSE.
|
||||
7. Select the Next button.
|
||||
8. You should see now a dialog box with the following properties. Note that the Moose_Framework/Moose Development/Moose directory is flagged as the **Source Directory*. This is important because it will search in the files in this directory and sub directories for lua documentator enabled lua files. It will make the intellisense work!
|
||||
|
||||

|
||||
|
||||
9. Press the Finish button.
|
||||
|
||||
As a result, when you browse to the Script Explorer, you'll see the following:
|
||||
|
||||

|
||||
|
||||
## YouTube Broadcast Channel
|
||||
|
||||
MOOSE has a [broadcast channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg/playlists) on youtube.
|
||||
These videos are grouped into playlists, which explain specific MOOSE capabilities,
|
||||
and gradually build up the "understanding" and "what is possible" to do with the MOOSE framework.
|
||||
I really, really encourage all to watch the explanation videos.
|
||||
|
||||
Some mandatory videos to watch are:
|
||||
|
||||
* [MOOSE Introduction](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1JEtVcyf9sazUV5_fGICz4)
|
||||
|
||||
* [MOOSE Setup](https://www.youtube.com/watch?v=-Hxae3mTCE8&t=159s&index=1&list=PL7ZUrU4zZUl0riB9ULVh-bZvFlw1_Wym2)
|
||||
* [MOOSE Spawning](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1jirWIo4t4YxqN-HxjqRkL)
|
||||
* [MOOSE Tasking](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3CgxN2iAViiGLTPpQ-Ajdg)
|
||||
* [MOOSE Task Dispatching](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3I6ieFM-cjey-rncF1ktNI)
|
||||
|
||||
## MOOSE community
|
||||
|
||||
There is a MOOSE community at various places out there. The main community can be found at slack.com.
|
||||
Various channels and people are helping each other out using the framework.
|
||||
If you would like to join, please contact me on skype: FlightControl_Skype.
|
||||
|
||||
|
||||
## Test Missions
|
||||
|
||||
The framework comes with [Test Missions](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Test%20Missions), that you can try out and helps you to code.
|
||||
You can copy/paste code the code snippets into your missions, as it accellerates your mission developments.
|
||||
|
||||
These exact test missions are demonstrated at the demo videos in the YouTube channel.
|
||||
|
||||
Note: MOOSE is complementary to [MIST](https://github.com/mrSkortch/MissionScriptingTools/releases), so if you use MIST in parallel with MOOSE objects, this should work.
|
||||
|
||||
# MOOSE Directory Structure
|
||||
|
||||
As you can see at the GitHub site, the MOOSE framework is devided into a couple of directories:
|
||||
|
||||
* Moose Development: Contains the collection of lua files that define the MOOSE classes. You can use this directory to build the dynamic luadoc documentation intellisense in your eclipse development environment.
|
||||
* Moose Mission Setup: Contains the Moose.lua file to be included in your scripts when using MOOSE classes (see below the point Mission Design with Moose).
|
||||
* Moose Test Missions: Contains a directory structure with Moose Test Missions and examples. In each directory, you will find a miz file and a lua file containing the main mission script.
|
||||
* Moose Training: Contains the documentation of Moose generated with luadoc from the Moose source code. The presentations used during the videos in my [youtube channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg), are also to be found here.
|
||||
|
||||
# Mission Design with Moose
|
||||
|
||||
In order to create a mission using MOOSE, you'll have to include a file named **Moose.lua**:
|
||||
|
||||
1. Create a new mission in the DCS World Mission Editor.
|
||||
2. In the mission editor, create a new trigger.
|
||||
3. Name the trigger Moose Load and let it execute only at MISSION START.
|
||||
4. Add an action DO SCRIPT FILE (without a condition, so the middle column must be empty).
|
||||
5. In the action, browse to the **[Moose.lua](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Mission%20Setup)** file in the **Moose Mission Setup** directory, and include this file within your mission.
|
||||
6. Make sure that the "Moose Load" trigger is completely at the top of your mission.
|
||||
|
||||
Voila, MOOSE is now included in your mission. During the execution of this mission, all MOOSE classes will be loaded, and all MOOSE initializations will be exectuted before any other mission action is executed.
|
||||
|
||||
IMPORTANT NOTE: When a new version of MOOSE is released, you'll have to UPDATE the Moose.lua file in EACH OF YOUR MISSION.
|
||||
This can be a tedious task, and for this purpose, a tool has been developed that will update the Moose.lua files automatically within your missions.
|
||||
Refer to the tool at [Moose Mission Setup\Moose Mission Update](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Mission%20Setup/Moose%20Mission%20Update) directory for further information included in the [READ.ME]() file.
|
||||
|
||||
# MOOSE Classes
|
||||
|
||||
The following classes are currently embedded within MOOSE and can be included within your mission scripts:
|
||||
|
||||

|
||||
|
||||
## MOOSE Core Classes
|
||||
|
||||
These classes define the base building blocks of the MOOSE framework. These classes are heavily used within the MOOSE framework.
|
||||
|
||||
* [BASE](Documentation/Base.html): The main class from which all MOOSE classes are derived from. The BASE class contains essential functions to support inheritance and MOOSE object execution tracing (logging within the DCS.log file in the saved games folder of the user).
|
||||
|
||||
* [DATABASE](Documentation/Database.html): Creates a collection of GROUPS[], UNITS[], CLIENTS[] and managed these sets automatically. Provides an API set to retrieve a GROUP, UNIT or CLIENT instance from the _DATABASE object using defined APIs. The collections are maintained dynamically during the execution of the mission, so when players join, leave, when units are created or destroyed, the collections are dynamically updated.
|
||||
|
||||
* [EVENT](Documentation/Event.html): Provides the Event Dispatcher base class to handle DCS Events, being fired upon registered events within the DCS simulator. Note that EVENT is used by BASE, exposing OnEvent() methods to catch these DCS events.
|
||||
|
||||
* [FSM](Documentation/Fsm.html): The main FSM class can be used to build a Finite State Machine. The derived FSM_ classes provide Finite State Machine building capability for CONTROLLABLEs, ACT_ (Task Actions) classes, TASKs and SETs.
|
||||
|
||||
* [MENU](Documentation/Menu.html): Set Menu options (F10) for All Players, Coalitions, Groups, Clients. MENU also manages the recursive removal of menus, which is a big asset!
|
||||
|
||||
* [SETS](Documentation/Set.html): Create SETs of MOOSE objects. SETs can be created for GROUPs, UNITs, AIRBASEs, ...
|
||||
The SET can be filtered with defined filter criteria.
|
||||
Iterators are available that iterate through the GROUPSET, calling a function for each object within the SET.
|
||||
|
||||
* [MESSAGE](Documentation/Message.html): A message publishing system, displaying messages to Clients, Coalitions or All players.
|
||||
|
||||
* [POINTS](Documentation/Point.html): A set of point classes to manage the 2D or 3D simulation space, through an extensive method library.
|
||||
The POINT_VEC3 class manages the 3D simulation space, while the POINT_VEC2 class manages the 2D simulation space.
|
||||
|
||||
* [ZONES](Documentation/Zone.html): A set of zone classes that provide the functionality to validate the presence of GROUPS, UNITS, CLIENTS, STATICS within a certain ZONE. The zones can take various forms and can be movable.
|
||||
|
||||
* [SCHEDULER](Documentation/Scheduler.html): This class implements a timer scheduler that will call at optional specified intervals repeatedly or just one time a scheduled function.
|
||||
|
||||
|
||||
## MOOSE Wrapper Classes
|
||||
|
||||
MOOSE Wrapper Classes provide an object oriented hierarchical mechanism to manage the DCS objects within the simulator.
|
||||
Wrapper classes provide another easier mechanism to control Groups, Units, Statics, Airbases and other objects.
|
||||
|
||||
* **[OBJECT](Documentation/Object.html)**: This class provides the base for MOOSE objects.
|
||||
|
||||
* **[IDENTIFIABLE](Documentation/Identifiable.html)**: This class provides the base for MOOSE identifiable objects, which is every object within the simulator :-).
|
||||
|
||||
* **[POSITIONABLE](Documentation/Positionable.html)**: This class provides the base for MOOSE positionable objects. These are AIRBASEs, STATICs, GROUPs, UNITs ...
|
||||
|
||||
* **[CONTROLLABLE](Documentation/Controllable.html)**: This class provides the base for MOOSE controllable objects. These are GROUPs, UNITs, CLIENTs.
|
||||
|
||||
* **[AIRBASE](Documentation/Airbase.html)**: This class wraps a DCS Airbase object within the simulator.
|
||||
|
||||
* **[GROUP](Documentation/Group.html)**: This class wraps a DCS Group objects within the simulator, which are currently alive.
|
||||
It provides a more extensive API set.
|
||||
It takes an abstraction of the complexity to give tasks, commands and set various options to DCS Groups.
|
||||
Additionally, the GROUP class provides a much richer API to identify various properties of the DCS Group.
|
||||
For each DCS Group created object within a running mission, a GROUP object will be created automatically, beging managed within the DATABASE.
|
||||
|
||||
* **[UNIT](Documentation/Unit.html)**: This class wraps a DCS Unit object within the simulator, which are currently alive. It provides a more extensive API set, as well takes an abstraction of the complexity to give commands and set various options to DCS Units. Additionally, the UNIT class provides a much richer API to identify various properties of the DCS Unit. For each DCS Unit object created within a running mission, a UNIT object will be created automatically, that is stored within the DATABASE, under the _DATABASE object.
|
||||
the UNIT class provides a more extensive API set, taking an abstraction of the complexity to give tasks, commands and set various options to DCS Units.
|
||||
For each DCS Unit created object within a running mission, a UNIT object will be created automatically, beging managed within the DATABASE.
|
||||
|
||||
* **[CLIENT](Documentation/Client.html)**: This class wraps a DCS Unit object within the simulator, which has a skill Client or Player.
|
||||
The CLIENT class derives from the UNIT class, thus contains the complete UNIT API set, and additionally, the CLIENT class provides an API set to manage players joining or leaving clients, sending messages to players, and manage the state of units joined by players. For each DCS Unit object created within a running mission that can be joined by a player, a CLIENT object will be created automatically, that is stored within the DATABASE, under the _DATABASE object.
|
||||
|
||||
* **[STATIC](Documentation/Static.html)**: This class wraps a DCS StaticObject object within the simulator.
|
||||
The STATIC class derives from the POSITIONABLE class, thus contains also the position API set.
|
||||
|
||||
|
||||
## MOOSE Functional Classes
|
||||
|
||||
MOOSE Functional Classes provide various functions that are useful in mission design.
|
||||
|
||||
* [SPAWN](Documentation/Spawn.html): Spawn new groups (and units) during mission execution.
|
||||
|
||||
* [ESCORT](Moose Training/Documentation/Escort.html): Makes groups consisting of helicopters, airplanes, ground troops or ships within a mission joining your flight. You can control these groups through the ratio menu during your flight. Available commands are around: Navigation, Position Hold, Reporting (Target Detection), Attacking, Assisted Attacks, ROE, Evasion, Mission Execution and more ...
|
||||
|
||||
* [MISSILETRAINER](Moose Training/Documentation/MissileTrainer.html): Missile trainer, it destroys missiles when they are within a certain range of player airplanes, displays tracking and alert messages of missile launches; approach; destruction, and configure with radio menu commands. Various APIs available to configure the trainer.
|
||||
|
||||
* [DETECTION](Moose Training/Documentation/Detection.html): Detect other units using the available sensors of the detection unit. The DETECTION_BASE derived classes will provide different methods how the sets of detected objects are built.
|
||||
|
||||
## MOOSE AI Controlling Classes
|
||||
|
||||
MOOSE AI Controlling Classes provide mechanisms to control AI over long lasting processes.
|
||||
These AI Controlling Classes are based on FSM (Finite State Machine) Classes, and provided an encapsulated way to make AI behave or execute an activity.
|
||||
|
||||
* [AI_BALANCER](Documentation/AI_Balancer.html): Compensate in a multi player mission the abscence of players with dynamically spawned AI air units. When players join CLIENTS, the AI will either be destroyed, or will fly back to the home or nearest friendly airbase.
|
||||
|
||||
* [AI_PATROLZONE](Documentation/AI_PatrolZone.html): Make an alive AI Group patrol a zone derived from the ZONE_BASE class. Manage out-of-fuel events and set altitude and speed ranges for the patrol.
|
||||
|
||||
* [AI_CARGO](Documentation/AI_Cargo.html): Make AI behave as cargo. Various CARGO types exist.
|
||||
|
||||
## MOOSE Tasking Classes
|
||||
|
||||
MOOSE Tasking Classes provide a comprehensive Mission Orchestration System.
|
||||
Through COMMANDCENTERs, multiple logical MISSIONs can be orchestrated for coalitions.
|
||||
Within each MISSION, various TASKs can be defined.
|
||||
Each TASK has a TASK ACTION flow, which is the flow that a player (hosted by a UNIT) within the simulator needs to follow and accomplish.
|
||||
|
||||
* [COMMANDCENTER](Documentation/CommandCenter.html): Orchestrates various logical MISSIONs for a coalition.
|
||||
|
||||
* [MISSION](Documentation/Mission.html): Each MISSION has various TASKs to be executed and accomplished by players.
|
||||
|
||||
* [TASK](Documentation/Task.html): Each TASK has a status, and has a TASK ACTION flow for each Player acting and executing the TASK.
|
||||
|
||||
* [TASK_SEAD](Documentation/Task_SEAD.html): Models a SEAD Task, where a Player is routed towards an attack zone, and various SEADing targets need to be eliminated.
|
||||
|
||||
* [TASK_A2G](Documentation/Task_A2G.html): Models a A2G Task, where a Player is routed towards an attack zone, and various A2G targets need to be eliminated.
|
||||
|
||||
## MOOSE Action Classes
|
||||
|
||||
MOOSE Action Classes are task action sub-flows, that can be used and combined, to quickly define a comprehensive end-to-end task action flow.
|
||||
For example, for the SEAD Task, the task action flow combines the actions ASSIGN, ROUTE, ACCOUNT and ASSIST task action sub-flows.
|
||||
|
||||
* [ACT_ASSIGN](Documentation/Assign.html): Mechanism to accept a TASK by a player. For example, assign the task only after the player accepts the task using the menu.
|
||||
|
||||
* [ACT_ROUTE](Documentation/Route.html): Mechanisms to route players to zones or any other positionable coordinate. For example, route a player towards a zone.
|
||||
|
||||
* [ACT_ACCOUNT](Documentation/Account.html): Mechanisms to account various events within the simulator. For example, account the dead events, accounting dead units within a Target SET within a ZONE.
|
||||
|
||||
* [ACT_ASSIST](Documentation/Assist.html): Mechanisms to assist players executing a task. For example, acquire targets through smoking them.
|
||||
|
||||
|
||||
# Credits
|
||||
|
||||
Note that the framework is based on code i've written myself, but some of it is also based on code that i've seen as great scripting code and ideas, and which i've revised. I see this framework evolving towards a broader public, and the ownership may dissapear (or parts of it). Consider this code public domain. Therefore a list of credits to all who have or are contributing (this list will increase over time): Grimes, Prof_Hilactic, xcom, the 476 virtual squadron team, ...
|
||||
|
||||
You'll notice that within this framework, there are functions used from mist. I've taken the liberty to copy those atomic mist functions that are very nice and useful, and used those.
|
||||
|
||||
**Grimes**
|
||||
Without the effort of Grimes with MIST and his continuous documentation, the development of MOOSE would not have been possible. MOOSE is not replacing MIST, but is compensating it.
|
||||
|
||||
**Prof_hilactic**
|
||||
SEAD Defenses. I've taken the script, and reworded it to fit within MOOSE. The script within MOOSE is hardly recognizable anymore from the original. Find here the posts: http://forums.eagle.ru/showpost.php?...59&postcount=1
|
||||
|
||||
**xcom**
|
||||
His contribution is related to the Event logging system. I've analyzed and studied his scripts, and reworked it a bit to use it also within the framework (I've also tweaked it a bit). Find his post here: http://forums.eagle.ru/showpost.php?...73&postcount=1
|
||||
|
||||
**Dutch_Baron (James)**
|
||||
Working together with James has resulted in the creation of the AIBALANCER class. James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
|
||||
**Stuka (Danny)**
|
||||
Working together with Danny has resulted in the MISSILETRAINER class. Stuka has shared his ideas and together we made a design. Together with the 476 virtual team, we tested this CLASS, and got much positive feedback!
|
||||
|
||||
**Mechanic (Gabor)**
|
||||
Worked together with Gabor to create the concept of the DETECTION and FAC classes. Mechanic shared his ideas and concepts to group detected targets into sets within detection zones... Will continue to work with G<>bor to workout the DETECTION and FAC classes.
|
||||
|
||||
**Shadoh**
|
||||
Interacted on the eagle dynamics forum to build the FOLLOW class to build large WWII airplane formations.
|
||||
|
||||
For the rest I also would like to thank the numerous feedback and help and assistance of the moose community at SLACK.COM.
|
||||
Note that there is a vast amount of other scripts out there.
|
||||
I may contact you personally to ask for your contribution / permission if i can use your idea or script to tweak it to the framework.
|
||||
Parts of these scripts will have to be redesigned to fit it into an OO framework.
|
||||
|
||||
The rest of the framework functions and class definitions were my own developments, especially the core of MOOSE.
|
||||
Trust I've spent hours and hours investigating, trying and writing and documenting code building this framework.
|
||||
Hope you think the idea is great and useful.
|
||||
155
docs/README.md
@ -1,64 +1,99 @@
|
||||
# Context
|
||||
|
||||
# 1) MOOSE framework
|
||||
|
||||
MOOSE is a **M**ission **O**bject **O**riented **S**cripting **E**nvironment, and is meant for mission designers and mission hosters.
|
||||
It allows to quickly setup complex missions using pre-scripted scenarios using the available classes within the MOOSE Framework.
|
||||
MOOSE is designed to work with DCS world 1.5. and 2.0.
|
||||
MOOSE works with DCS world 1.5. and 2.0.
|
||||
|
||||

|
||||

|
||||
|
||||
# Goals
|
||||
MOOSE is an Object Oriented framework and defines **Classes**, which are components that combine **Methods** and **Variables**/**Properties** as one encapsulated structure (table).
|
||||
Mission Designers can **instantiate objects** from these MOOSE classes, which declares a variable that contains a reference to the instantiated object from the MOOSE Class.
|
||||
So, you can use that variable to use its methods and properties to build your logic. Note that in OO lua, a methods are addressed using the ":" notation,
|
||||
because a "self" variable is passed that contains the object reference to that function!
|
||||
|
||||
The goal of MOOSE is to allow mission designers to enhance their scripting with mission orchestration objects, which can be instantiated from defined classes within the framework. This will allow to write mission scripts with minimal code embedded. Of course, the richness of the framework will determine the richness of the misson scenarios. We can expect that MOOSE will evolve over time, as more missions will be designed within the framework.
|
||||
An example of what this means is shortly explained using the SPAWN class of MOOSE, which you can use to spawn new groups into your running mission.
|
||||
The SPAWN class simplifies the process of spawning, and it has many methods that you can use to create variations how you want your spawn object to spawn new groups.
|
||||
|
||||
## GitHub Repository
|
||||
```lua
|
||||
local SpawnObject = SPAWN:New( "GroupName" ) -- This creates a new SpawnObject from the SPAWN class, using the :New method constructor to instantiate a new SPAWN object searching for the GroupName as the late activated group defined within your Mission Editor.
|
||||
-- Nothing is spawned yet..., so let's use now the SpawnObject to spawn a new GROUP.
|
||||
|
||||
You can find the source of [MOOSE on GITHUB](https://github.com/FlightControl-Master/MOOSE/). It is free for download.
|
||||
local SpawnGroup = SpawnObject:Spawn() -- Here we use the :Spawn() method of the SPAWN class. This method creates a new group from the GroupName template as defined within the Mission Editor.
|
||||
```
|
||||
|
||||
## YouTube Broadcast Channel
|
||||
## 1.1) MOOSE framework goal
|
||||
|
||||
MOOSE has a [broadcast channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg/playlists) on youtube.
|
||||
These videos are grouped into playlists, which explain specific MOOSE capabilities,
|
||||
and gradually build up the "understanding" and "what is possible" to do with the MOOSE framework.
|
||||
I really, really encourage all to watch the explanation videos.
|
||||
The goal of MOOSE is to allow mission designers to enhance their scripting with mission orchestration objects, which can be instantiated from defined classes within the framework. This will allow to write mission scripts with minimal code embedded. Of course, the richness of the framework will determine the richness of the misson scenarios.
|
||||
The MOOSE is a service that is produced while being consumed ... , it will evolve further as more classes are developed for the framework, and as more users are using it.
|
||||
|
||||
Some mandatory videos to watch are:
|
||||
MOOSE is NOT meant to be a one-man show, it is meant to evolve within a growing community around the framework.
|
||||
|
||||
* [MOOSE Introduction](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1JEtVcyf9sazUV5_fGICz4)
|
||||
Within the community, key users will start supporting, documenting, explaining and even creating new classes for the framework.
|
||||
It is the ambition to grow this framework as a de-facto standard for mission designers to use.
|
||||
|
||||
* [MOOSE Setup](https://www.youtube.com/watch?v=-Hxae3mTCE8&t=159s&index=1&list=PL7ZUrU4zZUl0riB9ULVh-bZvFlw1_Wym2)
|
||||
* [MOOSE Spawning](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl1jirWIo4t4YxqN-HxjqRkL)
|
||||
* [MOOSE Tasking](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3CgxN2iAViiGLTPpQ-Ajdg)
|
||||
* [MOOSE Task Dispatching](https://www.youtube.com/playlist?list=PL7ZUrU4zZUl3I6ieFM-cjey-rncF1ktNI)
|
||||
## 1.2) MOOSE framework at GITHUB
|
||||
|
||||
## MOOSE community
|
||||
You can find the source of [MOOSE framework on GITHUB](https://github.com/FlightControl-Master/MOOSE/).
|
||||
It is free for download and usage, but it is under license of the GNU 3.0 open source license policy.
|
||||
The MOOSE development uses the GITHUB service to enforce and control a structured development within a growing community.
|
||||
GITHUB enforces a structured approval process, release and change management, and a communicative distribution and deployment.
|
||||
The MOOSE framework development is considered an open source project, where contributors are welcome to contribute on the development.
|
||||
Some key users have already started with this process. Contact me if you're interested to contribute.
|
||||
|
||||
There is a MOOSE community at various places out there. The main community can be found at slack.com.
|
||||
Various channels and people are helping each other out using the framework.
|
||||
If you would like to join, please contact me on skype: FlightControl_Skype.
|
||||
## 1.3) Eclipse LDT
|
||||
|
||||
MOOSE utilizes the Eclipse Lua Development Tools. As a result, the MOOSE framework is documented using the luadocumentor standard.
|
||||
Every class, method and variable is documented within the source, and mission designers can write mission script lua code that is **intellisense**(-ed) ...
|
||||
What that means is that while you are coding your mission, your object and variables (derived from MOOSE classes) will list the methods and properties of that class interactively while coding ...
|
||||
|
||||
## Test Missions
|
||||

|
||||
|
||||
The framework comes with [Test Missions](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Test%20Missions), that you can try out and helps you to code.
|
||||
You can copy/paste code the code snippets into your missions, as it accellerates your mission developments.
|
||||
## 1.4) LUA training
|
||||
|
||||
These exact test missions are demonstrated at the demo videos in the YouTube channel.
|
||||
In order to efficiently use the MOOSE framework, it is highly recommended that you learn a couple of basic principles of lua.
|
||||
I recommend you learn the basic lua principles following this [lua tutorial](https://www.tutorialspoint.com/lua).
|
||||
We're not asking you to become an expert in lua, leave that to the experts, but, you'll need to have some basic lua coding
|
||||
knowledge to "understand" the code, and also, to understand the syntax.
|
||||
|
||||
Note: MOOSE is complementary to [MIST](https://github.com/mrSkortch/MissionScriptingTools/releases), so if you use MIST in parallel with MOOSE objects, this should work.
|
||||
**Therefore, I suggest you walk through this [lua quick guide](https://www.tutorialspoint.com/lua/lua_quick_guide.htm)**.
|
||||
Ignore the lua environment setup. DCS comes with a pre-defined lua environment.
|
||||
|
||||
# MOOSE Directory Structure
|
||||
# 2) Installation
|
||||
|
||||
As you can see at the GitHub site, the MOOSE framework is devided into a couple of directories:
|
||||
There is a complete installation guide as part of this documentation.
|
||||
|
||||
[Click here for the installation guide of the MOOSE framework](Installation.html).
|
||||
|
||||
# 3) Support Channels
|
||||
|
||||
MOOSE is broadcasted, documented and supported through various social media channels.
|
||||
|
||||
[Click here for the communities guide of the MOOSE framework](Communities.html).
|
||||
|
||||
# 4) Demonstration Missions
|
||||
|
||||
The framework comes with [Test Missions](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Test%20Missions),
|
||||
that you can try out and helps you to code. These test missions provide examples of defined use cases how the MOOSE
|
||||
framework can be utilized. Each test mission is located in a separate directory, which contains at least one .lua file and .miz file.
|
||||
The .lua file contains the mission script file that shows how the use case was implemented.
|
||||
You can copy/paste code the code snippets from this .lua file into your missions, as it will accellerate your mission developments.
|
||||
You will learn, see, and understand how the different MOOSE classes need to be applied, and how you can create
|
||||
more complex mission scenarios by combining these MOOSE classes into a complex but powerful mission engine.
|
||||
|
||||
These exact test missions are also demonstrated at the demo videos in the YouTube channel.
|
||||
|
||||
# 5) MOOSE Directory Structure
|
||||
|
||||
The MOOSE framework is devided into a couple of directories:
|
||||
|
||||
* Moose Development: Contains the collection of lua files that define the MOOSE classes. You can use this directory to build the dynamic luadoc documentation intellisense in your eclipse development environment.
|
||||
* Moose Mission Setup: Contains the Moose.lua file to be included in your scripts when using MOOSE classes (see below the point Mission Design with Moose).
|
||||
* Moose Test Missions: Contains a directory structure with Moose Test Missions and examples. In each directory, you will find a miz file and a lua file containing the main mission script.
|
||||
* Moose Training: Contains the documentation of Moose generated with luadoc from the Moose source code. The presentations used during the videos in my [youtube channel](https://www.youtube.com/channel/UCjrA9j5LQoWsG4SpS8i79Qg), are also to be found here.
|
||||
|
||||
# Mission Design with Moose
|
||||
# 6) Mission Design with MOOSE
|
||||
|
||||
In order to create a mission using MOOSE, you'll have to include a file named **Moose.lua**:
|
||||
In order to create or design a mission using MOOSE, you'll have to include a file named **Moose.lua**:
|
||||
|
||||
1. Create a new mission in the DCS World Mission Editor.
|
||||
2. In the mission editor, create a new trigger.
|
||||
@ -73,13 +108,32 @@ IMPORTANT NOTE: When a new version of MOOSE is released, you'll have to UPDATE t
|
||||
This can be a tedious task, and for this purpose, a tool has been developed that will update the Moose.lua files automatically within your missions.
|
||||
Refer to the tool at [Moose Mission Setup\Moose Mission Update](https://github.com/FlightControl-Master/MOOSE/tree/master/Moose%20Mission%20Setup/Moose%20Mission%20Update) directory for further information included in the [READ.ME]() file.
|
||||
|
||||
# MOOSE Classes
|
||||
# 7) MOOSE Framework
|
||||
|
||||
The following classes are currently embedded within MOOSE and can be included within your mission scripts:
|
||||
The following classes are currently embedded within MOOSE framework and can be included within your mission scripts:
|
||||
|
||||

|
||||

|
||||
|
||||
## MOOSE Core Classes
|
||||
MOOSE is an Object Oriented framework and defines **Classes**, which are components that combine **Methods** and **Variables**/**Properties** as one encapsulated structure (table).
|
||||
Mission Designers can what we call **instantiate objects** from these MOOSE classes.
|
||||
|
||||
An example of what this means is shortly explained using the SPAWN class of MOOSE, which you can use to spawn new groups into your running mission.
|
||||
The SPAWN class simplifies the process of spawning, and it has many methods that you can use to create variations how you want your spawn object to spawn new groups.
|
||||
|
||||
```lua
|
||||
local SpawnObject = SPAWN:New( "GroupName" ) -- This creates a new SpawnObject from the SPAWN class, using the :New method constructor to instantiate a new SPAWN object searching for the GroupName as the late activated group defined within your Mission Editor.
|
||||
-- Nothing is spawned yet..., so let's use now the SpawnObject to spawn a new GROUP.
|
||||
|
||||
local SpawnGroup = SpawnObject:Spawn() -- Here we use the :Spawn() method of the SPAWN class. This method creates a new group from the GroupName template as defined within the Mission Editor.
|
||||
```
|
||||
|
||||
MOOSE Classes derive or inherit from each other, that means, within MOOSE there is an **Inheritance** structure where **inherited MOOSE Classes** are re-using properties and methods from the **Parent MOOSE Class**.
|
||||
This powerful concept is used everywhere within the MOOSE framework. The main (Parent) Class in the MOOSE framework is the BASE class. Every MOOSE Class is derived from this top BASE Class.
|
||||
So is also the SPAWN class derived from the BASE class. The BASE class provides powerful methods for debugging, event handling and implements the class handling logic.
|
||||
As a normal MOOSE user, you won't implement any code using inheritance but just know that the inheritance structure is omni present in the intellisense and documentation.
|
||||
You'll need to browse to the right MOOSE Class within the inheritance tree structure to identify which methods are properties are defined for which class.
|
||||
|
||||
## 7.1) MOOSE Core Classes
|
||||
|
||||
These classes define the base building blocks of the MOOSE framework. These classes are heavily used within the MOOSE framework.
|
||||
|
||||
@ -107,7 +161,7 @@ The POINT_VEC3 class manages the 3D simulation space, while the POINT_VEC2 class
|
||||
* [SCHEDULER](Documentation/Scheduler.html): This class implements a timer scheduler that will call at optional specified intervals repeatedly or just one time a scheduled function.
|
||||
|
||||
|
||||
## MOOSE Wrapper Classes
|
||||
## 7.2) MOOSE Wrapper Classes
|
||||
|
||||
MOOSE Wrapper Classes provide an object oriented hierarchical mechanism to manage the DCS objects within the simulator.
|
||||
Wrapper classes provide another easier mechanism to control Groups, Units, Statics, Airbases and other objects.
|
||||
@ -139,7 +193,7 @@ The CLIENT class derives from the UNIT class, thus contains the complete UNIT AP
|
||||
The STATIC class derives from the POSITIONABLE class, thus contains also the position API set.
|
||||
|
||||
|
||||
## MOOSE Functional Classes
|
||||
## 7.3) MOOSE Functional Classes
|
||||
|
||||
MOOSE Functional Classes provide various functions that are useful in mission design.
|
||||
|
||||
@ -151,7 +205,7 @@ MOOSE Functional Classes provide various functions that are useful in mission de
|
||||
|
||||
* [DETECTION](Moose Training/Documentation/Detection.html): Detect other units using the available sensors of the detection unit. The DETECTION_BASE derived classes will provide different methods how the sets of detected objects are built.
|
||||
|
||||
## MOOSE AI Controlling Classes
|
||||
## 7.4) MOOSE AI Controlling Classes
|
||||
|
||||
MOOSE AI Controlling Classes provide mechanisms to control AI over long lasting processes.
|
||||
These AI Controlling Classes are based on FSM (Finite State Machine) Classes, and provided an encapsulated way to make AI behave or execute an activity.
|
||||
@ -162,7 +216,7 @@ These AI Controlling Classes are based on FSM (Finite State Machine) Classes, an
|
||||
|
||||
* [AI_CARGO](Documentation/AI_Cargo.html): Make AI behave as cargo. Various CARGO types exist.
|
||||
|
||||
## MOOSE Tasking Classes
|
||||
## 7.5) MOOSE Human Tasking Classes
|
||||
|
||||
MOOSE Tasking Classes provide a comprehensive Mission Orchestration System.
|
||||
Through COMMANDCENTERs, multiple logical MISSIONs can be orchestrated for coalitions.
|
||||
@ -179,7 +233,7 @@ Each TASK has a TASK ACTION flow, which is the flow that a player (hosted by a U
|
||||
|
||||
* [TASK_A2G](Documentation/Task_A2G.html): Models a A2G Task, where a Player is routed towards an attack zone, and various A2G targets need to be eliminated.
|
||||
|
||||
## MOOSE Action Classes
|
||||
## 7.6) MOOSE Action Classes
|
||||
|
||||
MOOSE Action Classes are task action sub-flows, that can be used and combined, to quickly define a comprehensive end-to-end task action flow.
|
||||
For example, for the SEAD Task, the task action flow combines the actions ASSIGN, ROUTE, ACCOUNT and ASSIST task action sub-flows.
|
||||
@ -193,14 +247,22 @@ For example, for the SEAD Task, the task action flow combines the actions ASSIGN
|
||||
* [ACT_ASSIST](Documentation/Assist.html): Mechanisms to assist players executing a task. For example, acquire targets through smoking them.
|
||||
|
||||
|
||||
# Credits
|
||||
# 8) Credits
|
||||
|
||||
Note that the framework is based on code i've written myself, but some of it is also based on code that i've seen as great scripting code and ideas, and which i've revised. I see this framework evolving towards a broader public, and the ownership may dissapear (or parts of it). Consider this code public domain. Therefore a list of credits to all who have or are contributing (this list will increase over time): Grimes, Prof_Hilactic, xcom, the 476 virtual squadron team, ...
|
||||
Note that most of the framework is based on code i've written myself,
|
||||
but some code of it is also based on code that i've seen as great scripting code and ideas,
|
||||
and which has been revised and/or reworked to fit into the MOOSE framework.
|
||||
I see this framework evolving towards a broader public, and the ownership may dissapear (or parts of it). Consider this code public domain.
|
||||
Therefore a list of credits to all who have or are contributing (this list will increase over time).
|
||||
|
||||
You'll notice that within this framework, there are functions used from mist. I've taken the liberty to copy those atomic mist functions that are very nice and useful, and used those.
|
||||
|
||||
**Grimes**
|
||||
Without the effort of Grimes with MIST and his continuous documentation, the development of MOOSE would not have been possible. MOOSE is not replacing MIST, but is compensating it.
|
||||
Without the effort of Grimes with MIST and his continuous documentation of the DCS API, the development of MOOSE would not have been possible.
|
||||
MOOSE is complementary to [MIST](https://github.com/mrSkortch/MissionScriptingTools/releases), so if you use MIST in parallel with MOOSE objects, this should work.
|
||||
The documentation of the [DCS API] is the work of Grimes. Please consult his documentation in case of any question concerning the DCS API level.
|
||||
|
||||
|
||||
|
||||
**Prof_hilactic**
|
||||
SEAD Defenses. I've taken the script, and reworded it to fit within MOOSE. The script within MOOSE is hardly recognizable anymore from the original. Find here the posts: http://forums.eagle.ru/showpost.php?...59&postcount=1
|
||||
@ -227,4 +289,7 @@ Parts of these scripts will have to be redesigned to fit it into an OO framework
|
||||
|
||||
The rest of the framework functions and class definitions were my own developments, especially the core of MOOSE.
|
||||
Trust I've spent hours and hours investigating, trying and writing and documenting code building this framework.
|
||||
Hope you think the idea is great and useful.
|
||||
Hope you think the idea is great and useful.
|
||||
|
||||
Thank you!
|
||||
FC
|
||||
BIN
docs/Usage/Intellisense.JPG
Normal file
|
After Width: | Height: | Size: 73 KiB |