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

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +1,87 @@
--- **Core** - Models the process to achieve goal(s).
--
-- ===
--
--
-- ## Features:
--
--
-- * Define the goal.
-- * Monitor the goal achievement.
-- * Manage goal contribution by players.
--
--
-- ===
--
--
-- Classes that implement a goal achievement, will derive from GOAL to implement the ways how the achievements can be realized.
--
--
-- ===
--
--
-- ### Author: **FlightControl**
-- ### Contributions: **funkyfranky**
--
--
-- ===
--
--
-- @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
--
--
-- * @{#GOAL.New}(): Creates a new GOAL object.
--
--
-- # 2. GOAL is a finite state machine (FSM).
--
--
-- ## 2.1. GOAL States
--
--
-- * **Pending**: The goal object is in progress.
-- * **Achieved**: The goal objective is Achieved.
--
--
-- ## 2.2. GOAL Events
--
--
-- * **Achieved**: Set the goal objective to Achieved.
--
--
-- # 3. Player contributions.
--
--
-- Goals are most of the time achieved by players. These player achievements can be registered as part of the goal achievement.
-- Use @{#GOAL.AddPlayerContribution}() to add a player contribution to the goal.
-- The player contributions are based on a points system, an internal counter per player.
-- So once the goal has been achieved, the player contributions can be queried using @{#GOAL.GetPlayerContributions}(),
-- So once the goal has been achieved, the player contributions can be queried using @{#GOAL.GetPlayerContributions}(),
-- that retrieves all contributions done by the players. For one player, the contribution can be queried using @{#GOAL.GetPlayerContribution}().
-- The total amount of player contributions can be queried using @{#GOAL.GetTotalContributions}().
--
--
-- # 4. Goal achievement.
--
--
-- Once the goal is achieved, the mission designer will need to trigger the goal achievement using the **Achieved** event.
-- The underlying 2 examples will achieve the goals for the `Goal` object:
--
--
-- Goal:Achieved() -- Achieve the goal immediately.
-- Goal:__Achieved( 30 ) -- Achieve the goal within 30 seconds.
--
--
-- # 5. Check goal achievement.
--
--
-- The method @{#GOAL.IsAchieved}() will return true if the goal is achieved (the trigger **Achieved** was executed).
-- You can use this method to check asynchronously if a goal has been achieved, for example using a scheduler.
--
--
-- @field #GOAL
GOAL = {
ClassName = "GOAL",
}
--- @field #table GOAL.Players
GOAL.Players = {}
--- @field #number GOAL.TotalContributions
GOAL.TotalContributions = 0
--- GOAL Constructor.
-- @param #GOAL self
-- @return #GOAL
function GOAL:New()
local self = BASE:Inherit( self, FSM:New() ) -- #GOAL
self:F( {} )
@ -104,11 +102,10 @@ do -- Goal
-- @param #string From
-- @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
-- @param #GOAL self
@ -116,47 +113,44 @@ do -- Goal
-- @param #string Event
-- @param #string To
-- @return #boolean
--- Achieved Handler OnAfter for GOAL
-- @function [parent=#GOAL] OnAfterAchieved
-- @param #GOAL self
-- @param #string From
-- @param #string Event
-- @param #string To
--- Achieved Trigger for GOAL
-- @function [parent=#GOAL] Achieved
-- @param #GOAL self
--- Achieved Asynchronous Trigger for GOAL
-- @function [parent=#GOAL] __Achieved
-- @param #GOAL self
-- @param #number Delay
self:SetEventPriority( 5 )
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
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
@ -173,9 +166,7 @@ do -- Goal
function GOAL:GetTotalContributions()
return self.TotalContributions or 0
end
--- Validates if the goal is achieved.
-- @param #GOAL self
-- @return #boolean true if the goal is achieved.
@ -183,4 +174,4 @@ do -- Goal
return self:Is( "Achieved" )
end
end
end

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
--- **Core** - Informs the players using messages during a simulation.
--
--
-- ===
--
--
-- ## Features:
--
--
-- * A more advanced messaging system using the DCS message system.
-- * Time messages.
-- * Send messages based on a message type, which has a pre-defined duration that can be tweaked in SETTINGS.
-- * Send message to all players.
-- * Send messages to a coalition.
-- * Send messages to a specific group.
--
--
-- ===
--
--
-- @module Core.Message
-- @image Core_Message.JPG
@ -23,14 +23,14 @@
--- Message System to display Messages to Clients, Coalitions or All.
-- Messages are shown on the display panel for an amount of seconds, and will then disappear.
-- Messages can contain a category which is indicating the category of the message.
--
--
-- ## MESSAGE construction
--
--
-- Messages are created with @{#MESSAGE.New}. Note that when the MESSAGE object is created, no message is sent yet.
-- To send messages, you need to use the To functions.
--
--
-- ## Send messages to an audience
--
--
-- Messages are sent:
--
-- * To a @{Client} using @{#MESSAGE.ToClient}().
@ -39,26 +39,26 @@
-- * To the red coalition using @{#MESSAGE.ToRed}().
-- * To the blue coalition using @{#MESSAGE.ToBlue}().
-- * To all Players using @{#MESSAGE.ToAll}().
--
--
-- ## Send conditionally to an audience
--
--
-- Messages can be sent conditionally to an audience (when a condition is true):
--
--
-- * To all players using @{#MESSAGE.ToAllIf}().
-- * To a coalition using @{#MESSAGE.ToCoalitionIf}().
--
--
-- ===
--
--
-- ### Author: **FlightControl**
-- ### Contributions:
--
-- ### Contributions:
--
-- ===
--
--
-- @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,52 +79,52 @@ 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"
self.MessageCategory = MessageCategory:sub( 1, -2 ) .. ":\n"
end
else
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.MessageSent = false
self.MessageGroup = false
self.MessageCoalition = false
self.MessageDuration = MessageDuration or 5
self.MessageTime = timer.getTime()
self.MessageText = MessageText:gsub( "^\n", "", 1 ):gsub( "\n$", "", 1 )
return self
self.MessageSent = false
self.MessageGroup = false
self.MessageCoalition = false
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.
--- 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.
-- The message display times are automatically defined based on the timing settings in the @{Settings} menu.
-- @param self
@ -134,83 +133,83 @@ 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() )
self:F( { MessageText } )
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.
--- 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
return self
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
end
--- Sends a MESSAGE to a Group.
--- Sends a MESSAGE to a Group.
-- @param #MESSAGE self
-- @param Wrapper.Group#GROUP Group to which the message is displayed.
-- @return #MESSAGE Message object.
@ -218,74 +217,80 @@ function MESSAGE:ToGroup( Group, Settings )
self:F( Group.GroupName )
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
return self
end
--- Sends a MESSAGE to the Blue coalition.
-- @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()
function MESSAGE:ToBlue()
self:F()
self:ToCoalition( coalition.side.BLUE )
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 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:ToCoalition( coalition.side.RED )
return self
self:ToCoalition( coalition.side.BLUE )
return self
end
--- Sends a MESSAGE to a Coalition.
--- 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()
self:ToCoalition( coalition.side.RED )
return self
end
--- Sends a MESSAGE to a Coalition.
-- @param #MESSAGE self
-- @param #DCS.coalition.side CoalitionSide @{#DCS.coalition.side} to which the message is displayed.
-- @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,20 +298,20 @@ 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
return self
end
return self
end
--- Sends a MESSAGE to a Coalition if the given Condition is true.
--- Sends a MESSAGE to a Coalition if the given Condition is true.
-- @param #MESSAGE self
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
-- @param #boolean Condition Sends the message only if the condition is true.
-- @param #boolean Condition Sends the message only if the condition is true.
-- @return #MESSAGE self
function MESSAGE:ToCoalitionIf( CoalitionSide, Condition )
self:F( CoalitionSide )
@ -314,7 +319,7 @@ function MESSAGE:ToCoalitionIf( CoalitionSide, Condition )
if Condition and Condition == true then
self:ToCoalition( CoalitionSide )
end
return self
end
@ -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

@ -1,13 +1,13 @@
--- **Core** - Provides a handy means to create messages and reports.
--
-- ===
--
--
-- ## Features:
--
--
-- * Create text blocks that are formatted.
-- * Create automatic indents.
-- * Variate the delimiters between reporting lines.
--
--
-- ===
--
-- ### Authors: FlightControl : Design & Programming
@ -15,7 +15,6 @@
-- @module Core.Report
-- @image Core_Report.JPG
--- @type REPORT
-- @extends Core.Base#BASE
@ -36,7 +35,7 @@ function REPORT:New( Title )
self.Report = {}
self:SetTitle( Title or "" )
self:SetTitle( Title or "" )
self:SetIndent( 3 )
return self
@ -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
@ -95,7 +92,7 @@ end
-- @param #string Title The title of the report.
-- @return #REPORT
function REPORT:SetTitle( Title )
self.Title = Title
self.Title = Title
return self
end

View File

@ -1,36 +1,36 @@
--- **Core** -- SCHEDULEDISPATCHER dispatches the different schedules.
--
--
-- ===
--
--
-- Takes care of the creation and dispatching of scheduled functions for SCHEDULER objects.
--
--
-- This class is tricky and needs some thorough explanation.
-- SCHEDULE classes are used to schedule functions for objects, or as persistent objects.
-- The SCHEDULEDISPATCHER class ensures that:
--
--
-- - Scheduled functions are planned according the SCHEDULER object parameters.
-- - Scheduled functions are repeated when requested, according the SCHEDULER object parameters.
-- - Scheduled functions are automatically removed when the schedule is finished, according the SCHEDULER object parameters.
--
--
-- The SCHEDULEDISPATCHER class will manage SCHEDULER object in memory during garbage collection:
--
--
-- - 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.
-- Even when there are pending timer scheduled functions to be executed for the SCHEDULER object,
--
-- 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.
--
--
-- The SCHEDULEDISPATCHER allows multiple scheduled functions to be planned and executed for one SCHEDULER object.
-- The SCHEDULER object therefore keeps a table of "CallID's", which are returned after each planning of a new scheduled function by the SCHEDULEDISPATCHER.
-- The SCHEDULER object plans new scheduled functions through the @{Core.Scheduler#SCHEDULER.Schedule}() method.
-- The SCHEDULER object plans new scheduled functions through the @{Core.Scheduler#SCHEDULER.Schedule}() method.
-- The Schedule() method returns the CallID that is the reference ID for each planned schedule.
--
--
-- ===
--
--
-- ### Contributions: -
-- ### Authors: FlightControl : Design & Programming
--
--
-- @module Core.ScheduleDispatcher
-- @image Core_Schedule_Dispatcher.JPG
@ -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.
@ -95,39 +95,38 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- Increase counter.
self.CallID = self.CallID + 1
-- Create ID.
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))
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 ) )
-- Initialize PersistentSchedulers
self.PersistentSchedulers = self.PersistentSchedulers or {}
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } )
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } )
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] } )
end
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,10 +148,10 @@ 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 = {}
if debug then
TraceLevel = TraceLevel or 2
Info = debug.getinfo( TraceLevel, "nlS" )
@ -166,7 +165,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
--- Function passed to the DCS timer.scheduleFunction()
self.Schedule[Scheduler][CallID].CallHandler = function( Params )
local CallID = Params.CallID
local Info = Params.Info or {}
local Source = Info.source or "?"
@ -180,27 +179,27 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
end
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)
-- Schedule object.
local Schedule = self.Schedule[Scheduler][CallID] --#SCHEDULEDISPATCHER.ScheduleData
--self:T3( { Schedule = Schedule } )
local MasterObject = tostring( Scheduler.MasterObject )
local SchedulerObject = Scheduler.MasterObject --Scheduler.SchedulerObject Now is this the Maste or Scheduler object?
-- Schedule object.
local Schedule = self.Schedule[Scheduler][CallID] -- #SCHEDULEDISPATCHER.ScheduleData
-- self:T3( { Schedule = Schedule } )
local SchedulerObject = Scheduler.MasterObject -- Scheduler.SchedulerObject Now is this the Master or Scheduler object?
local ShowTrace = Scheduler.ShowTrace
local ScheduleFunction = Schedule.Function
local ScheduleArguments = Schedule.Arguments or {}
local Start = Schedule.Start
@ -208,18 +207,17 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
local Randomize = Schedule.Randomize or 0
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
SchedulerObject:T( Prefix .. Name .. ":" .. Line .. " (" .. Source .. ")" )
end
return ScheduleFunction( SchedulerObject, unpack( ScheduleArguments ) )
return ScheduleFunction( SchedulerObject, unpack( ScheduleArguments ) )
end
Status, Result = xpcall( Timer, ErrorHandler )
else
@ -227,40 +225,39 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
if ShowTrace then
self:T( Prefix .. Name .. ":" .. Line .. " (" .. Source .. ")" )
end
return ScheduleFunction( unpack( ScheduleArguments ) )
return ScheduleFunction( unpack( ScheduleArguments ) )
end
Status, Result = xpcall( Timer, ErrorHandler )
end
local CurrentTime = timer.getTime()
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 } )
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 } )
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 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 )
end
else
self:Stop( Scheduler, CallID )
end
else
self:I( "<<<>" .. Name .. ":" .. Line .. " (" .. Source .. ")" )
end
return nil
end
self:Start( Scheduler, CallID, Info )
return CallID
end
@ -284,33 +281,33 @@ end
-- @param #string Info (Optional) Debug info.
function SCHEDULEDISPATCHER:Start( Scheduler, CallID, Info )
self:F2( { Start = CallID, Scheduler = Scheduler } )
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()
Schedule.StartTime = Tnow -- Set the StartTime field to indicate when the scheduler started.
local Tnow = timer.getTime()
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)
self:T(string.format("Starting scheduledispatcher Call ID=%s ==> Schedule ID=%s", tostring(CallID), tostring(Schedule.ScheduleID)))
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 ) ) )
end
else
-- Recursive.
for CallID, Schedule in pairs( self.Schedule[Scheduler] or {} ) do
self:Start( Scheduler, CallID, Info ) -- Recursive
end
end
end
@ -322,29 +319,29 @@ function SCHEDULEDISPATCHER:Stop( Scheduler, CallID )
self:F2( { Stop = CallID, Scheduler = Scheduler } )
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
for CallID, Schedule in pairs( self.Schedule[Scheduler] or {} ) do
self:Stop( Scheduler, CallID ) -- Recursive
end
end
end
@ -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

