Core modules formatting (#1670)

* Update Fsm.lua

Code formatting and minor typo/documentation fixes.

* Update Goal.lua

Code formatting and minor typo/documentation fixes.

* Update Menu.lua

Code formatting and minor typo/documentation fixes.

* Update Message.lua

Code formatting and minor typo/documentation fixes.

* Update Report.lua

Code formatting and minor typo/documentation fixes.

* Update ScheduleDispatcher.lua

Code formatting and minor typo/documentation fixes.

* Update Scheduler.lua

Code formatting and minor typo/documentation fixes.

* Update Settings.lua

Code formatting and minor typo/documentation fixes.

* Update Spawn.lua

Code formatting and minor typo/documentation fixes.
This commit is contained in:
TommyC81 2021-12-20 15:59:56 +04:00 committed by GitHub
parent 55cee46a8d
commit 4a406604bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 2646 additions and 2753 deletions

View File

@ -53,7 +53,7 @@
--
-- Detailed explanations and API specifics are further below clarified and FSM derived class specifics are described in those class documentation sections.
--
-- ##__Dislaimer:__
-- ##__Disclaimer:__
-- The FSM class development is based on a finite state machine implementation made by Conroy Kyle.
-- The state machine can be found on [github](https://github.com/kyleconroy/lua-state-machine)
-- I've reworked this development (taken the concept), and created a **hierarchical state machine** out of it, embedded within the DCS simulator.
@ -69,7 +69,6 @@
--
-- ===
--
--
-- ### Author: **FlightControl**
-- ### Contributions: **funkyfranky**
--
@ -89,7 +88,6 @@ do -- FSM
-- @field #string current Current state name.
-- @extends Core.Base#BASE
--- A Finite State Machine (FSM) models a process flow that transitions between various **States** through triggered **Events**.
--
-- A FSM can only be in one of a finite number of states.
@ -145,12 +143,12 @@ do -- FSM
-- Most of the time, these Event Triggers are used within the Transition Handler methods, so that a workflow is created running through the state machine.
--
-- As explained above, a FSM supports **Linear State Transitions** and **Hierarchical State Transitions**, and both can be mixed to make a comprehensive FSM implementation.
-- The below documentation has a seperate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**.
-- The below documentation has a separate chapter explaining both transition modes, taking into account the **Transition Rules**, **Transition Handlers** and **Event Triggers**.
--
-- ## FSM Linear Transitions
--
-- Linear Transitions are Transition Rules allowing an FSM to transition from one or multiple possible **From** state(s) towards a **To** state upon a Triggered **Event**.
-- The Lineair transition rule evaluation will always be done from the **current state** of the FSM.
-- The Linear transition rule evaluation will always be done from the **current state** of the FSM.
-- If no valid Transition Rule can be found in the FSM, the FSM will log an error and stop.
--
-- ### FSM Transition Rules
@ -185,7 +183,7 @@ do -- FSM
-- * The From states can be **a table of strings**, indicating that the transition rule will be valid **if the current state** of the FSM will be **one of the given From states**.
-- * The From state can be a **"*"**, indicating that **the transition rule will always be valid**, regardless of the current state of the FSM.
--
-- The below code snippet shows how the two last lines can be rewritten and consensed.
-- The below code snippet shows how the two last lines can be rewritten and condensed.
--
-- FsmSwitch:AddTransition( { "On", "Middle" }, "SwitchOff", "Off" )
--
@ -221,7 +219,7 @@ do -- FSM
-- * The method **FSM:Event()** triggers an Event that will be processed **synchronously** or **immediately**.
-- * The method **FSM:__Event( __seconds__ )** triggers an Event that will be processed **asynchronously** over time, waiting __x seconds__.
--
-- The destinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time.
-- The distinction between these 2 Event Trigger methods are important to understand. An asynchronous call will "log" the Event Trigger to be executed at a later time.
-- Processing will just continue. Synchronous Event Trigger methods are useful to change states of the FSM immediately, but may have a larger processing impact.
--
-- The following example provides a little demonstration on the difference between synchronous and asynchronous Event Triggering.
@ -345,7 +343,6 @@ do -- FSM
-- ===
--
-- @field #FSM
--
FSM = {
ClassName = "FSM",
}
@ -379,7 +376,6 @@ do -- FSM
return self
end
--- Sets the start state of the FSM.
-- @param #FSM self
-- @param #string State A string defining the start state.
@ -388,7 +384,6 @@ do -- FSM
self.current = State
end
--- Returns the start state of the FSM.
-- @param #FSM self
-- @return #string A string containing the start state.
@ -416,7 +411,6 @@ do -- FSM
self:_eventmap( self.Events, Transition )
end
--- Returns a table of the transition rules defined within the FSM.
-- @param #FSM self
-- @return #table Transitions.
@ -450,7 +444,6 @@ do -- FSM
return Process
end
--- Returns a table of the SubFSM rules defined within the FSM.
-- @param #FSM self
-- @return #table Sub processes.
@ -499,7 +492,6 @@ do -- FSM
return self._EndStates or {}
end
--- Adds a score for the FSM to be achieved.
-- @param #FSM self
-- @param #string State is the state of the process when the score needs to be given. (See the relevant state descriptions of the process).
@ -563,27 +555,27 @@ do -- FSM
end
--- Event map.
--- Event map.
-- @param #FSM self
-- @param #table Events Events.
-- @param #table EventStructure Event structure.
function FSM:_eventmap( Events, EventStructure )
local Event = EventStructure.Event
local __Event = "__" .. EventStructure.Event
local Event = EventStructure.Event
local __Event = "__" .. EventStructure.Event
self[Event] = self[Event] or self:_create_transition(Event)
self[__Event] = self[__Event] or self:_delayed_transition(Event)
self[Event] = self[Event] or self:_create_transition( Event )
self[__Event] = self[__Event] or self:_delayed_transition( Event )
-- Debug message.
self:T2( "Added methods: " .. Event .. ", " .. __Event )
-- Debug message.
self:T2( "Added methods: " .. Event .. ", " .. __Event )
Events[Event] = self.Events[Event] or { map = {} }
self:_add_to_map( Events[Event].map, EventStructure )
Events[Event] = self.Events[Event] or { map = {} }
self:_add_to_map( Events[Event].map, EventStructure )
end
--- Sub maps.
--- Sub maps.
-- @param #FSM self
-- @param #table subs Subs.
-- @param #table sub Sub.
@ -613,7 +605,7 @@ do -- FSM
-- @param #string EventName Event name.
-- @return Value.
function FSM:_call_handler( step, trigger, params, EventName )
--env.info(string.format("FF T=%.3f _call_handler step=%s, trigger=%s, event=%s", timer.getTime(), step, trigger, EventName))
-- env.info(string.format("FF T=%.3f _call_handler step=%s, trigger=%s, event=%s", timer.getTime(), step, trigger, EventName))
local handler = step .. trigger
@ -644,10 +636,12 @@ do -- FSM
return errmsg
end
--return self[handler](self, unpack( params ))
-- return self[handler](self, unpack( params ))
-- Protected call.
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler )
local Result, Value = xpcall( function()
return self[handler]( self, unpack( params ) )
end, ErrorHandler )
return Value
end
@ -671,17 +665,16 @@ do -- FSM
local From = self.current
-- Parameters.
local Params = { From, EventName, To, ... }
local Params = { From, EventName, To, ... }
if self["onleave".. From] or
self["OnLeave".. From] or
self["onbefore".. EventName] or
self["OnBefore".. EventName] or
self["onafter".. EventName] or
self["OnAfter".. EventName] or
self["onenter".. To] or
self["OnEnter".. To] then
if self["onleave" .. From] or
self["OnLeave" .. From] or
self["onbefore" .. EventName] or
self["OnBefore" .. EventName] or
self["onafter" .. EventName] or
self["OnAfter" .. EventName] or
self["onenter" .. To] or
self["OnEnter" .. To] then
if self:_call_handler( "onbefore", EventName, Params, EventName ) == false then
self:T( "*** FSM *** Cancel" .. " *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** onbefore" .. EventName )
@ -716,11 +709,11 @@ do -- FSM
end
if ClassName == "FSM_CONTROLLABLE" then
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** TaskUnit: " .. self.Controllable.ControllableName .. " *** " )
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** TaskUnit: " .. self.Controllable.ControllableName .. " *** " )
end
if ClassName == "FSM_PROCESS" then
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** Task: " .. self.Task:GetName() .. ", TaskUnit: " .. self.Controllable.ControllableName .. " *** " )
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** Task: " .. self.Task:GetName() .. ", TaskUnit: " .. self.Controllable.ControllableName .. " *** " )
end
end
@ -733,10 +726,10 @@ do -- FSM
for _, sub in pairs( subtable ) do
--if sub.nextevent then
-- if sub.nextevent then
-- self:F2( "nextevent = " .. sub.nextevent )
-- self[sub.nextevent]( self )
--end
-- end
self:T( "*** FSM *** Sub *** " .. sub.StartEvent )
@ -753,11 +746,11 @@ do -- FSM
self:T( "*** FSM *** End *** " .. Event )
self:_call_handler("onenter", To, Params, EventName )
self:_call_handler("OnEnter", To, Params, EventName )
self:_call_handler("onafter", EventName, Params, EventName )
self:_call_handler("OnAfter", EventName, Params, EventName )
self:_call_handler("onstate", "change", Params, EventName )
self:_call_handler( "onenter", To, Params, EventName )
self:_call_handler( "OnEnter", To, Params, EventName )
self:_call_handler( "onafter", EventName, Params, EventName )
self:_call_handler( "OnAfter", EventName, Params, EventName )
self:_call_handler( "onstate", "change", Params, EventName )
fsmparent[Event]( fsmparent )
@ -766,13 +759,13 @@ do -- FSM
if execute then
self:_call_handler("onafter", EventName, Params, EventName )
self:_call_handler("OnAfter", EventName, Params, EventName )
self:_call_handler( "onafter", EventName, Params, EventName )
self:_call_handler( "OnAfter", EventName, Params, EventName )
self:_call_handler("onenter", To, Params, EventName )
self:_call_handler("OnEnter", To, Params, EventName )
self:_call_handler( "onenter", To, Params, EventName )
self:_call_handler( "OnEnter", To, Params, EventName )
self:_call_handler("onstate", "change", Params, EventName )
self:_call_handler( "onstate", "change", Params, EventName )
end
else
@ -809,16 +802,16 @@ do -- FSM
self._EventSchedules[EventName] = CallID
-- Debug output.
self:T2(string.format("NEGATIVE Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring(CallID)))
self:T2( string.format( "NEGATIVE Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring( CallID ) ) )
else
self:T2(string.format("NEGATIVE Event %s delayed by %.1f sec CANCELLED as we already have such an event in the queue.", EventName, DelaySeconds))
self:T2( string.format( "NEGATIVE Event %s delayed by %.1f sec CANCELLED as we already have such an event in the queue.", EventName, DelaySeconds ) )
-- reschedule
end
else
CallID = self.CallScheduler:Schedule( self, self._handler, { EventName, ... }, DelaySeconds or 1, nil, nil, nil, 4, true )
self:T2(string.format("Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring(CallID)))
self:T2( string.format( "Event %s delayed by %.1f sec SCHEDULED with CallID=%s", EventName, DelaySeconds, tostring( CallID ) ) )
end
else
error( "FSM: An asynchronous event trigger requires a DelaySeconds parameter!!! This can be positive or negative! Sorry, but will not process this." )
@ -835,7 +828,9 @@ do -- FSM
-- @param #string EventName Event name.
-- @return #function Function.
function FSM:_create_transition( EventName )
return function( self, ... ) return self._handler( self, EventName , ... ) end
return function( self, ... )
return self._handler( self, EventName, ... )
end
end
--- Go sub.
@ -862,16 +857,16 @@ do -- FSM
local FSMParent = self.fsmparent
if FSMParent and self.endstates[Current] then
--self:T( { 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:T( { ParentFrom, self.ReturnEvents } )
-- self:T( { ParentFrom, self.ReturnEvents } )
local Event = self.ReturnEvents[Current]
--self:T( { Event } )
-- self:T( { Event } )
if Event then
return FSMParent, Event
else
--self:T( { "Could not find parent event name for state ", ParentFrom } )
-- self:T( { "Could not find parent event name for state ", ParentFrom } )
end
end
@ -883,17 +878,17 @@ do -- FSM
-- @param #table Map Map.
-- @param #table Event Event table.
function FSM:_add_to_map( Map, Event )
self:F3( { Map, Event } )
self:F3( { Map, Event } )
if type(Event.From) == 'string' then
Map[Event.From] = Event.To
if type( Event.From ) == 'string' then
Map[Event.From] = Event.To
else
for _, From in ipairs(Event.From) do
Map[From] = Event.To
for _, From in ipairs( Event.From ) do
Map[From] = Event.To
end
end
self:T3( { Map, Event } )
self:T3( { Map, Event } )
end
--- Get current state.
@ -922,7 +917,7 @@ do -- FSM
-- @param #FSM self
-- @param #string State State name.
-- @param #boolean If true, FSM is in this state.
function FSM:is(state)
function FSM:is( state )
return self.current == state
end
@ -931,11 +926,11 @@ do -- FSM
-- @param #string e Event name.
-- @return #boolean If true, FSM can do the event.
-- @return #string To state.
function FSM:can(e)
function FSM:can( e )
local Event = self.Events[e]
--self:F3( { self.current, Event } )
-- self:F3( { self.current, Event } )
local To = Event and Event.map[self.current] or Event.map['*']
@ -946,8 +941,8 @@ do -- FSM
-- @param #FSM self
-- @param #string e Event name.
-- @return #boolean If true, FSM cannot do the event.
function FSM:cannot(e)
return not self:can(e)
function FSM:cannot( e )
return not self:can( e )
end
end
@ -1036,7 +1031,7 @@ do -- FSM_CONTROLLABLE
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function FSM_CONTROLLABLE:OnAfterStop(Controllable,From,Event,To)
function FSM_CONTROLLABLE:OnAfterStop( Controllable, From, Event, To )
-- Clear all pending schedules
self.CallScheduler:Clear()
@ -1047,7 +1042,7 @@ do -- FSM_CONTROLLABLE
-- @param Wrapper.Controllable#CONTROLLABLE FSMControllable
-- @return #FSM_CONTROLLABLE
function FSM_CONTROLLABLE:SetControllable( FSMControllable )
--self:F( FSMControllable:GetName() )
-- self:F( FSMControllable:GetName() )
self.Controllable = FSMControllable
end
@ -1075,9 +1070,11 @@ do -- FSM_CONTROLLABLE
if self[handler] then
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** TaskUnit: " .. self.Controllable:GetName() )
self._EventSchedules[EventName] = nil
local Result, Value = xpcall( function() return self[handler]( self, self.Controllable, unpack( params ) ) end, ErrorHandler )
local Result, Value = xpcall( function()
return self[handler]( self, self.Controllable, unpack( params ) )
end, ErrorHandler )
return Value
--return self[handler]( self, self.Controllable, unpack( params ) )
-- return self[handler]( self, self.Controllable, unpack( params ) )
end
end
@ -1089,16 +1086,13 @@ do -- FSM_PROCESS
-- @field Tasking.Task#TASK Task
-- @extends Core.Fsm#FSM_CONTROLLABLE
--- FSM_PROCESS class models Finite State Machines for @{Task} actions, which control @{Client}s.
--
-- ===
--
-- @field #FSM_PROCESS FSM_PROCESS
--
FSM_PROCESS = {
ClassName = "FSM_PROCESS",
}
FSM_PROCESS = { ClassName = "FSM_PROCESS" }
--- Creates a new FSM_PROCESS object.
-- @param #FSM_PROCESS self
@ -1107,7 +1101,7 @@ do -- FSM_PROCESS
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- Core.Fsm#FSM_PROCESS
--self:F( Controllable )
-- self:F( Controllable )
self:Assign( Controllable, Task )
@ -1139,10 +1133,12 @@ do -- FSM_PROCESS
self._EventSchedules[EventName] = nil
local Result, Value
if self.Controllable and self.Controllable:IsAlive() == true then
Result, Value = xpcall( function() return self[handler]( self, self.Controllable, self.Task, unpack( params ) ) end, ErrorHandler )
Result, Value = xpcall( function()
return self[handler]( self, self.Controllable, self.Task, unpack( params ) )
end, ErrorHandler )
end
return Value
--return self[handler]( self, self.Controllable, unpack( params ) )
-- return self[handler]( self, self.Controllable, unpack( params ) )
end
end
@ -1152,7 +1148,6 @@ do -- FSM_PROCESS
function FSM_PROCESS:Copy( Controllable, Task )
self:T( { self:GetClassNameAndID() } )
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
NewFsm:Assign( Controllable, Task )
@ -1170,7 +1165,7 @@ do -- FSM_PROCESS
-- Copy Processes
for ProcessID, Process in pairs( self:GetProcesses() ) do
--self:E( { Process:GetName() } )
-- self:E( { Process:GetName() } )
local FsmProcess = NewFsm:AddProcess( Process.From, Process.Event, Process.fsm:Copy( Controllable, Task ), Process.ReturnEvents )
end
@ -1244,7 +1239,7 @@ do -- FSM_PROCESS
return self:GetTask():GetMission():GetCommandCenter()
end
-- TODO: Need to check and fix that an FSM_PROCESS is only for a UNIT. Not for a GROUP.
-- TODO: Need to check and fix that an FSM_PROCESS is only for a UNIT. Not for a GROUP.
--- Send a message of the @{Task} to the Group of the Unit.
-- @param #FSM_PROCESS self
@ -1263,32 +1258,29 @@ do -- FSM_PROCESS
CC:MessageToGroup( Message, TaskGroup )
end
--- Assign the process to a @{Wrapper.Unit} and activate the process.
-- @param #FSM_PROCESS self
-- @param Task.Tasking#TASK Task
-- @param Wrapper.Unit#UNIT ProcessUnit
-- @return #FSM_PROCESS self
function FSM_PROCESS:Assign( ProcessUnit, Task )
--self:T( { Task:GetName(), ProcessUnit:GetName() } )
-- self:T( { Task:GetName(), ProcessUnit:GetName() } )
self:SetControllable( ProcessUnit )
self:SetTask( Task )
--self.ProcessGroup = ProcessUnit:GetGroup()
-- self.ProcessGroup = ProcessUnit:GetGroup()
return self
end
-- function FSM_PROCESS:onenterAssigned( ProcessUnit, Task, From, Event, To )
--
-- if From( "Planned" ) then
-- self:T( "*** FSM *** Assign *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
-- self.Task:Assign()
-- end
-- end
-- function FSM_PROCESS:onenterAssigned( ProcessUnit, Task, From, Event, To )
--
-- if From( "Planned" ) then
-- self:T( "*** FSM *** Assign *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
-- self.Task:Assign()
-- end
-- end
function FSM_PROCESS:onenterFailed( ProcessUnit, Task, From, Event, To )
self:T( "*** FSM *** Failed *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
@ -1296,7 +1288,6 @@ do -- FSM_PROCESS
self.Task:Fail()
end
--- StateMachine callback function for a FSM_PROCESS
-- @param #FSM_PROCESS self
-- @param Wrapper.Controllable#CONTROLLABLE ProcessUnit
@ -1309,10 +1300,10 @@ do -- FSM_PROCESS
self:T( "*** FSM *** Change *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
end
-- if self:IsTrace() then
-- MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
-- self:F2( { Scores = self._Scores, To = To } )
-- end
-- if self:IsTrace() then
-- MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
-- self:F2( { Scores = self._Scores, To = To } )
-- end
-- 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
@ -1374,8 +1365,10 @@ do -- FSM_TASK
if self[handler] then
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** Task: " .. self.TaskName )
self._EventSchedules[EventName] = nil
--return self[handler]( self, unpack( params ) )
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler )
-- return self[handler]( self, unpack( params ) )
local Result, Value = xpcall( function()
return self[handler]( self, unpack( params ) )
end, ErrorHandler )
return Value
end
end
@ -1389,14 +1382,12 @@ do -- FSM_SET
-- @field Core.Set#SET_BASE Set
-- @extends Core.Fsm#FSM
--- FSM_SET class models Finite State Machines for @{Set}s. Note that these FSMs control multiple objects!!! So State concerns here
-- for multiple objects or the position of the state machine in the process.
--
-- ===
--
-- @field #FSM_SET FSM_SET
--
FSM_SET = {
ClassName = "FSM_SET",
}
@ -1434,8 +1425,8 @@ do -- FSM_SET
return self.Controllable
end
function FSM_SET:_call_handler( step, trigger, params, EventName )
local handler = step .. trigger
function FSM_SET:_call_handler( step, trigger, params, EventName )
local handler = step .. trigger
if self[handler] then
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] )
self._EventSchedules[EventName] = nil

View File

@ -22,13 +22,11 @@
-- @module Core.Goal
-- @image Core_Goal.JPG
do -- Goal
--- @type GOAL
-- @extends Core.Fsm#FSM
--- Models processes that have an objective with a defined achievement. Derived classes implement the ways how the achievements can be realized.
--
-- # 1. GOAL constructor
@ -105,9 +103,8 @@ do -- Goal
-- @param #string Event
-- @param #string To
self:SetStartState( "Pending" )
self:AddTransition( "*", "Achieved", "Achieved" )
self:AddTransition( "*", "Achieved", "Achieved" )
--- Achieved Handler OnBefore for GOAL
-- @function [parent=#GOAL] OnBeforeAchieved
@ -138,25 +135,22 @@ do -- Goal
return self
end
--- Add a new contribution by a player.
-- @param #GOAL self
-- @param #string PlayerName The name of the player.
function GOAL:AddPlayerContribution( PlayerName )
self:F({PlayerName})
self:F( { PlayerName } )
self.Players[PlayerName] = self.Players[PlayerName] or 0
self.Players[PlayerName] = self.Players[PlayerName] + 1
self.TotalContributions = self.TotalContributions + 1
end
--- @param #GOAL self
-- @param #number Player contribution.
function GOAL:GetPlayerContribution( PlayerName )
return self.Players[PlayerName] or 0
end
--- Get the players who contributed to achieve the goal.
-- The result is a list of players, sorted by the name of the players.
-- @param #GOAL self
@ -165,7 +159,6 @@ do -- Goal
return self.Players or {}
end
--- Gets the total contributions that happened to achieve the goal.
-- The result is a number.
-- @param #GOAL self
@ -174,8 +167,6 @@ do -- Goal
return self.TotalContributions or 0
end
--- Validates if the goal is achieved.
-- @param #GOAL self
-- @return #boolean true if the goal is achieved.

View File

@ -14,7 +14,7 @@
-- * Only create or delete menus when required, and keep existing menus persistent.
-- * Update menu structures.
-- * Refresh menu structures intelligently, based on a time stamp of updates.
-- - Delete obscolete menus.
-- - Delete obsolete menus.
-- - Create new one where required.
-- - Don't touch the existing ones.
-- * Provide a variable amount of parameters to menus.
@ -23,7 +23,7 @@
-- * Provide a great tool to manage menus in your code.
--
-- DCS Menus can be managed using the MENU classes.
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scanerios where you need to
-- The advantage of using MENU classes is that it hides the complexity of dealing with menu management in more advanced scenarios where you need to
-- set menus and later remove them, and later set them again. You'll find while using use normal DCS scripting functions, that setting and removing
-- menus is not a easy feat if you have complex menu hierarchies defined.
-- Using the MOOSE menu classes, the removal and refreshing of menus are nicely being handled within these classes, and becomes much more easy.
@ -53,7 +53,6 @@
-- @module Core.Menu
-- @image Core_Menu.JPG
MENU_INDEX = {}
MENU_INDEX.MenuMission = {}
MENU_INDEX.MenuMission.Menus = {}
@ -64,8 +63,6 @@ MENU_INDEX.Coalition[coalition.side.RED] = {}
MENU_INDEX.Coalition[coalition.side.RED].Menus = {}
MENU_INDEX.Group = {}
function MENU_INDEX:ParentPath( ParentMenu, MenuText )
local Path = ParentMenu and "@" .. table.concat( ParentMenu.MenuPath or {}, "@" ) or ""
@ -98,29 +95,25 @@ function MENU_INDEX:ParentPath( ParentMenu, MenuText )
end
function MENU_INDEX:PrepareMission()
self.MenuMission.Menus = self.MenuMission.Menus or {}
self.MenuMission.Menus = self.MenuMission.Menus or {}
end
function MENU_INDEX:PrepareCoalition( CoalitionSide )
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
self.Coalition[CoalitionSide] = self.Coalition[CoalitionSide] or {}
self.Coalition[CoalitionSide].Menus = self.Coalition[CoalitionSide].Menus or {}
end
---
-- @param Wrapper.Group#GROUP Group
function MENU_INDEX:PrepareGroup( Group )
if Group and Group:IsAlive() ~= nil then -- something was changed here!
if Group and Group:IsAlive() ~= nil then -- something was changed here!
local GroupName = Group:GetName()
self.Group[GroupName] = self.Group[GroupName] or {}
self.Group[GroupName].Menus = self.Group[GroupName].Menus or {}
end
end
function MENU_INDEX:HasMissionMenu( Path )
return self.MenuMission.Menus[Path]
@ -136,8 +129,6 @@ function MENU_INDEX:ClearMissionMenu( Path )
self.MenuMission.Menus[Path] = nil
end
function MENU_INDEX:HasCoalitionMenu( Coalition, Path )
return self.Coalition[Coalition].Menus[Path]
@ -153,8 +144,6 @@ function MENU_INDEX:ClearCoalitionMenu( Coalition, Path )
self.Coalition[Coalition].Menus[Path] = nil
end
function MENU_INDEX:HasGroupMenu( Group, Path )
if Group and Group:IsAlive() then
local MenuGroupName = Group:GetName()
@ -166,7 +155,7 @@ end
function MENU_INDEX:SetGroupMenu( Group, Path, Menu )
local MenuGroupName = Group:GetName()
Group:F({MenuGroupName=MenuGroupName,Path=Path})
Group:F( { MenuGroupName = MenuGroupName, Path = Path } )
self.Group[MenuGroupName].Menus[Path] = Menu
end
@ -178,32 +167,25 @@ end
function MENU_INDEX:Refresh( Group )
for MenuID, Menu in pairs( self.MenuMission.Menus ) do
Menu:Refresh()
end
for MenuID, Menu in pairs( self.MenuMission.Menus ) do
Menu:Refresh()
end
for MenuID, Menu in pairs( self.Coalition[coalition.side.BLUE].Menus ) do
Menu:Refresh()
end
for MenuID, Menu in pairs( self.Coalition[coalition.side.BLUE].Menus ) do
Menu:Refresh()
end
for MenuID, Menu in pairs( self.Coalition[coalition.side.RED].Menus ) do
Menu:Refresh()
end
for MenuID, Menu in pairs( self.Coalition[coalition.side.RED].Menus ) do
Menu:Refresh()
end
local GroupName = Group:GetName()
for MenuID, Menu in pairs( self.Group[GroupName].Menus ) do
Menu:Refresh()
end
local GroupName = Group:GetName()
for MenuID, Menu in pairs( self.Group[GroupName].Menus ) do
Menu:Refresh()
end
end
do -- MENU_BASE
--- @type MENU_BASE
@ -216,10 +198,10 @@ do -- MENU_BASE
ClassName = "MENU_BASE",
MenuPath = nil,
MenuText = "",
MenuParentPath = nil
MenuParentPath = nil,
}
--- Consructor
--- Constructor
-- @param #MENU_BASE
-- @return #MENU_BASE
function MENU_BASE:New( MenuText, ParentMenu )
@ -229,13 +211,13 @@ do -- MENU_BASE
MenuParentPath = ParentMenu.MenuPath
end
local self = BASE:Inherit( self, BASE:New() )
local self = BASE:Inherit( self, BASE:New() )
self.MenuPath = nil
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self.MenuParentPath = MenuParentPath
self.Path = ( self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "" ) .. "@" .. self.MenuText
self.MenuPath = nil
self.MenuText = MenuText
self.ParentMenu = ParentMenu
self.MenuParentPath = MenuParentPath
self.Path = (self.ParentMenu and "@" .. table.concat( self.MenuParentPath or {}, "@" ) or "") .. "@" .. self.MenuText
self.Menus = {}
self.MenuCount = 0
self.MenuStamp = timer.getTime()
@ -246,7 +228,7 @@ do -- MENU_BASE
self.ParentMenu.Menus[MenuText] = self
end
return self
return self
end
function MENU_BASE:SetParentMenu( MenuText, Menu )
@ -262,7 +244,7 @@ do -- MENU_BASE
self.ParentMenu.Menus[MenuText] = nil
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1
if self.ParentMenu.MenuCount == 0 then
--self.ParentMenu:Remove()
-- self.ParentMenu:Remove()
end
end
end
@ -272,12 +254,11 @@ do -- MENU_BASE
-- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}.
-- @return #MENU_BASE
function MENU_BASE:SetRemoveParent( RemoveParent )
--self:F( { RemoveParent } )
-- self:F( { RemoveParent } )
self.MenuRemoveParent = RemoveParent
return self
end
--- Gets a @{Menu} from a parent @{Menu}
-- @param #MENU_BASE self
-- @param #string MenuText The text of the child menu.
@ -295,7 +276,6 @@ do -- MENU_BASE
return self
end
--- Gets a menu stamp for later prevention of menu removal.
-- @param #MENU_BASE self
-- @return MenuStamp
@ -303,7 +283,6 @@ do -- MENU_BASE
return timer.getTime()
end
--- Sets a time stamp for later prevention of menu removal.
-- @param #MENU_BASE self
-- @param MenuStamp
@ -346,7 +325,7 @@ do -- MENU_COMMAND_BASE
-- @return #MENU_COMMAND_BASE
function MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, CommandMenuArguments )
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) -- #MENU_COMMAND_BASE
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) -- #MENU_COMMAND_BASE
-- When a menu function goes into error, DCS displays an obscure menu message.
-- This error handler catches the menu error and displays the full call stack.
@ -367,7 +346,7 @@ do -- MENU_COMMAND_BASE
local Status, Result = xpcall( MenuFunction, ErrorHandler )
end
return self
return self
end
--- This sets the new command function of a menu,
@ -394,7 +373,6 @@ do -- MENU_COMMAND_BASE
end
do -- MENU_MISSION
--- @type MENU_MISSION
@ -406,13 +384,13 @@ do -- MENU_MISSION
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_MISSION.Remove}.
-- @field #MENU_MISSION
MENU_MISSION = {
ClassName = "MENU_MISSION"
ClassName = "MENU_MISSION",
}
--- MENU_MISSION constructor. Creates a new MENU_MISSION object and creates the menu for a complete mission file.
-- @param #MENU_MISSION self
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
-- @return #MENU_MISSION
function MENU_MISSION:New( MenuText, ParentMenu )
@ -470,7 +448,7 @@ do -- MENU_MISSION
if MissionMenu == self then
self:RemoveSubMenus()
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
self:F( { Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then
missionCommands.removeItem( self.MenuPath )
@ -487,8 +465,6 @@ do -- MENU_MISSION
return self
end
end
do -- MENU_MISSION_COMMAND
@ -503,7 +479,7 @@ do -- MENU_MISSION_COMMAND
--
-- @field #MENU_MISSION_COMMAND
MENU_MISSION_COMMAND = {
ClassName = "MENU_MISSION_COMMAND"
ClassName = "MENU_MISSION_COMMAND",
}
--- MENU_MISSION constructor. Creates a new radio command item for a complete mission file, which can invoke a function with parameters.
@ -556,7 +532,7 @@ do -- MENU_MISSION_COMMAND
if MissionMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
self:F( { Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then
missionCommands.removeItem( self.MenuPath )
@ -575,8 +551,6 @@ do -- MENU_MISSION_COMMAND
end
do -- MENU_COALITION
--- @type MENU_COALITION
@ -627,14 +601,14 @@ do -- MENU_COALITION
--
-- @field #MENU_COALITION
MENU_COALITION = {
ClassName = "MENU_COALITION"
ClassName = "MENU_COALITION",
}
--- MENU_COALITION constructor. Creates a new MENU_COALITION object and creates the menu for a complete coalition.
-- @param #MENU_COALITION self
-- @param DCS#coalition.side Coalition The coalition owning the menu.
-- @param #string MenuText The text for the menu.
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the perent menu of DCS world (under F10 other).
-- @param #table ParentMenu The parent menu. This parameter can be ignored if you want the menu to be located at the parent menu of DCS world (under F10 other).
-- @return #MENU_COALITION self
function MENU_COALITION:New( Coalition, MenuText, ParentMenu )
@ -693,7 +667,7 @@ do -- MENU_COALITION
if CoalitionMenu == self then
self:RemoveSubMenus()
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
@ -712,8 +686,6 @@ do -- MENU_COALITION
end
do -- MENU_COALITION_COMMAND
--- @type MENU_COALITION_COMMAND
@ -726,7 +698,7 @@ do -- MENU_COALITION_COMMAND
--
-- @field #MENU_COALITION_COMMAND
MENU_COALITION_COMMAND = {
ClassName = "MENU_COALITION_COMMAND"
ClassName = "MENU_COALITION_COMMAND",
}
--- MENU_COALITION constructor. Creates a new radio command item for a coalition, which can invoke a function with parameters.
@ -760,7 +732,6 @@ do -- MENU_COALITION_COMMAND
end
--- Refreshes a radio item for a coalition
-- @param #MENU_COALITION_COMMAND self
-- @return #MENU_COALITION_COMMAND
@ -784,7 +755,7 @@ do -- MENU_COALITION_COMMAND
if CoalitionMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
self:F( { Coalition = self.Coalition, Text = self.MenuText, Path = self.MenuPath } )
if self.MenuPath ~= nil then
missionCommands.removeItemForCoalition( self.Coalition, self.MenuPath )
@ -803,7 +774,6 @@ do -- MENU_COALITION_COMMAND
end
--- MENU_GROUP
do
@ -817,7 +787,6 @@ do
--- @type MENU_GROUP
-- @extends Core.Menu#MENU_BASE
--- Manages the main menus for @{Wrapper.Group}s.
--
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
@ -875,7 +844,7 @@ do
--
-- @field #MENU_GROUP
MENU_GROUP = {
ClassName = "MENU_GROUP"
ClassName = "MENU_GROUP",
}
--- MENU_GROUP constructor. Creates a new radio menu item for a group.
@ -938,7 +907,6 @@ do
end
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP self
-- @param MenuStamp
@ -953,7 +921,7 @@ do
if GroupMenu == self then
self:RemoveSubMenus( MenuStamp, MenuTag )
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
@ -971,7 +939,6 @@ do
return self
end
--- @type MENU_GROUP_COMMAND
-- @extends Core.Menu#MENU_COMMAND_BASE
@ -981,7 +948,7 @@ do
--
-- @field #MENU_GROUP_COMMAND
MENU_GROUP_COMMAND = {
ClassName = "MENU_GROUP_COMMAND"
ClassName = "MENU_GROUP_COMMAND",
}
--- Creates a new radio command item for a group
@ -1043,9 +1010,9 @@ do
if GroupMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
end
MENU_INDEX:ClearGroupMenu( self.Group, Path )
@ -1069,7 +1036,6 @@ do
--- @type MENU_GROUP_DELAYED
-- @extends Core.Menu#MENU_BASE
--- The MENU_GROUP_DELAYED class manages the main menus for groups.
-- You can add menus with the @{#MENU_GROUP.New} method, which constructs a MENU_GROUP object and returns you the object reference.
-- Using this object reference, you can then remove ALL the menus and submenus underlying automatically with @{#MENU_GROUP.Remove}.
@ -1079,7 +1045,7 @@ do
--
-- @field #MENU_GROUP_DELAYED
MENU_GROUP_DELAYED = {
ClassName = "MENU_GROUP_DELAYED"
ClassName = "MENU_GROUP_DELAYED",
}
--- MENU_GROUP_DELAYED constructor. Creates a new radio menu item for a group.
@ -1116,7 +1082,6 @@ do
end
--- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP_DELAYED self
-- @return #MENU_GROUP_DELAYED
@ -1135,7 +1100,6 @@ do
end
--- Refreshes a new radio item for a group and submenus
-- @param #MENU_GROUP_DELAYED self
-- @return #MENU_GROUP_DELAYED
@ -1167,7 +1131,6 @@ do
end
--- Removes the main menu and sub menus recursively of this MENU_GROUP.
-- @param #MENU_GROUP_DELAYED self
-- @param MenuStamp
@ -1182,7 +1145,7 @@ do
if GroupMenu == self then
self:RemoveSubMenus( MenuStamp, MenuTag )
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
@ -1200,7 +1163,6 @@ do
return self
end
--- @type MENU_GROUP_COMMAND_DELAYED
-- @extends Core.Menu#MENU_COMMAND_BASE
@ -1211,7 +1173,7 @@ do
--
-- @field #MENU_GROUP_COMMAND_DELAYED
MENU_GROUP_COMMAND_DELAYED = {
ClassName = "MENU_GROUP_COMMAND_DELAYED"
ClassName = "MENU_GROUP_COMMAND_DELAYED",
}
--- Creates a new radio command item for a group
@ -1292,7 +1254,7 @@ do
if GroupMenu == self then
if not MenuStamp or self.MenuStamp ~= MenuStamp then
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
if (not MenuTag) or (MenuTag and self.MenuTag and MenuTag == self.MenuTag) then
if self.MenuPath ~= nil then
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )

View File

@ -56,9 +56,9 @@
--
-- @field #MESSAGE
MESSAGE = {
ClassName = "MESSAGE",
MessageCategory = 0,
MessageID = 0,
ClassName = "MESSAGE",
MessageCategory = 0,
MessageID = 0,
}
--- Message Types
@ -68,10 +68,9 @@ MESSAGE.Type = {
Information = "Information",
Briefing = "Briefing Report",
Overview = "Overview Report",
Detailed = "Detailed Report"
Detailed = "Detailed Report",
}
--- Creates a new MESSAGE object. Note that these MESSAGE objects are not yet displayed on the display panel. You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
-- @param self
-- @param #string MessageText is the text of the Message.
@ -80,25 +79,26 @@ MESSAGE.Type = {
-- @param #boolean ClearScreen (optional) Clear all previous messages if true.
-- @return #MESSAGE
-- @usage
-- -- Create a series of new Messages.
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", 25, "End of Mission" )
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
--
-- -- Create a series of new Messages.
-- -- MessageAll is meant to be sent to all players, for 25 seconds, and is classified as "Score".
-- -- MessageRED is meant to be sent to the RED players only, for 10 seconds, and is classified as "End of Mission", with ID "Win".
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
-- -- MessageClient1 is meant to be sent to a Client, for 25 seconds, and is classified as "Score", with ID "Score".
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", 25, "End of Mission" )
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", 25, "Penalty" )
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", 25, "Score" )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", 25, "Score")
--
function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen )
local self = BASE:Inherit( self, BASE:New() )
self:F( { MessageText, MessageDuration, MessageCategory } )
local self = BASE:Inherit( self, BASE:New() )
self:F( { MessageText, MessageDuration, MessageCategory } )
self.MessageType = nil
-- When no MessageCategory is given, we don't show it as a title...
if MessageCategory and MessageCategory ~= "" then
if MessageCategory:sub(-1) ~= "\n" then
if MessageCategory and MessageCategory ~= "" then
if MessageCategory:sub( -1 ) ~= "\n" then
self.MessageCategory = MessageCategory .. ": "
else
self.MessageCategory = MessageCategory:sub( 1, -2 ) .. ":\n"
@ -107,23 +107,22 @@ function MESSAGE:New( MessageText, MessageDuration, MessageCategory, ClearScreen
self.MessageCategory = ""
end
self.ClearScreen=false
if ClearScreen~=nil then
self.ClearScreen=ClearScreen
self.ClearScreen = false
if ClearScreen ~= nil then
self.ClearScreen = ClearScreen
end
self.MessageDuration = MessageDuration or 5
self.MessageTime = timer.getTime()
self.MessageText = MessageText:gsub("^\n","",1):gsub("\n$","",1)
self.MessageDuration = MessageDuration or 5
self.MessageTime = timer.getTime()
self.MessageText = MessageText:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
self.MessageSent = false
self.MessageGroup = false
self.MessageCoalition = false
self.MessageSent = false
self.MessageGroup = false
self.MessageCoalition = false
return self
return self
end
--- Creates a new MESSAGE object of a certain type.
-- Note that these MESSAGE objects are not yet displayed on the display panel.
-- You must use the functions @{ToClient} or @{ToCoalition} or @{ToAll} to send these Messages to the respective recipients.
@ -134,10 +133,12 @@ end
-- @param #boolean ClearScreen (optional) Clear all previous messages.
-- @return #MESSAGE
-- @usage
--
-- MessageAll = MESSAGE:NewType( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", MESSAGE.Type.Information )
-- MessageRED = MESSAGE:NewType( "To the RED Players: You receive a penalty because you've killed one of your own units", MESSAGE.Type.Information )
-- MessageClient1 = MESSAGE:NewType( "Congratulations, you've just hit a target", MESSAGE.Type.Update )
-- MessageClient2 = MESSAGE:NewType( "Congratulations, you've just killed a target", MESSAGE.Type.Update )
--
function MESSAGE:NewType( MessageText, MessageType, ClearScreen )
local self = BASE:Inherit( self, BASE:New() )
@ -145,69 +146,67 @@ function MESSAGE:NewType( MessageText, MessageType, ClearScreen )
self.MessageType = MessageType
self.ClearScreen=false
if ClearScreen~=nil then
self.ClearScreen=ClearScreen
self.ClearScreen = false
if ClearScreen ~= nil then
self.ClearScreen = ClearScreen
end
self.MessageTime = timer.getTime()
self.MessageText = MessageText:gsub("^\n","",1):gsub("\n$","",1)
self.MessageText = MessageText:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
return self
end
--- Clears all previous messages from the screen before the new message is displayed. Not that this must come before all functions starting with ToX(), e.g. ToAll(), ToGroup() etc.
-- @param #MESSAGE self
-- @return #MESSAGE
function MESSAGE:Clear()
self:F()
self.ClearScreen=true
self.ClearScreen = true
return self
end
--- Sends a MESSAGE to a Client Group. Note that the Group needs to be defined within the ME with the skillset "Client" or "Player".
-- @param #MESSAGE self
-- @param Wrapper.Client#CLIENT Client is the Group of the Client.
-- @param Core.Settings#SETTINGS Settings Settings used to display the message.
-- @return #MESSAGE
-- @usage
-- -- Send the 2 messages created with the @{New} method to the Client Group.
-- -- Note that the Message of MessageClient2 is overwriting the Message of MessageClient1.
-- ClientGroup = Group.getByName( "ClientGroup" )
--
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- or
-- MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- or
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" )
-- MessageClient1:ToClient( ClientGroup )
-- MessageClient2:ToClient( ClientGroup )
-- -- Send the 2 messages created with the @{New} method to the Client Group.
-- -- Note that the Message of MessageClient2 is overwriting the Message of MessageClient1.
-- ClientGroup = Group.getByName( "ClientGroup" )
--
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- or
-- MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" ):ToClient( ClientGroup )
-- or
-- MessageClient1 = MESSAGE:New( "Congratulations, you've just hit a target", "Score", 25, "Score" )
-- MessageClient2 = MESSAGE:New( "Congratulations, you've just killed a target", "Score", 25, "Score" )
-- MessageClient1:ToClient( ClientGroup )
-- MessageClient2:ToClient( ClientGroup )
--
function MESSAGE:ToClient( Client, Settings )
self:F( Client )
self:F( Client )
if Client and Client:GetClientGroupID() then
if Client and Client:GetClientGroupID() then
if self.MessageType then
local Settings = Settings or ( Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
local Settings = Settings or (Client and _DATABASE:GetPlayerSettings( Client:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = "" -- self.MessageType .. ": "
end
if self.MessageDuration ~= 0 then
local ClientGroupID = Client:GetClientGroupID()
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
trigger.action.outTextForGroup( ClientGroupID, self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration , self.ClearScreen)
end
end
local ClientGroupID = Client:GetClientGroupID()
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
trigger.action.outTextForGroup( ClientGroupID, self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
end
end
return self
return self
end
--- Sends a MESSAGE to a Group.
@ -220,14 +219,14 @@ function MESSAGE:ToGroup( Group, Settings )
if Group then
if self.MessageType then
local Settings = Settings or ( Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() ) ) or _SETTINGS -- Core.Settings#SETTINGS
local Settings = Settings or (Group and _DATABASE:GetPlayerSettings( Group:GetPlayerName() )) or _SETTINGS -- Core.Settings#SETTINGS
self.MessageDuration = Settings:GetMessageTime( self.MessageType )
self.MessageCategory = "" -- self.MessageType .. ": "
end
if self.MessageDuration ~= 0 then
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
trigger.action.outTextForGroup( Group:GetID(), self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
trigger.action.outTextForGroup( Group:GetID(), self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
end
end
@ -237,38 +236,42 @@ end
-- @param #MESSAGE self
-- @return #MESSAGE
-- @usage
-- -- Send a message created with the @{New} method to the BLUE coalition.
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
-- or
-- MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
-- or
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageBLUE:ToBlue()
--
-- -- Send a message created with the @{New} method to the BLUE coalition.
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
-- or
-- MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToBlue()
-- or
-- MessageBLUE = MESSAGE:New( "To the BLUE Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageBLUE:ToBlue()
--
function MESSAGE:ToBlue()
self:F()
self:F()
self:ToCoalition( coalition.side.BLUE )
self:ToCoalition( coalition.side.BLUE )
return self
return self
end
--- Sends a MESSAGE to the Red Coalition.
-- @param #MESSAGE self
-- @return #MESSAGE
-- @usage
-- -- Send a message created with the @{New} method to the RED coalition.
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
-- or
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
-- or
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageRED:ToRed()
function MESSAGE:ToRed( )
self:F()
--
-- -- Send a message created with the @{New} method to the RED coalition.
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
-- or
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToRed()
-- or
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageRED:ToRed()
--
function MESSAGE:ToRed()
self:F()
self:ToCoalition( coalition.side.RED )
self:ToCoalition( coalition.side.RED )
return self
return self
end
--- Sends a MESSAGE to a Coalition.
@ -277,15 +280,17 @@ end
-- @param Core.Settings#SETTINGS Settings (Optional) Settings for message display.
-- @return #MESSAGE Message object.
-- @usage
-- -- Send a message created with the @{New} method to the RED coalition.
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
-- or
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
-- or
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageRED:ToCoalition( coalition.side.RED )
--
-- -- Send a message created with the @{New} method to the RED coalition.
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
-- or
-- MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" ):ToCoalition( coalition.side.RED )
-- or
-- MessageRED = MESSAGE:New( "To the RED Players: You receive a penalty because you've killed one of your own units", "Penalty", 25, "Score" )
-- MessageRED:ToCoalition( coalition.side.RED )
--
function MESSAGE:ToCoalition( CoalitionSide, Settings )
self:F( CoalitionSide )
self:F( CoalitionSide )
if self.MessageType then
local Settings = Settings or _SETTINGS -- Core.Settings#SETTINGS
@ -293,14 +298,14 @@ function MESSAGE:ToCoalition( CoalitionSide, Settings )
self.MessageCategory = "" -- self.MessageType .. ": "
end
if CoalitionSide then
if CoalitionSide then
if self.MessageDuration ~= 0 then
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
trigger.action.outTextForCoalition( CoalitionSide, self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
trigger.action.outTextForCoalition( CoalitionSide, self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
end
end
end
return self
return self
end
--- Sends a MESSAGE to a Coalition if the given Condition is true.
@ -323,14 +328,16 @@ end
-- @param Core.Settings#Settings Settings (Optional) Settings for message display.
-- @return #MESSAGE
-- @usage
-- -- Send a message created to all players.
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
-- or
-- MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
-- or
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
-- MessageAll:ToAll()
function MESSAGE:ToAll(Settings)
--
-- -- Send a message created to all players.
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
-- or
-- MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" ):ToAll()
-- or
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
-- MessageAll:ToAll()
--
function MESSAGE:ToAll( Settings )
self:F()
if self.MessageType then
@ -340,14 +347,13 @@ function MESSAGE:ToAll(Settings)
end
if self.MessageDuration ~= 0 then
self:T( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$","") .. " / " .. self.MessageDuration )
trigger.action.outText( self.MessageCategory .. self.MessageText:gsub("\n$",""):gsub("\n$",""), self.MessageDuration, self.ClearScreen )
self:T( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ) .. " / " .. self.MessageDuration )
trigger.action.outText( self.MessageCategory .. self.MessageText:gsub( "\n$", "" ):gsub( "\n$", "" ), self.MessageDuration, self.ClearScreen )
end
return self
end
--- Sends a MESSAGE to all players if the given Condition is true.
-- @param #MESSAGE self
-- @return #MESSAGE
@ -357,5 +363,5 @@ function MESSAGE:ToAllIf( Condition )
self:ToAll()
end
return self
return self
end

View File

@ -15,7 +15,6 @@
-- @module Core.Report
-- @image Core_Report.JPG
--- @type REPORT
-- @extends Core.Base#BASE
@ -45,28 +44,26 @@ end
--- Has the REPORT Text?
-- @param #REPORT self
-- @return #boolean
function REPORT:HasText() --R2.1
function REPORT:HasText() -- R2.1
return #self.Report > 0
end
--- Set indent of a REPORT.
-- @param #REPORT self
-- @param #number Indent
-- @return #REPORT
function REPORT:SetIndent( Indent ) --R2.1
function REPORT:SetIndent( Indent ) -- R2.1
self.Indent = Indent
return self
end
--- Add a new line to a REPORT.
-- @param #REPORT self
-- @param #string Text
-- @return #REPORT
function REPORT:Add( Text )
self.Report[#self.Report+1] = Text
self.Report[#self.Report + 1] = Text
return self
end
@ -76,17 +73,17 @@ end
-- @param #string Separator (optional) The start of each report line can begin with an optional separator character. This can be a "-", or "#", or "*". You're free to choose what you find the best.
-- @return #REPORT
function REPORT:AddIndent( Text, Separator )
self.Report[#self.Report+1] = ( ( Separator and Separator .. string.rep( " ", self.Indent - 1 ) ) or string.rep(" ", self.Indent ) ) .. Text:gsub("\n","\n"..string.rep( " ", self.Indent ) )
self.Report[#self.Report + 1] = ((Separator and Separator .. string.rep( " ", self.Indent - 1 )) or string.rep( " ", self.Indent )) .. Text:gsub( "\n", "\n" .. string.rep( " ", self.Indent ) )
return self
end
--- Produces the text of the report, taking into account an optional delimeter, which is \n by default.
--- Produces the text of the report, taking into account an optional delimiter, which is \n by default.
-- @param #REPORT self
-- @param #string Delimiter (optional) A delimiter text.
-- @return #string The report text.
function REPORT:Text( Delimiter )
Delimiter = Delimiter or "\n"
local ReportText = ( self.Title ~= "" and self.Title .. Delimiter or self.Title ) .. table.concat( self.Report, Delimiter ) or ""
local ReportText = (self.Title ~= "" and self.Title .. Delimiter or self.Title) .. table.concat( self.Report, Delimiter ) or ""
return ReportText
end

View File

@ -17,7 +17,7 @@
-- - When a SCHEDULER object is not attached to another object (that is, it's first :Schedule() parameter is nil), then the SCHEDULER object is _persistent_ within memory.
-- - When a SCHEDULER object *is* attached to another object, then the SCHEDULER object is _not persistent_ within memory after a garbage collection!
--
-- The none persistency of SCHEDULERS attached to objects is required to allow SCHEDULER objects to be garbage collectged, when the parent object is also desroyed or nillified and garbage collected.
-- The non-persistency of SCHEDULERS attached to objects is required to allow SCHEDULER objects to be garbage collected when the parent object is destroyed, or set to nil and garbage collected.
-- Even when there are pending timer scheduled functions to be executed for the SCHEDULER object,
-- these will not be executed anymore when the SCHEDULER object has been destroyed.
--
@ -38,7 +38,7 @@
-- @type SCHEDULEDISPATCHER
-- @field #string ClassName Name of the class.
-- @field #number CallID Call ID counter.
-- @field #table PersistentSchedulers Persistant schedulers.
-- @field #table PersistentSchedulers Persistent schedulers.
-- @field #table ObjectSchedulers Schedulers that only exist as long as the master object exists.
-- @field #table Schedule Meta table setmetatable( {}, { __mode = "k" } ).
-- @extends Core.Base#BASE
@ -46,11 +46,11 @@
--- The SCHEDULEDISPATCHER structure
-- @type SCHEDULEDISPATCHER
SCHEDULEDISPATCHER = {
ClassName = "SCHEDULEDISPATCHER",
CallID = 0,
PersistentSchedulers = {},
ObjectSchedulers = {},
Schedule = nil,
ClassName = "SCHEDULEDISPATCHER",
CallID = 0,
PersistentSchedulers = {},
ObjectSchedulers = {},
Schedule = nil,
}
--- Player data table holding all important parameters of each player.
@ -58,7 +58,7 @@ SCHEDULEDISPATCHER = {
-- @field #function Function The schedule function to be called.
-- @field #table Arguments Schedule function arguments.
-- @field #number Start Start time in seconds.
-- @field #number Repeat Repeat time intervall in seconds.
-- @field #number Repeat Repeat time interval in seconds.
-- @field #number Randomize Randomization factor [0,1].
-- @field #number Stop Stop time in seconds.
-- @field #number StartTime Time in seconds when the scheduler is created.
@ -77,7 +77,7 @@ end
--- Add a Schedule to the ScheduleDispatcher.
-- The development of this method was really tidy.
-- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is nillified.
-- It is constructed as such that a garbage collection is executed on the weak tables, when the Scheduler is set to nil.
-- Nothing of this code should be modified without testing it thoroughly.
-- @param #SCHEDULEDISPATCHER self
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
@ -85,7 +85,7 @@ end
-- @param #table ScheduleArguments Table of arguments passed to the ScheduleFunction.
-- @param #number Start Start time in seconds.
-- @param #number Repeat Repeat interval in seconds.
-- @param #number Randomize Radomization factor [0,1].
-- @param #number Randomize Randomization factor [0,1].
-- @param #number Stop Stop time in seconds.
-- @param #number TraceLevel Trace level [0,3].
-- @param Core.Fsm#FSM Fsm Finite state model.
@ -97,9 +97,9 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
self.CallID = self.CallID + 1
-- Create ID.
local CallID = self.CallID .. "#" .. ( Scheduler.MasterObject and Scheduler.MasterObject.GetClassNameAndID and Scheduler.MasterObject:GetClassNameAndID() or "" ) or ""
local CallID = self.CallID .. "#" .. (Scheduler.MasterObject and Scheduler.MasterObject.GetClassNameAndID and Scheduler.MasterObject:GetClassNameAndID() or "") or ""
self:T2(string.format("Adding schedule #%d CallID=%s", self.CallID, CallID))
self:T2( string.format( "Adding schedule #%d CallID=%s", self.CallID, CallID ) )
-- Initialize PersistentSchedulers
self.PersistentSchedulers = self.PersistentSchedulers or {}
@ -110,7 +110,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
if Scheduler.MasterObject then
self.ObjectSchedulers[CallID] = Scheduler
self:F3( { CallID = CallID, ObjectScheduler = tostring(self.ObjectSchedulers[CallID]), MasterObject = tostring(Scheduler.MasterObject) } )
self:F3( { CallID = CallID, ObjectScheduler = tostring( self.ObjectSchedulers[CallID] ), MasterObject = tostring( Scheduler.MasterObject ) } )
else
self.PersistentSchedulers[CallID] = Scheduler
self:F3( { CallID = CallID, PersistentScheduler = self.PersistentSchedulers[CallID] } )
@ -118,16 +118,15 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
self.Schedule = self.Schedule or setmetatable( {}, { __mode = "k" } )
self.Schedule[Scheduler] = self.Schedule[Scheduler] or {}
self.Schedule[Scheduler][CallID] = {} --#SCHEDULEDISPATCHER.ScheduleData
self.Schedule[Scheduler][CallID] = {} -- #SCHEDULEDISPATCHER.ScheduleData
self.Schedule[Scheduler][CallID].Function = ScheduleFunction
self.Schedule[Scheduler][CallID].Arguments = ScheduleArguments
self.Schedule[Scheduler][CallID].StartTime = timer.getTime() + ( Start or 0 )
self.Schedule[Scheduler][CallID].StartTime = timer.getTime() + (Start or 0)
self.Schedule[Scheduler][CallID].Start = Start + 0.1
self.Schedule[Scheduler][CallID].Repeat = Repeat or 0
self.Schedule[Scheduler][CallID].Randomize = Randomize or 0
self.Schedule[Scheduler][CallID].Stop = Stop
-- This section handles the tracing of the scheduled calls.
-- Because these calls will be executed with a delay, we inspect the place where these scheduled calls are initiated.
-- The Info structure contains the output of the debug.getinfo() calls, which inspects the call stack for the function name, line number and source name.
@ -149,7 +148,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- Therefore, in the call stack, at the TraceLevel these functions are mentioned as "tail calls", and the Info.name field will be nil as a result.
-- To obtain the correct function name for FSM object calls, the function is mentioned in the call stack at a higher stack level.
-- So when function name stored in Info.name is nil, then I inspect the function name within the call stack one level higher.
-- So this little piece of code does its magic wonderfully, preformance overhead is neglectible, as scheduled calls don't happen that often.
-- So this little piece of code does its magic wonderfully, performance overhead is negligible, as scheduled calls don't happen that often.
local Info = {}
@ -181,24 +180,24 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
return errmsg
end
-- Get object or persistant scheduler object.
local Scheduler = self.ObjectSchedulers[CallID] --Core.Scheduler#SCHEDULER
-- Get object or persistent scheduler object.
local Scheduler = self.ObjectSchedulers[CallID] -- Core.Scheduler#SCHEDULER
if not Scheduler then
Scheduler = self.PersistentSchedulers[CallID]
end
--self:T3( { Scheduler = Scheduler } )
-- self:T3( { Scheduler = Scheduler } )
if Scheduler then
local MasterObject = tostring(Scheduler.MasterObject)
local MasterObject = tostring( Scheduler.MasterObject )
-- Schedule object.
local Schedule = self.Schedule[Scheduler][CallID] --#SCHEDULEDISPATCHER.ScheduleData
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
--self:T3( { Schedule = Schedule } )
-- self:T3( { Schedule = Schedule } )
local SchedulerObject = Scheduler.MasterObject --Scheduler.SchedulerObject Now is this the Maste or Scheduler object?
local SchedulerObject = Scheduler.MasterObject -- Scheduler.SchedulerObject Now is this the Master or Scheduler object?
local ShowTrace = Scheduler.ShowTrace
local ScheduleFunction = Schedule.Function
@ -209,11 +208,10 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
local Stop = Schedule.Stop or 0
local ScheduleID = Schedule.ScheduleID
local Prefix = ( Repeat == 0 ) and "--->" or "+++>"
local Prefix = (Repeat == 0) and "--->" or "+++>"
local Status, Result
--self:E( { SchedulerObject = SchedulerObject } )
-- self:E( { SchedulerObject = SchedulerObject } )
if SchedulerObject then
local function Timer()
if ShowTrace then
@ -236,14 +234,13 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
local StartTime = Schedule.StartTime
-- Debug info.
self:F3( { CallID=CallID, ScheduleID=ScheduleID, Master = MasterObject, CurrentTime = CurrentTime, StartTime = StartTime, Start = Start, Repeat = Repeat, Randomize = Randomize, Stop = Stop } )
self:F3( { CallID = CallID, ScheduleID = ScheduleID, Master = MasterObject, CurrentTime = CurrentTime, StartTime = StartTime, Start = Start, Repeat = Repeat, Randomize = Randomize, Stop = Stop } )
if Status and ((Result == nil) or (Result and Result ~= false)) then
if Status and (( Result == nil ) or ( Result and Result ~= false ) ) then
if Repeat ~= 0 and ( ( Stop == 0 ) or ( Stop ~= 0 and CurrentTime <= StartTime + Stop ) ) then
local ScheduleTime = CurrentTime + Repeat + math.random(- ( Randomize * Repeat / 2 ), ( Randomize * Repeat / 2 )) + 0.0001 -- Accuracy
--self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
if Repeat ~= 0 and ((Stop == 0) or (Stop ~= 0 and CurrentTime <= StartTime + Stop)) then
local ScheduleTime = CurrentTime + Repeat + math.random( -(Randomize * Repeat / 2), (Randomize * Repeat / 2) ) + 0.0001 -- Accuracy
-- self:T3( { Repeat = CallID, CurrentTime, ScheduleTime, ScheduleArguments } )
return ScheduleTime -- returns the next time the function needs to be called.
else
self:Stop( Scheduler, CallID )
@ -287,21 +284,21 @@ function SCHEDULEDISPATCHER:Start( Scheduler, CallID, Info )
if CallID then
local Schedule = self.Schedule[Scheduler][CallID] --#SCHEDULEDISPATCHER.ScheduleData
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
-- Only start when there is no ScheduleID defined!
-- This prevents to "Start" the scheduler twice with the same CallID...
if not Schedule.ScheduleID then
-- Current time in seconds.
local Tnow=timer.getTime()
local Tnow = timer.getTime()
Schedule.StartTime = Tnow -- Set the StartTime field to indicate when the scheduler started.
Schedule.StartTime = Tnow -- Set the StartTime field to indicate when the scheduler started.
-- Start DCS schedule function https://wiki.hoggitworld.com/view/DCS_func_scheduleFunction
Schedule.ScheduleID = timer.scheduleFunction(Schedule.CallHandler, { CallID = CallID, Info = Info }, Tnow + Schedule.Start)
Schedule.ScheduleID = timer.scheduleFunction( Schedule.CallHandler, { CallID = CallID, Info = Info }, Tnow + Schedule.Start )
self:T(string.format("Starting scheduledispatcher Call ID=%s ==> Schedule ID=%s", tostring(CallID), tostring(Schedule.ScheduleID)))
self:T( string.format( "Starting SCHEDULEDISPATCHER Call ID=%s ==> Schedule ID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
end
else
@ -323,20 +320,20 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
if CallID then
local Schedule = self.Schedule[Scheduler][CallID] --#SCHEDULEDISPATCHER.ScheduleData
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
-- Only stop when there is a ScheduleID defined for the CallID. So, when the scheduler was stopped before, do nothing.
if Schedule.ScheduleID then
self:T(string.format("scheduledispatcher stopping scheduler CallID=%s, ScheduleID=%s", tostring(CallID), tostring(Schedule.ScheduleID)))
self:T( string.format( "SCHEDULEDISPATCHER stopping scheduler CallID=%s, ScheduleID=%s", tostring( CallID ), tostring( Schedule.ScheduleID ) ) )
-- Remove schedule function https://wiki.hoggitworld.com/view/DCS_func_removeFunction
timer.removeFunction(Schedule.ScheduleID)
timer.removeFunction( Schedule.ScheduleID )
Schedule.ScheduleID = nil
else
self:T(string.format("Error no ScheduleID for CallID=%s", tostring(CallID)))
self:T( string.format( "Error no ScheduleID for CallID=%s", tostring( CallID ) ) )
end
else
@ -359,7 +356,7 @@ function SCHEDULEDISPATCHER:Clear( Scheduler )
end
end
--- Shopw tracing info.
--- Show tracing info.
-- @param #SCHEDULEDISPATCHER self
-- @param Core.Scheduler#SCHEDULER Scheduler Scheduler object.
function SCHEDULEDISPATCHER:ShowTrace( Scheduler )

View File

@ -48,7 +48,6 @@
-- @field #boolean ShowTrace Trace info if true.
-- @extends Core.Base#BASE
--- Creates and handles schedules over time, which allow to execute code at specific time intervals with randomization.
--
-- A SCHEDULER can manage **multiple** (repeating) schedules. Each planned or executing schedule has a unique **ScheduleID**.
@ -79,7 +78,7 @@
--
-- ### Construct a SCHEDULER object without a volatile schedule, but volatile to the Object existence...
--
-- * @{#SCHEDULER.New}( Object ): Setup a new SCHEDULER object, which is linked to the Object. When the Object is nillified or destroyed, the SCHEDULER object will also be destroyed and stopped after garbage collection.
-- * @{#SCHEDULER.New}( Object ): Setup a new SCHEDULER object, which is linked to the Object. When the Object is set to nil or destroyed, the SCHEDULER object will also be destroyed and stopped after garbage collection.
--
-- ZoneObject = ZONE:New( "ZoneName" )
-- MasterObject = SCHEDULER:New( ZoneObject )
@ -149,13 +148,13 @@
-- ZoneObject = ZONE:New( "ZoneName" )
-- MasterObject = SCHEDULER:New( ZoneObject )
--
-- Several parameters can be specified that influence the behaviour of a Schedule.
-- Several parameters can be specified that influence the behavior of a Schedule.
--
-- ### A single schedule, immediately executed
--
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {} )
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within milleseconds ...
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within milliseconds ...
--
-- ### A single schedule, planned over time
--
@ -193,10 +192,10 @@
--
-- @field #SCHEDULER
SCHEDULER = {
ClassName = "SCHEDULER",
Schedules = {},
MasterObject = nil,
ShowTrace = nil,
ClassName = "SCHEDULER",
Schedules = {},
MasterObject = nil,
ShowTrace = nil,
}
--- SCHEDULER constructor.
@ -235,7 +234,7 @@ end
-- @param #number Start Specifies the amount of seconds that will be waited before the scheduling is started, and the event function is called.
-- @param #number Repeat Specifies the time interval in seconds when the scheduler will call the event function.
-- @param #number RandomizeFactor Specifies a randomization factor between 0 and 1 to randomize the Repeat.
-- @param #number Stop Time interval in seconds after which the scheduler will be stoppe.
-- @param #number Stop Time interval in seconds after which the scheduler will be stopped.
-- @param #number TraceLevel Trace level [0,3]. Default 3.
-- @param Core.Fsm#FSM Fsm Finite state model.
-- @return #table The ScheduleID of the planned schedule.
@ -248,25 +247,24 @@ function SCHEDULER:Schedule( MasterObject, SchedulerFunction, SchedulerArguments
if MasterObject and MasterObject.ClassName and MasterObject.ClassID then
ObjectName = MasterObject.ClassName .. MasterObject.ClassID
end
self:F3( { "Schedule :", ObjectName, tostring( MasterObject ), Start, Repeat, RandomizeFactor, Stop } )
self:F3( { "Schedule :", ObjectName, tostring( MasterObject ), Start, Repeat, RandomizeFactor, Stop } )
-- Set master object.
self.MasterObject = MasterObject
-- Add schedule.
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule(
self,
SchedulerFunction,
SchedulerArguments,
Start,
Repeat,
RandomizeFactor,
Stop,
TraceLevel or 3,
Fsm
)
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule( self,
SchedulerFunction,
SchedulerArguments,
Start,
Repeat,
RandomizeFactor,
Stop,
TraceLevel or 3,
Fsm
)
self.Schedules[#self.Schedules+1] = ScheduleID
self.Schedules[#self.Schedules + 1] = ScheduleID
return ScheduleID
end
@ -276,7 +274,7 @@ end
-- @param #string ScheduleID (Optional) The ScheduleID of the planned (repeating) schedule.
function SCHEDULER:Start( ScheduleID )
self:F3( { ScheduleID } )
self:T(string.format("Starting scheduler ID=%s", tostring(ScheduleID)))
self:T( string.format( "Starting scheduler ID=%s", tostring( ScheduleID ) ) )
_SCHEDULEDISPATCHER:Start( self, ScheduleID )
end
@ -285,7 +283,7 @@ end
-- @param #string ScheduleID (Optional) The ScheduleID of the planned (repeating) schedule.
function SCHEDULER:Stop( ScheduleID )
self:F3( { ScheduleID } )
self:T(string.format("Stopping scheduler ID=%s", tostring(ScheduleID)))
self:T( string.format( "Stopping scheduler ID=%s", tostring( ScheduleID ) ) )
_SCHEDULEDISPATCHER:Stop( self, ScheduleID )
end
@ -294,15 +292,15 @@ end
-- @param #string ScheduleID (optional) The ScheduleID of the planned (repeating) schedule.
function SCHEDULER:Remove( ScheduleID )
self:F3( { ScheduleID } )
self:T(string.format("Removing scheduler ID=%s", tostring(ScheduleID)))
self:T( string.format( "Removing scheduler ID=%s", tostring( ScheduleID ) ) )
_SCHEDULEDISPATCHER:RemoveSchedule( self, ScheduleID )
end
--- Clears all pending schedules.
-- @param #SCHEDULER self
function SCHEDULER:Clear()
self:F3( )
self:T(string.format("Clearing scheduler"))
self:F3()
self:T( string.format( "Clearing scheduler" ) )
_SCHEDULEDISPATCHER:Clear( self )
end

View File

@ -29,15 +29,14 @@
-- @module Core.Settings
-- @image Core_Settings.JPG
--- @type SETTINGS
-- @extends Core.Base#BASE
--- Takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework.
--- Takes care of various settings that influence the behavior of certain functionalities and classes within the MOOSE framework.
--
-- ===
--
-- The SETTINGS class takes care of various settings that influence the behaviour of certain functionalities and classes within the MOOSE framework.
-- The SETTINGS class takes care of various settings that influence the behavior of certain functionalities and classes within the MOOSE framework.
-- SETTINGS can work on 2 levels:
--
-- - **Default settings**: A running mission has **Default settings**.
@ -59,7 +58,7 @@
--
-- A menu is created automatically per Command Center that allows to modify the **Default** settings.
-- So, when joining a CC unit, a menu will be available that allows to change the settings parameters **FOR ALL THE PLAYERS**!
-- Note that the **Default settings** will only be used when a player has not choosen its own settings.
-- Note that the **Default settings** will only be used when a player has not chosen its own settings.
--
-- ## 2.2) Player settings menu
--
@ -69,7 +68,7 @@
--
-- ## 2.3) Show or Hide the Player Setting menus
--
-- Of course, it may be requried not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**.
-- Of course, it may be required not to show any setting menus. In this case, a method is available on the **\_SETTINGS object**.
-- Use @{#SETTINGS.SetPlayerMenuOff}() to hide the player menus, and use @{#SETTINGS.SetPlayerMenuOn}() show the player menus.
-- Note that when this method is used, any player already in a slot will not have its menus visibility changed.
-- The option will only have effect when a player enters a new slot or changes a slot.
@ -94,8 +93,8 @@
--
-- - A2G BR: [Bearing Range](https://en.wikipedia.org/wiki/Bearing_(navigation)).
-- - A2G MGRS: The [Military Grid Reference System](https://en.wikipedia.org/wiki/Military_Grid_Reference_System). The accuracy can also be adapted.
-- - A2G LL DMS: Lattitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
-- - A2G LL DDM: Lattitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
-- - A2G LL DMS: Latitude Longitude [Degrees Minutes Seconds](https://en.wikipedia.org/wiki/Geographic_coordinate_conversion). The accuracy can also be adapted.
-- - A2G LL DDM: Latitude Longitude [Decimal Degrees Minutes](https://en.wikipedia.org/wiki/Decimal_degrees). The accuracy can also be adapted.
--
-- ### 3.1.2) A2G coordinates setting **menu**
--
@ -183,7 +182,7 @@
-- The settings can be changed by using the **Default settings menu** on the Command Center or the **Player settings menu** on the Player Slot.
--
-- Each Message Type has specific timings that will be applied when the message is displayed.
-- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be choosen.
-- The Settings Menu will provide for each Message Type a selection of proposed durations from which can be chosen.
-- So the player can choose its own amount of seconds how long a message should be displayed of a certain type.
-- Note that **Update** messages can be chosen not to be displayed at all!
--
@ -196,7 +195,7 @@
--
-- ## 3.5) **Era** of the battle
--
-- The threat level metric is scaled according the era of the battle. A target that is AAA, will pose a much greather threat in WWII than on modern warfare.
-- The threat level metric is scaled according the era of the battle. A target that is AAA, will pose a much greater threat in WWII than on modern warfare.
-- Therefore, there are 4 era that are defined within the settings:
--
-- - **WWII** era: Use for warfare with equipment during the world war II time.
@ -213,8 +212,8 @@
SETTINGS = {
ClassName = "SETTINGS",
ShowPlayerMenu = true,
MenuShort = false,
MenuStatic = false,
MenuShort = false,
MenuStatic = false,
}
SETTINGS.__Enum = {}
@ -231,7 +230,6 @@ SETTINGS.__Enum.Era = {
Modern = 4,
}
do -- SETTINGS
--- SETTINGS constructor.
@ -268,14 +266,14 @@ do -- SETTINGS
-- Short text are better suited for, e.g., VR.
-- @param #SETTINGS self
-- @param #boolean onoff If *true* use short menu texts. If *false* long ones (default).
function SETTINGS:SetMenutextShort(onoff)
function SETTINGS:SetMenutextShort( onoff )
_SETTINGS.MenuShort = onoff
end
--- Set menu to be static.
-- @param #SETTINGS self
-- @param #boolean onoff If *true* menu is static. If *false* menu will be updated after changes (default).
function SETTINGS:SetMenuStatic(onoff)
function SETTINGS:SetMenuStatic( onoff )
_SETTINGS.MenuStatic = onoff
end
@ -289,7 +287,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if metric.
function SETTINGS:IsMetric()
return ( self.Metric ~= nil and self.Metric == true ) or ( self.Metric == nil and _SETTINGS:IsMetric() )
return (self.Metric ~= nil and self.Metric == true) or (self.Metric == nil and _SETTINGS:IsMetric())
end
--- Sets the SETTINGS imperial.
@ -302,7 +300,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if imperial.
function SETTINGS:IsImperial()
return ( self.Metric ~= nil and self.Metric == false ) or ( self.Metric == nil and _SETTINGS:IsMetric() )
return (self.Metric ~= nil and self.Metric == false) or (self.Metric == nil and _SETTINGS:IsMetric())
end
--- Sets the SETTINGS LL accuracy.
@ -344,13 +342,12 @@ do -- SETTINGS
self.MessageTypeTimings[MessageType] = MessageTime
end
--- Gets the SETTINGS Message Display Timing of a MessageType
-- @param #SETTINGS self
-- @param Core.Message#MESSAGE MessageType The type of the message.
-- @return #number
function SETTINGS:GetMessageTime( MessageType )
return ( self.MessageTypeTimings and self.MessageTypeTimings[MessageType] ) or _SETTINGS:GetMessageTime( MessageType )
return (self.MessageTypeTimings and self.MessageTypeTimings[MessageType]) or _SETTINGS:GetMessageTime( MessageType )
end
--- Sets A2G LL DMS
@ -371,14 +368,14 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if LL DMS
function SETTINGS:IsA2G_LL_DMS()
return ( self.A2GSystem and self.A2GSystem == "LL DMS" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_LL_DMS() )
return (self.A2GSystem and self.A2GSystem == "LL DMS") or (not self.A2GSystem and _SETTINGS:IsA2G_LL_DMS())
end
--- Is LL DDM
-- @param #SETTINGS self
-- @return #boolean true if LL DDM
function SETTINGS:IsA2G_LL_DDM()
return ( self.A2GSystem and self.A2GSystem == "LL DDM" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_LL_DDM() )
return (self.A2GSystem and self.A2GSystem == "LL DDM") or (not self.A2GSystem and _SETTINGS:IsA2G_LL_DDM())
end
--- Sets A2G MGRS
@ -392,7 +389,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if MGRS
function SETTINGS:IsA2G_MGRS()
return ( self.A2GSystem and self.A2GSystem == "MGRS" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_MGRS() )
return (self.A2GSystem and self.A2GSystem == "MGRS") or (not self.A2GSystem and _SETTINGS:IsA2G_MGRS())
end
--- Sets A2G BRA
@ -406,7 +403,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if BRA
function SETTINGS:IsA2G_BR()
return ( self.A2GSystem and self.A2GSystem == "BR" ) or ( not self.A2GSystem and _SETTINGS:IsA2G_BR() )
return (self.A2GSystem and self.A2GSystem == "BR") or (not self.A2GSystem and _SETTINGS:IsA2G_BR())
end
--- Sets A2A BRA
@ -420,7 +417,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if BRA
function SETTINGS:IsA2A_BRAA()
return ( self.A2ASystem and self.A2ASystem == "BRAA" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BRAA() )
return (self.A2ASystem and self.A2ASystem == "BRAA") or (not self.A2ASystem and _SETTINGS:IsA2A_BRAA())
end
--- Sets A2A BULLS
@ -434,7 +431,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if BULLS
function SETTINGS:IsA2A_BULLS()
return ( self.A2ASystem and self.A2ASystem == "BULLS" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_BULLS() )
return (self.A2ASystem and self.A2ASystem == "BULLS") or (not self.A2ASystem and _SETTINGS:IsA2A_BULLS())
end
--- Sets A2A LL DMS
@ -455,14 +452,14 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if LL DMS
function SETTINGS:IsA2A_LL_DMS()
return ( self.A2ASystem and self.A2ASystem == "LL DMS" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_LL_DMS() )
return (self.A2ASystem and self.A2ASystem == "LL DMS") or (not self.A2ASystem and _SETTINGS:IsA2A_LL_DMS())
end
--- Is LL DDM
-- @param #SETTINGS self
-- @return #boolean true if LL DDM
function SETTINGS:IsA2A_LL_DDM()
return ( self.A2ASystem and self.A2ASystem == "LL DDM" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_LL_DDM() )
return (self.A2ASystem and self.A2ASystem == "LL DDM") or (not self.A2ASystem and _SETTINGS:IsA2A_LL_DDM())
end
--- Sets A2A MGRS
@ -476,7 +473,7 @@ do -- SETTINGS
-- @param #SETTINGS self
-- @return #boolean true if MGRS
function SETTINGS:IsA2A_MGRS()
return ( self.A2ASystem and self.A2ASystem == "MGRS" ) or ( not self.A2ASystem and _SETTINGS:IsA2A_MGRS() )
return (self.A2ASystem and self.A2ASystem == "MGRS") or (not self.A2ASystem and _SETTINGS:IsA2A_MGRS())
end
--- @param #SETTINGS self
@ -495,37 +492,37 @@ do -- SETTINGS
-- A2G Coordinate System
-------
local text="A2G Coordinate System"
local text = "A2G Coordinate System"
if _SETTINGS.MenuShort then
text="A2G Coordinates"
text = "A2G Coordinates"
end
local A2GCoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
-- Set LL DMS
if not self:IsA2G_LL_DMS() then
local text="Lat/Lon Degree Min Sec (LL DMS)"
local text = "Lat/Lon Degree Min Sec (LL DMS)"
if _SETTINGS.MenuShort then
text="LL DMS"
text = "LL DMS"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime )
end
-- Set LL DDM
if not self:IsA2G_LL_DDM() then
local text="Lat/Lon Degree Dec Min (LL DDM)"
local text = "Lat/Lon Degree Dec Min (LL DDM)"
if _SETTINGS.MenuShort then
text="LL DDM"
text = "LL DDM"
end
MENU_GROUP_COMMAND:New( MenuGroup, "Lat/Lon Degree Dec Min (LL DDM)", A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime )
end
-- Set LL DMS accuracy.
if self:IsA2G_LL_DDM() then
local text1="LL DDM Accuracy 1"
local text2="LL DDM Accuracy 2"
local text3="LL DDM Accuracy 3"
local text1 = "LL DDM Accuracy 1"
local text2 = "LL DDM Accuracy 2"
local text3 = "LL DDM Accuracy 3"
if _SETTINGS.MenuShort then
text1="LL DDM"
text1 = "LL DDM"
end
MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 1", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 1 ):SetTime( MenuTime )
MENU_GROUP_COMMAND:New( MenuGroup, "LL DDM Accuracy 2", A2GCoordinateMenu, self.MenuLL_DDM_Accuracy, self, MenuGroup, RootMenu, 2 ):SetTime( MenuTime )
@ -534,18 +531,18 @@ do -- SETTINGS
-- Set BR.
if not self:IsA2G_BR() then
local text="Bearing, Range (BR)"
local text = "Bearing, Range (BR)"
if _SETTINGS.MenuShort then
text="BR"
text = "BR"
end
MENU_GROUP_COMMAND:New( MenuGroup, text , A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime )
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "BR" ):SetTime( MenuTime )
end
-- Set MGRS.
if not self:IsA2G_MGRS() then
local text="Military Grid (MGRS)"
local text = "Military Grid (MGRS)"
if _SETTINGS.MenuShort then
text="MGRS"
text = "MGRS"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, A2GCoordinateMenu, self.A2GMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
end
@ -563,24 +560,24 @@ do -- SETTINGS
-- A2A Coordinate System
-------
local text="A2A Coordinate System"
local text = "A2A Coordinate System"
if _SETTINGS.MenuShort then
text="A2A Coordinates"
text = "A2A Coordinates"
end
local A2ACoordinateMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
if not self:IsA2A_LL_DMS() then
local text="Lat/Lon Degree Min Sec (LL DMS)"
local text = "Lat/Lon Degree Min Sec (LL DMS)"
if _SETTINGS.MenuShort then
text="LL DMS"
text = "LL DMS"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DMS" ):SetTime( MenuTime )
end
if not self:IsA2A_LL_DDM() then
local text="Lat/Lon Degree Dec Min (LL DDM)"
local text = "Lat/Lon Degree Dec Min (LL DDM)"
if _SETTINGS.MenuShort then
text="LL DDM"
text = "LL DDM"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "LL DDM" ):SetTime( MenuTime )
end
@ -593,25 +590,25 @@ do -- SETTINGS
end
if not self:IsA2A_BULLS() then
local text="Bullseye (BULLS)"
local text = "Bullseye (BULLS)"
if _SETTINGS.MenuShort then
text="Bulls"
text = "Bulls"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BULLS" ):SetTime( MenuTime )
end
if not self:IsA2A_BRAA() then
local text="Bearing Range Altitude Aspect (BRAA)"
local text = "Bearing Range Altitude Aspect (BRAA)"
if _SETTINGS.MenuShort then
text="BRAA"
text = "BRAA"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "BRAA" ):SetTime( MenuTime )
end
if not self:IsA2A_MGRS() then
local text="Military Grid (MGRS)"
local text = "Military Grid (MGRS)"
if _SETTINGS.MenuShort then
text="MGRS"
text = "MGRS"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, A2ACoordinateMenu, self.A2AMenuSystem, self, MenuGroup, RootMenu, "MGRS" ):SetTime( MenuTime )
end
@ -624,31 +621,31 @@ do -- SETTINGS
MENU_GROUP_COMMAND:New( MenuGroup, "MGRS Accuracy 5", A2ACoordinateMenu, self.MenuMGRS_Accuracy, self, MenuGroup, RootMenu, 5 ):SetTime( MenuTime )
end
local text="Measures and Weights System"
local text = "Measures and Weights System"
if _SETTINGS.MenuShort then
text="Unit System"
text = "Unit System"
end
local MetricsMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
if self:IsMetric() then
local text="Imperial (Miles,Feet)"
local text = "Imperial (Miles,Feet)"
if _SETTINGS.MenuShort then
text="Imperial"
text = "Imperial"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, false ):SetTime( MenuTime )
end
if self:IsImperial() then
local text="Metric (Kilometers,Meters)"
local text = "Metric (Kilometers,Meters)"
if _SETTINGS.MenuShort then
text="Metric"
text = "Metric"
end
MENU_GROUP_COMMAND:New( MenuGroup, text, MetricsMenu, self.MenuMWSystem, self, MenuGroup, RootMenu, true ):SetTime( MenuTime )
end
local text="Messages and Reports"
local text = "Messages and Reports"
if _SETTINGS.MenuShort then
text="Messages & Reports"
text = "Messages & Reports"
end
local MessagesMenu = MENU_GROUP:New( MenuGroup, text, SettingsMenu ):SetTime( MenuTime )
@ -689,7 +686,6 @@ do -- SETTINGS
MENU_GROUP_COMMAND:New( MenuGroup, "2 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 120 ):SetTime( MenuTime )
MENU_GROUP_COMMAND:New( MenuGroup, "3 minutes", DetailedReportsMenu, self.MenuMessageTimingsSystem, self, MenuGroup, RootMenu, MESSAGE.Type.DetailedReportsMenu, 180 ):SetTime( MenuTime )
SettingsMenu:Remove( MenuTime )
return self
@ -733,11 +729,11 @@ do -- SETTINGS
self.PlayerMenu = PlayerMenu
self:I(string.format("Setting menu for player %s", tostring(PlayerName)))
self:I( string.format( "Setting menu for player %s", tostring( PlayerName ) ) )
local submenu = MENU_GROUP:New( PlayerGroup, "LL Accuracy", PlayerMenu )
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 0 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 0 )
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 1 Decimal", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 1 Decimal", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 1 )
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 2 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 2 )
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 3 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 3 )
MENU_GROUP_COMMAND:New( PlayerGroup, "LL 4 Decimals", submenu, self.MenuGroupLL_DDM_AccuracySystem, self, PlayerUnit, PlayerGroup, PlayerName, 4 )
@ -754,40 +750,40 @@ do -- SETTINGS
-- A2G Coordinate System
------
local text="A2G Coordinate System"
local text = "A2G Coordinate System"
if _SETTINGS.MenuShort then
text="A2G Coordinates"
text = "A2G Coordinates"
end
local A2GCoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
if not self:IsA2G_LL_DMS() or _SETTINGS.MenuStatic then
local text="Lat/Lon Degree Min Sec (LL DMS)"
local text = "Lat/Lon Degree Min Sec (LL DMS)"
if _SETTINGS.MenuShort then
text="A2G LL DMS"
text = "A2G LL DMS"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
end
if not self:IsA2G_LL_DDM() or _SETTINGS.MenuStatic then
local text="Lat/Lon Degree Dec Min (LL DDM)"
local text = "Lat/Lon Degree Dec Min (LL DDM)"
if _SETTINGS.MenuShort then
text="A2G LL DDM"
text = "A2G LL DDM"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
end
if not self:IsA2G_BR() or _SETTINGS.MenuStatic then
local text="Bearing, Range (BR)"
local text = "Bearing, Range (BR)"
if _SETTINGS.MenuShort then
text="A2G BR"
text = "A2G BR"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "BR" )
end
if not self:IsA2G_MGRS() or _SETTINGS.MenuStatic then
local text="Military Grid (MGRS)"
local text = "Military Grid (MGRS)"
if _SETTINGS.MenuShort then
text="A2G MGRS"
text = "A2G MGRS"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2GCoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
end
@ -796,49 +792,48 @@ do -- SETTINGS
-- A2A Coordinates Menu
------
local text="A2A Coordinate System"
local text = "A2A Coordinate System"
if _SETTINGS.MenuShort then
text="A2A Coordinates"
text = "A2A Coordinates"
end
local A2ACoordinateMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
if not self:IsA2A_LL_DMS() or _SETTINGS.MenuStatic then
local text="Lat/Lon Degree Min Sec (LL DMS)"
local text = "Lat/Lon Degree Min Sec (LL DMS)"
if _SETTINGS.MenuShort then
text="A2A LL DMS"
text = "A2A LL DMS"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2GSystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DMS" )
end
if not self:IsA2A_LL_DDM() or _SETTINGS.MenuStatic then
local text="Lat/Lon Degree Dec Min (LL DDM)"
local text = "Lat/Lon Degree Dec Min (LL DDM)"
if _SETTINGS.MenuShort then
text="A2A LL DDM"
text = "A2A LL DDM"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "LL DDM" )
end
if not self:IsA2A_BULLS() or _SETTINGS.MenuStatic then
local text="Bullseye (BULLS)"
local text = "Bullseye (BULLS)"
if _SETTINGS.MenuShort then
text="A2A BULLS"
text = "A2A BULLS"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BULLS" )
end
if not self:IsA2A_BRAA() or _SETTINGS.MenuStatic then
local text="Bearing Range Altitude Aspect (BRAA)"
local text = "Bearing Range Altitude Aspect (BRAA)"
if _SETTINGS.MenuShort then
text="A2A BRAA"
text = "A2A BRAA"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "BRAA" )
end
if not self:IsA2A_MGRS() or _SETTINGS.MenuStatic then
local text="Military Grid (MGRS)"
local text = "Military Grid (MGRS)"
if _SETTINGS.MenuShort then
text="A2A MGRS"
text = "A2A MGRS"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, A2ACoordinateMenu, self.MenuGroupA2ASystem, self, PlayerUnit, PlayerGroup, PlayerName, "MGRS" )
end
@ -847,24 +842,24 @@ do -- SETTINGS
-- Unit system
---
local text="Measures and Weights System"
local text = "Measures and Weights System"
if _SETTINGS.MenuShort then
text="Unit System"
text = "Unit System"
end
local MetricsMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
if self:IsMetric() or _SETTINGS.MenuStatic then
local text="Imperial (Miles,Feet)"
local text = "Imperial (Miles,Feet)"
if _SETTINGS.MenuShort then
text="Imperial"
text = "Imperial"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, false )
end
if self:IsImperial() or _SETTINGS.MenuStatic then
local text="Metric (Kilometers,Meters)"
local text = "Metric (Kilometers,Meters)"
if _SETTINGS.MenuShort then
text="Metric"
text = "Metric"
end
MENU_GROUP_COMMAND:New( PlayerGroup, text, MetricsMenu, self.MenuGroupMWSystem, self, PlayerUnit, PlayerGroup, PlayerName, true )
end
@ -873,9 +868,9 @@ do -- SETTINGS
-- Messages and Reports
---
local text="Messages and Reports"
local text = "Messages and Reports"
if _SETTINGS.MenuShort then
text="Messages & Reports"
text = "Messages & Reports"
end
local MessagesMenu = MENU_GROUP:New( PlayerGroup, text, PlayerMenu )
@ -935,39 +930,38 @@ do -- SETTINGS
return self
end
--- @param #SETTINGS self
function SETTINGS:A2GMenuSystem( MenuGroup, RootMenu, A2GSystem )
self.A2GSystem = A2GSystem
MESSAGE:New( string.format("Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll()
MESSAGE:New( string.format( "Settings: Default A2G coordinate system set to %s for all players!", A2GSystem ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu )
end
--- @param #SETTINGS self
function SETTINGS:A2AMenuSystem( MenuGroup, RootMenu, A2ASystem )
self.A2ASystem = A2ASystem
MESSAGE:New( string.format("Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll()
MESSAGE:New( string.format( "Settings: Default A2A coordinate system set to %s for all players!", A2ASystem ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu )
end
--- @param #SETTINGS self
function SETTINGS:MenuLL_DDM_Accuracy( MenuGroup, RootMenu, LL_Accuracy )
self.LL_Accuracy = LL_Accuracy
MESSAGE:New( string.format("Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll()
MESSAGE:New( string.format( "Settings: Default LL accuracy set to %s for all players!", LL_Accuracy ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu )
end
--- @param #SETTINGS self
function SETTINGS:MenuMGRS_Accuracy( MenuGroup, RootMenu, MGRS_Accuracy )
self.MGRS_Accuracy = MGRS_Accuracy
MESSAGE:New( string.format("Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll()
MESSAGE:New( string.format( "Settings: Default MGRS accuracy set to %s for all players!", MGRS_Accuracy ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu )
end
--- @param #SETTINGS self
function SETTINGS:MenuMWSystem( MenuGroup, RootMenu, MW )
self.Metric = MW
MESSAGE:New( string.format("Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll()
MESSAGE:New( string.format( "Settings: Default measurement format set to %s for all players!", MW and "Metric" or "Imperial" ), 5 ):ToAll()
self:SetSystemMenu( MenuGroup, RootMenu )
end
@ -980,12 +974,12 @@ do -- SETTINGS
do
--- @param #SETTINGS self
function SETTINGS:MenuGroupA2GSystem( PlayerUnit, PlayerGroup, PlayerName, A2GSystem )
BASE:E( {self, PlayerUnit:GetName(), A2GSystem} )
BASE:E( { self, PlayerUnit:GetName(), A2GSystem } )
self.A2GSystem = A2GSystem
MESSAGE:New( string.format( "Settings: A2G format set to %s for player %s.", A2GSystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
if _SETTINGS.MenuStatic==false then
self:RemovePlayerMenu(PlayerUnit)
self:SetPlayerMenu(PlayerUnit)
if _SETTINGS.MenuStatic == false then
self:RemovePlayerMenu( PlayerUnit )
self:SetPlayerMenu( PlayerUnit )
end
end
@ -993,9 +987,9 @@ do -- SETTINGS
function SETTINGS:MenuGroupA2ASystem( PlayerUnit, PlayerGroup, PlayerName, A2ASystem )
self.A2ASystem = A2ASystem
MESSAGE:New( string.format( "Settings: A2A format set to %s for player %s.", A2ASystem, PlayerName ), 5 ):ToGroup( PlayerGroup )
if _SETTINGS.MenuStatic==false then
self:RemovePlayerMenu(PlayerUnit)
self:SetPlayerMenu(PlayerUnit)
if _SETTINGS.MenuStatic == false then
self:RemovePlayerMenu( PlayerUnit )
self:SetPlayerMenu( PlayerUnit )
end
end
@ -1003,9 +997,9 @@ do -- SETTINGS
function SETTINGS:MenuGroupLL_DDM_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, LL_Accuracy )
self.LL_Accuracy = LL_Accuracy
MESSAGE:New( string.format( "Settings: LL format accuracy set to %d decimal places for player %s.", LL_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
if _SETTINGS.MenuStatic==false then
self:RemovePlayerMenu(PlayerUnit)
self:SetPlayerMenu(PlayerUnit)
if _SETTINGS.MenuStatic == false then
self:RemovePlayerMenu( PlayerUnit )
self:SetPlayerMenu( PlayerUnit )
end
end
@ -1013,9 +1007,9 @@ do -- SETTINGS
function SETTINGS:MenuGroupMGRS_AccuracySystem( PlayerUnit, PlayerGroup, PlayerName, MGRS_Accuracy )
self.MGRS_Accuracy = MGRS_Accuracy
MESSAGE:New( string.format( "Settings: MGRS format accuracy set to %d for player %s.", MGRS_Accuracy, PlayerName ), 5 ):ToGroup( PlayerGroup )
if _SETTINGS.MenuStatic==false then
self:RemovePlayerMenu(PlayerUnit)
self:SetPlayerMenu(PlayerUnit)
if _SETTINGS.MenuStatic == false then
self:RemovePlayerMenu( PlayerUnit )
self:SetPlayerMenu( PlayerUnit )
end
end
@ -1023,9 +1017,9 @@ do -- SETTINGS
function SETTINGS:MenuGroupMWSystem( PlayerUnit, PlayerGroup, PlayerName, MW )
self.Metric = MW
MESSAGE:New( string.format( "Settings: Measurement format set to %s for player %s.", MW and "Metric" or "Imperial", PlayerName ), 5 ):ToGroup( PlayerGroup )
if _SETTINGS.MenuStatic==false then
self:RemovePlayerMenu(PlayerUnit)
self:SetPlayerMenu(PlayerUnit)
if _SETTINGS.MenuStatic == false then
self:RemovePlayerMenu( PlayerUnit )
self:SetPlayerMenu( PlayerUnit )
end
end
@ -1055,7 +1049,6 @@ do -- SETTINGS
end
--- Configures the era of the mission to be Cold war.
-- @param #SETTINGS self
-- @return #SETTINGS self
@ -1065,7 +1058,6 @@ do -- SETTINGS
end
--- Configures the era of the mission to be Modern war.
-- @param #SETTINGS self
-- @return #SETTINGS self
@ -1075,7 +1067,4 @@ do -- SETTINGS
end
end

File diff suppressed because it is too large Load Diff