@ -1,41 +1,41 @@
--- **Core** - Prepares and handles the execution of functions over scheduled time (intervals).
--
-- ===
--
--
-- ## Features:
--
--
-- * Schedule functions over time,
-- * optionally in an optional specified time interval,
-- * optionally **repeating** with a specified time repeat interval,
-- * optionally **randomizing** with a specified time interval randomization factor,
-- * optionally **stop** the repeating after a specified time interval.
-- * optionally in an optional specified time interval,
-- * optionally **repeating** with a specified time repeat interval,
-- * optionally **randomizing** with a specified time interval randomization factor,
-- * optionally **stop** the repeating after a specified time interval.
--
-- ===
--
--
-- # Demo Missions
--
--
-- ### [SCHEDULER Demo Missions source code](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master-release/SCH%20-%20Scheduler)
--
--
-- ### [SCHEDULER Demo Missions, only for beta testers](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/SCH%20-%20Scheduler)
--
-- ### [ALL Demo Missions pack of the last release](https://github.com/FlightControl-Master/MOOSE_MISSIONS/releases)
--
-- ===
--
-- # YouTube Channel
--
-- ### [SCHEDULER YouTube Channel (none)]()
--
--
-- ===
--
-- ### Contributions:
--
-- # YouTube Channel
--
-- ### [SCHEDULER YouTube Channel (none)]()
--
-- ===
--
-- ### Contributions:
--
-- * FlightControl : Concept & Testing
--
-- ### Authors:
--
--
-- ### Authors:
--
-- * FlightControl : Design & Programming
--
--
-- ===
--
-- @module Core.Scheduler
@ -48,62 +48,61 @@
-- @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**.
-- The ScheduleID is returned when the method @{#SCHEDULER.Schedule}() is called.
-- It is recommended to store the ScheduleID in a variable, as it is used in the methods @{SCHEDULER.Start}() and @{SCHEDULER.Stop}(),
-- which can start and stop specific repeating schedules respectively within a SCHEDULER object.
--
-- ## SCHEDULER constructor
--
--
-- The SCHEDULER class is quite easy to use, but note that the New constructor has variable parameters:
--
--
-- The @{#SCHEDULER.New}() method returns 2 variables:
--
--
-- 1. The SCHEDULER object reference.
-- 2. The first schedule planned in the SCHEDULER object.
--
--
-- To clarify the different appliances, lets have a look at the following examples:
--
--
-- ### Construct a SCHEDULER object without a persistent schedule.
--
--
-- * @{#SCHEDULER.New}( nil ): Setup a new SCHEDULER object, which is persistently executed after garbage collection.
--
--
-- MasterObject = SCHEDULER:New()
-- SchedulerID = MasterObject:Schedule( nil, ScheduleFunction, {} )
--
--
-- The above example creates a new MasterObject, but does not schedule anything.
-- A separate schedule is created by using the MasterObject using the method :Schedule..., which returns a ScheduleID
--
--
-- ### 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 )
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {} )
-- ...
-- ZoneObject = nil
-- garbagecollect()
--
--
-- The above example creates a new MasterObject, but does not schedule anything, and is bound to the existence of ZoneObject, which is a ZONE.
-- A separate schedule is created by using the MasterObject using the method :Schedule()..., which returns a ScheduleID
-- Later in the logic, the ZoneObject is put to nil, and garbage is collected.
-- As a result, the MasterObject will cancel any planned schedule.
--
--
-- ### Construct a SCHEDULER object with a persistent schedule.
--
--
-- * @{#SCHEDULER.New}( nil, Function, FunctionArguments, Start, ... ): Setup a new persistent SCHEDULER object, and start a new schedule for the Function with the defined FunctionArguments according the Start and sequent parameters.
--
--
-- MasterObject, SchedulerID = SCHEDULER:New( nil, ScheduleFunction, {} )
--
--
-- The above example creates a new MasterObject, and does schedule the first schedule as part of the call.
-- Note that 2 variables are returned here: MasterObject, ScheduleID...
--
--
-- ### Construct a SCHEDULER object without a schedule, but volatile to the Object existence...
--
--
-- * @{#SCHEDULER.New}( Object, Function, FunctionArguments, Start, ... ): Setup a new SCHEDULER object, linked to Object, and start a new schedule for the Function with the defined FunctionArguments according the Start and sequent parameters.
--
-- ZoneObject = ZONE:New( "ZoneName" )
@ -112,13 +111,13 @@
-- ...
-- ZoneObject = nil
-- garbagecollect()
--
--
-- The above example creates a new MasterObject, and schedules a method call (ScheduleFunction),
-- and is bound to the existence of ZoneObject, which is a ZONE object (ZoneObject).
-- Both a MasterObject and a SchedulerID variable are returned.
-- Later in the logic, the ZoneObject is put to nil, and garbage is collected.
-- As a result, the MasterObject will cancel the planned schedule.
--
--
-- ## SCHEDULER timer stopping and (re-)starting.
--
-- The SCHEDULER can be stopped and restarted with the following methods:
@ -133,70 +132,70 @@
-- MasterObject:Stop( SchedulerID )
-- ...
-- MasterObject:Start( SchedulerID )
--
--
-- The above example creates a new MasterObject, and does schedule the first schedule as part of the call.
-- Note that 2 variables are returned here: MasterObject, ScheduleID...
-- Later in the logic, the repeating schedule with SchedulerID is stopped.
-- A bit later, the repeating schedule with SchedulerId is (re)-started.
--
-- Note that 2 variables are returned here: MasterObject, ScheduleID...
-- Later in the logic, the repeating schedule with SchedulerID is stopped.
-- A bit later, the repeating schedule with SchedulerId is (re)-started.
--
-- ## Create a new schedule
--
-- With the method @{#SCHEDULER.Schedule}() a new time event can be scheduled.
--
-- With the method @{#SCHEDULER.Schedule}() a new time event can be scheduled.
-- This method is used by the :New() constructor when a new schedule is planned.
--
--
-- Consider the following code fragment of the SCHEDULER object creation.
--
--
-- 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
--
--
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {}, 10 )
--
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within 10 seconds ...
--
--
-- ### A schedule with a repeating time interval, planned over time
--
--
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {}, 10, 60 )
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within 10 seconds,
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within 10 seconds,
-- and repeating 60 every seconds ...
--
--
-- ### A schedule with a repeating time interval, planned over time, with time interval randomization
--
--
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {}, 10, 60, 0.5 )
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within 10 seconds,
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within 10 seconds,
-- and repeating 60 seconds, with a 50% time interval randomization ...
-- So the repeating time interval will be randomized using the **0.5**,
-- and will calculate between **60 - ( 60 * 0.5 )** and **60 + ( 60 * 0.5 )** for each repeat,
-- So the repeating time interval will be randomized using the **0.5**,
-- and will calculate between **60 - ( 60 * 0.5 )** and **60 + ( 60 * 0.5 )** for each repeat,
-- which is in this example between **30** and **90** seconds.
--
--
-- ### A schedule with a repeating time interval, planned over time, with time interval randomization, and stop after a time interval
--
--
-- SchedulerID = MasterObject:Schedule( ZoneObject, ScheduleFunction, {}, 10, 60, 0.5, 300 )
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within 10 seconds,
--
-- The above example schedules a new ScheduleFunction call to be executed asynchronously, within 10 seconds,
-- The schedule will repeat every 60 seconds.
-- So the repeating time interval will be randomized using the **0.5**,
-- and will calculate between **60 - ( 60 * 0.5 )** and **60 + ( 60 * 0.5 )** for each repeat,
-- So the repeating time interval will be randomized using the **0.5**,
-- and will calculate between **60 - ( 60 * 0.5 )** and **60 + ( 60 * 0.5 )** for each repeat,
-- which is in this example between **30** and **90** seconds.
-- The schedule will stop after **300** seconds.
--
--
-- @field #SCHEDULER
SCHEDULER = {
ClassName = "SCHEDULER",
Schedules = {},
MasterObject = nil,
ShowTrace = nil,
ClassName = "SCHEDULER",
Schedules = {},
MasterObject = nil,
ShowTrace = nil,
}
--- SCHEDULER constructor.
@ -211,15 +210,15 @@ SCHEDULER = {
-- @return #SCHEDULER self.
-- @return #table The ScheduleID of the planned schedule.
function SCHEDULER:New( MasterObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop )
local self = BASE:Inherit( self, BASE:New() ) -- #SCHEDULER
self:F2( { Start, Repeat, RandomizeFactor, Stop } )
local ScheduleID = nil
self.MasterObject = MasterObject
self.ShowTrace = false
if SchedulerFunction then
ScheduleID = self:Schedule( MasterObject, SchedulerFunction, SchedulerArguments, Start, Repeat, RandomizeFactor, Stop, 3 )
end
@ -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.
@ -245,28 +244,27 @@ function SCHEDULER:Schedule( MasterObject, SchedulerFunction, SchedulerArguments
-- Debug info.
local ObjectName = "-"
if MasterObject and MasterObject.ClassName and MasterObject.ClassID then
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
)
self.Schedules[#self.Schedules+1] = ScheduleID
local ScheduleID = _SCHEDULEDISPATCHER:AddSchedule( self,
SchedulerFunction,
SchedulerArguments,
Start,
Repeat,
RandomizeFactor,
Stop,
TraceLevel or 3,
Fsm
)
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