mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge pull request #172 from FlightControl-Master/Moose-Release
-- Fixed DETECTION DISPATCHER -- Need to test this in a group. -- Revised messages adding @ signs, which represent to who the message is targetted.
This commit is contained in:
commit
8eaa6a39d9
@ -144,13 +144,15 @@ do -- ACT_ROUTE
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE:onbeforeRoute( ProcessUnit, Event, From, To )
|
||||
self:F( { "BeforeRoute 1", self.DisplayCount, self.DisplayInterval } )
|
||||
|
||||
if ProcessUnit:IsAlive() then
|
||||
self:F( "BeforeRoute 2" )
|
||||
local HasArrived = self:onfuncHasArrived( ProcessUnit ) -- Polymorphic
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
self:T( { HasArrived = HasArrived } )
|
||||
if not HasArrived then
|
||||
self:__Report( 1 )
|
||||
self:Report()
|
||||
end
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
@ -208,6 +210,7 @@ do -- ACT_ROUTE_ZONE
|
||||
function ACT_ROUTE_ZONE:Init( FsmRoute )
|
||||
|
||||
self.TargetZone = FsmRoute.TargetZone
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
|
||||
@ -550,6 +550,8 @@ 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.
|
||||
|
||||
--- Send a message of the @{Task} to the Group of the Unit.
|
||||
-- @param #FSM_PROCESS self
|
||||
function FSM_PROCESS:Message( Message )
|
||||
@ -558,6 +560,12 @@ function FSM_PROCESS:Message( Message )
|
||||
local CC = self:GetCommandCenter()
|
||||
local TaskGroup = self.Controllable:GetGroup()
|
||||
|
||||
local PlayerName = self.Controllable:GetPlayerName() -- Only for a unit
|
||||
PlayerName = PlayerName and " (" .. PlayerName .. ")" or "" -- If PlayerName is nil, then keep it nil, otherwise add brackets.
|
||||
local Callsign = self.Controllable:GetCallsign()
|
||||
local Prefix = Callsign and " @ " .. Callsign .. PlayerName or ""
|
||||
|
||||
Message = Prefix .. ": " .. Message
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
end
|
||||
|
||||
|
||||
@ -1475,6 +1475,25 @@ function SET_UNIT:GetUnitThreatLevels()
|
||||
return UnitThreatLevels
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the SET_UNIT.
|
||||
-- @param #SET_UNIT self
|
||||
function SET_UNIT:CalculateThreatLevelA2G()
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( self:GetSet() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
return MaxThreatLevelA2G
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Returns if the @{Set} has targets having a radar (of a given type).
|
||||
-- @param #SET_UNIT self
|
||||
-- @param Dcs.DCSWrapper.Unit#Unit.RadarType RadarType
|
||||
|
||||
@ -64,7 +64,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
self.CommandCenterName = CommandCenterName or CommandCenterPositionable:GetName()
|
||||
self.CommandCenterCoalition = CommandCenterPositionable:GetCoalition()
|
||||
|
||||
self.Missions = setmetatable( {}, { __mode = "v" } )
|
||||
self.Missions = {}
|
||||
|
||||
self:EventOnBirth(
|
||||
--- @param #COMMANDCENTER self
|
||||
@ -142,7 +142,7 @@ end
|
||||
-- @return #string
|
||||
function COMMANDCENTER:GetName()
|
||||
|
||||
return self.HQName
|
||||
return self.CommandCenterName
|
||||
end
|
||||
|
||||
--- Gets the POSITIONABLE of the HQ command center.
|
||||
@ -188,7 +188,12 @@ end
|
||||
function COMMANDCENTER:SetMenu()
|
||||
self:F()
|
||||
|
||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "HQ" )
|
||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "Command Center (" .. self:GetName() .. ")" )
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission:RemoveMenu()
|
||||
end
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
@ -218,9 +223,14 @@ end
|
||||
|
||||
--- Send a CC message to a GROUP.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup )
|
||||
-- @param #string Message
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
|
||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup, Name )
|
||||
|
||||
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup )
|
||||
local Prefix = Name and "@ Group (" .. Name .. "): " or ''
|
||||
Message = Prefix .. Message
|
||||
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -382,7 +382,6 @@ do -- DETECTION_DISPATCHER
|
||||
if Task then
|
||||
if Task:IsStatePlanned() and DetectedArea.Changed == true then
|
||||
self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
||||
Mission:RemoveTaskMenu( Task )
|
||||
Task = Mission:RemoveTask( Task )
|
||||
end
|
||||
end
|
||||
@ -486,7 +485,7 @@ do -- DETECTION_DISPATCHER
|
||||
end
|
||||
|
||||
-- TODO set menus using the HQ coordinator
|
||||
Mission:SetMenu()
|
||||
Mission:GetCommandCenter():SetMenu()
|
||||
|
||||
if #AreaMsg > 0 then
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
|
||||
@ -200,7 +200,6 @@ end
|
||||
|
||||
--- Sets the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
-- @param Core.Menu#MENU_COALITION CommandCenterMenu
|
||||
function MISSION:SetMenu()
|
||||
self:F()
|
||||
|
||||
@ -210,6 +209,17 @@ function MISSION:SetMenu()
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
function MISSION:RemoveMenu()
|
||||
self:F()
|
||||
|
||||
for _, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Task:RemoveMenu()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Gets the COMMANDCENTER.
|
||||
-- @param #MISSION self
|
||||
|
||||
@ -439,7 +439,8 @@ function TASK:MessageToGroups( Message )
|
||||
local CC = Mission:GetCommandCenter()
|
||||
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
CC:MessageToGroup( Message, TaskGroup, TaskGroup:GetName() )
|
||||
end
|
||||
end
|
||||
|
||||
@ -527,7 +528,6 @@ function TASK:SetMenu()
|
||||
|
||||
self.SetGroup:Flush()
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
self:RemoveMenuForGroup( TaskGroup )
|
||||
if self:IsStatePlanned() or self:IsStateReplanned() then
|
||||
self:SetMenuForGroup( TaskGroup )
|
||||
end
|
||||
@ -873,7 +873,7 @@ function TASK:onenterAssigned( Event, From, To )
|
||||
|
||||
self:E("Task Assigned")
|
||||
|
||||
self:MessageToGroups( "Task " .. self:GetName() .. " has been assigned!" )
|
||||
self:MessageToGroups( "Task " .. self:GetName() .. " has been assigned to your group." )
|
||||
self:GetMission():__Start()
|
||||
end
|
||||
|
||||
@ -992,10 +992,12 @@ function TASK:ReportDetails()
|
||||
PlayerNames[#PlayerNames+1] = PlayerName
|
||||
end
|
||||
end
|
||||
PlayerNameText = table.concat( PlayerNames, ", " )
|
||||
local PlayerNameText = table.concat( PlayerNames, ", " )
|
||||
Report:Add( "Task " .. Name .. " - State '" .. State .. "' - Players " .. PlayerNameText )
|
||||
end
|
||||
|
||||
-- Loop each Process in the Task, and find Reporting Details.
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
|
||||
@ -1,84 +0,0 @@
|
||||
--- @module Task_Client_Menu
|
||||
|
||||
--- TASK2_MENU_CLIENT class
|
||||
-- @type TASK2_MENU_CLIENT
|
||||
-- @field Wrapper.Unit#UNIT TaskUnit
|
||||
-- @field Core.Set#SET_UNIT TargetSet
|
||||
-- @field Core.Menu#MENU_CLIENT_COMMAND MenuTask
|
||||
-- @extends Task2#TASK2
|
||||
TASK2_MENU_CLIENT = {
|
||||
ClassName = "TASK2_MENU_CLIENT",
|
||||
TargetSet = nil,
|
||||
}
|
||||
|
||||
|
||||
--- Creates a new MENU handling machine.
|
||||
-- @param #TASK2_MENU_CLIENT self
|
||||
-- @param Tasking.Mission#MISSION Mission
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param #string MenuText The text of the menu item.
|
||||
-- @return #TASK2_MENU_CLIENT self
|
||||
function TASK2_MENU_CLIENT:New( Mission, TaskUnit, MenuText )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, TASK2:New( Mission, TaskUnit ) ) -- #TASK2_MENU_CLIENT
|
||||
|
||||
self.MenuText = MenuText
|
||||
|
||||
self.Fsm = FSM_TASK:New( self, {
|
||||
initial = 'Unassigned',
|
||||
events = {
|
||||
{ name = 'Menu', from = 'Unassigned', to = 'AwaitingMenu' },
|
||||
{ name = 'Assign', from = 'AwaitingMenu', to = 'Assigned' },
|
||||
},
|
||||
callbacks = {
|
||||
onMenu = self.OnMenu,
|
||||
onAssign = self.OnAssign,
|
||||
},
|
||||
endstates = {
|
||||
'Assigned'
|
||||
},
|
||||
} )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Task Events
|
||||
|
||||
--- StateMachine callback function for a TASK2
|
||||
-- @param #TASK2_MENU_CLIENT self
|
||||
-- @param Core.Fsm#FSM_TASK Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function TASK2_MENU_CLIENT:OnMenu( Fsm, Event, From, To )
|
||||
self:E( { Event, From, To, self.TaskUnit.UnitName} )
|
||||
|
||||
self.TaskUnit:Message( "Press F10 for task menu", 15 )
|
||||
self.Menu = MENU_CLIENT:New( self.TaskUnit, self.Mission:GetName(), nil )
|
||||
self.MenuTask = MENU_CLIENT_COMMAND:New( self.TaskUnit, self.MenuText, self.Menu, self.MenuAssign, self )
|
||||
end
|
||||
|
||||
--- Menu function.
|
||||
-- @param #TASK2_MENU_CLIENT self
|
||||
function TASK2_MENU_CLIENT:MenuAssign()
|
||||
self:E( )
|
||||
|
||||
self.TaskUnit:Message( "Menu Assign", 15 )
|
||||
|
||||
self:NextEvent( self.Fsm.Assign )
|
||||
end
|
||||
|
||||
--- StateMachine callback function for a TASK2
|
||||
-- @param #TASK2_MENU_CLIENT self
|
||||
-- @param Core.Fsm#FSM_TASK Fsm
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function TASK2_MENU_CLIENT:OnAssign( Fsm, Event, From, To )
|
||||
self:E( { Event, From, To, self.TaskUnit.UnitName} )
|
||||
|
||||
self.TaskUnit:Message( "Assign Task", 15 )
|
||||
self.MenuTask:Remove()
|
||||
end
|
||||
|
||||
@ -45,19 +45,19 @@ do -- TASK_A2G
|
||||
self.TargetZone = TargetZone
|
||||
self.FACUnit = FACUnit
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
local A2GUnitProcess = self:GetUnitProcess()
|
||||
|
||||
Fsm:AddProcess( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddAction ( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
A2GUnitProcess:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
A2GUnitProcess:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
A2GUnitProcess:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
A2GUnitProcess:AddTransition( "Arrived", "Update", "Updated" )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
--Fsm:AddProcess ( "Updated", "JTAC", PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) )
|
||||
Fsm:AddAction ( "Accounted", "Success", "Success" )
|
||||
Fsm:AddAction ( "Failed", "Fail", "Failed" )
|
||||
A2GUnitProcess:AddTransition( "Accounted", "Success", "Success" )
|
||||
A2GUnitProcess:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
function A2GUnitProcess:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
self:Account()
|
||||
self:Smoke()
|
||||
|
||||
@ -1,283 +0,0 @@
|
||||
--- This module contains the AI_BALANCER class.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- 1) @{AI.AI_Balancer#AI_BALANCER} class, extends @{Core.Base#BASE}
|
||||
-- =======================================================
|
||||
-- The @{AI.AI_Balancer#AI_BALANCER} class controls the dynamic spawning of AI GROUPS depending on a SET_CLIENT.
|
||||
-- There will be as many AI GROUPS spawned as there at CLIENTS in SET_CLIENT not spawned.
|
||||
-- The AI_Balancer uses the @{PatrolCore.Zone#AI_PATROLZONE} class to make AI patrol an zone until the fuel treshold is reached.
|
||||
--
|
||||
-- 1.1) AI_BALANCER construction method:
|
||||
-- ------------------------------------
|
||||
-- Create a new AI_BALANCER object with the @{#AI_BALANCER.New} method:
|
||||
--
|
||||
-- * @{#AI_BALANCER.New}: Creates a new AI_BALANCER object.
|
||||
--
|
||||
-- 1.2) AI_BALANCER returns AI to Airbases:
|
||||
-- ---------------------------------------
|
||||
-- You can configure to have the AI to return to:
|
||||
--
|
||||
-- * @{#AI_BALANCER.ReturnToHomeAirbase}: Returns the AI to the home @{Wrapper.Airbase#AIRBASE}.
|
||||
-- * @{#AI_BALANCER.ReturnToNearestAirbases}: Returns the AI to the nearest friendly @{Wrapper.Airbase#AIRBASE}.
|
||||
--
|
||||
-- 1.3) AI_BALANCER allows AI to patrol specific zones:
|
||||
-- ---------------------------------------------------
|
||||
-- Use @{AI.AI_Balancer#AI_BALANCER.SetPatrolZone}() to specify a zone where the AI needs to patrol.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- **API CHANGE HISTORY**
|
||||
-- ======================
|
||||
--
|
||||
-- The underlying change log documents the API changes. Please read this carefully. The following notation is used:
|
||||
--
|
||||
-- * **Added** parts are expressed in bold type face.
|
||||
-- * _Removed_ parts are expressed in italic type face.
|
||||
--
|
||||
-- Hereby the change log:
|
||||
--
|
||||
-- 2016-08-17: SPAWN:**InitCleanUp**( SpawnCleanUpInterval ) replaces SPAWN:_CleanUp_( SpawnCleanUpInterval )
|
||||
--
|
||||
-- * Want to ensure that the methods starting with **Init** are the first called methods before any _Spawn_ method is called!
|
||||
-- * This notation makes it now more clear which methods are initialization methods and which methods are Spawn enablement methods.
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- AUTHORS and CONTRIBUTIONS
|
||||
-- =========================
|
||||
--
|
||||
-- ### Contributions:
|
||||
--
|
||||
-- * **Dutch_Baron (James)**: Who you can search on the Eagle Dynamics Forums.
|
||||
-- Working together with James has resulted in the creation of the AI_BALANCER class.
|
||||
-- James has shared his ideas on balancing AI with air units, and together we made a first design which you can use now :-)
|
||||
--
|
||||
-- * **SNAFU**:
|
||||
-- Had a couple of mails with the guys to validate, if the same concept in the GCI/CAP script could be reworked within MOOSE.
|
||||
-- None of the script code has been used however within the new AI_BALANCER moose class.
|
||||
--
|
||||
-- ### Authors:
|
||||
--
|
||||
-- * FlightControl: Framework Design & Programming
|
||||
--
|
||||
-- @module AI_Balancer
|
||||
|
||||
|
||||
|
||||
--- AI_BALANCER class
|
||||
-- @type AI_BALANCER
|
||||
-- @field Core.Set#SET_CLIENT SetClient
|
||||
-- @field Functional.Spawn#SPAWN SpawnAI
|
||||
-- @field #boolean ToNearestAirbase
|
||||
-- @field Core.Set#SET_AIRBASE ReturnAirbaseSet
|
||||
-- @field Dcs.DCSTypes#Distance ReturnTresholdRange
|
||||
-- @field #boolean ToHomeAirbase
|
||||
-- @field PatrolCore.Zone#AI_PATROLZONE PatrolZone
|
||||
-- @extends Core.Base#BASE
|
||||
AI_BALANCER = {
|
||||
ClassName = "AI_BALANCER",
|
||||
PatrolZones = {},
|
||||
AIGroups = {},
|
||||
}
|
||||
|
||||
--- Creates a new AI_BALANCER object, building a set of units belonging to a coalitions, categories, countries, types or with defined prefix names.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param SetClient A SET_CLIENT object that will contain the CLIENT objects to be monitored if they are alive or not (joined by a player).
|
||||
-- @param SpawnAI A SPAWN object that will spawn the AI units required, balancing the SetClient.
|
||||
-- @return #AI_BALANCER self
|
||||
function AI_BALANCER:New( SetClient, SpawnAI )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
|
||||
self.SetClient = SetClient
|
||||
if type( SpawnAI ) == "table" then
|
||||
if SpawnAI.ClassName and SpawnAI.ClassName == "SPAWN" then
|
||||
self.SpawnAI = { SpawnAI }
|
||||
else
|
||||
local SpawnObjects = true
|
||||
for SpawnObjectID, SpawnObject in pairs( SpawnAI ) do
|
||||
if SpawnObject.ClassName and SpawnObject.ClassName == "SPAWN" then
|
||||
self:E( SpawnObject.ClassName )
|
||||
else
|
||||
self:E( "other object" )
|
||||
SpawnObjects = false
|
||||
end
|
||||
end
|
||||
if SpawnObjects == true then
|
||||
self.SpawnAI = SpawnAI
|
||||
else
|
||||
error( "No SPAWN object given in parameter SpawnAI, either as a single object or as a table of objects!" )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.ToNearestAirbase = false
|
||||
self.ReturnHomeAirbase = false
|
||||
|
||||
self.AIMonitorSchedule = SCHEDULER:New( self, self._ClientAliveMonitorScheduler, {}, 1, 10, 0 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Returns the AI to the nearest friendly @{Wrapper.Airbase#AIRBASE}.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param Dcs.DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Wrapper.Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Wrapper.Airbase#AIRBASE}.
|
||||
-- @param Core.Set#SET_AIRBASE ReturnAirbaseSet The SET of @{Core.Set#SET_AIRBASE}s to evaluate where to return to.
|
||||
function AI_BALANCER:ReturnToNearestAirbases( ReturnTresholdRange, ReturnAirbaseSet )
|
||||
|
||||
self.ToNearestAirbase = true
|
||||
self.ReturnTresholdRange = ReturnTresholdRange
|
||||
self.ReturnAirbaseSet = ReturnAirbaseSet
|
||||
end
|
||||
|
||||
--- Returns the AI to the home @{Wrapper.Airbase#AIRBASE}.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param Dcs.DCSTypes#Distance ReturnTresholdRange If there is an enemy @{Wrapper.Client#CLIENT} within the ReturnTresholdRange given in meters, the AI will not return to the nearest @{Wrapper.Airbase#AIRBASE}.
|
||||
function AI_BALANCER:ReturnToHomeAirbase( ReturnTresholdRange )
|
||||
|
||||
self.ToHomeAirbase = true
|
||||
self.ReturnTresholdRange = ReturnTresholdRange
|
||||
end
|
||||
|
||||
--- Let the AI patrol a @{Zone} with a given Speed range and Altitude range.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @param PatrolCore.Zone#AI_PATROLZONE PatrolZone The @{PatrolZone} where the AI needs to patrol.
|
||||
-- @return PatrolCore.Zone#AI_PATROLZONE self
|
||||
function AI_BALANCER:SetPatrolZone( PatrolZone, PatrolFloorAltitude, PatrolCeilingAltitude, PatrolMinSpeed, PatrolMaxSpeed )
|
||||
|
||||
self.PatrolZone = AI_PATROLZONE:New(
|
||||
self.SpawnAI,
|
||||
PatrolZone,
|
||||
PatrolFloorAltitude,
|
||||
PatrolCeilingAltitude,
|
||||
PatrolMinSpeed,
|
||||
PatrolMaxSpeed
|
||||
)
|
||||
end
|
||||
|
||||
--- Get the @{PatrolZone} object assigned by the @{AI_Balancer} object.
|
||||
-- @param #AI_BALANCER self
|
||||
-- @return PatrolCore.Zone#AI_PATROLZONE PatrolZone The @{PatrolZone} where the AI needs to patrol.
|
||||
function AI_BALANCER:GetPatrolZone()
|
||||
|
||||
return self.PatrolZone
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_BALANCER self
|
||||
function AI_BALANCER:_ClientAliveMonitorScheduler()
|
||||
|
||||
self.SetClient:ForEachClient(
|
||||
--- @param Wrapper.Client#CLIENT Client
|
||||
function( Client )
|
||||
local ClientAIAliveState = Client:GetState( self, 'AIAlive' )
|
||||
self:T( ClientAIAliveState )
|
||||
if Client:IsAlive() then
|
||||
if ClientAIAliveState == true then
|
||||
Client:SetState( self, 'AIAlive', false )
|
||||
|
||||
local AIGroup = self.AIGroups[Client.UnitName] -- Wrapper.Group#GROUP
|
||||
|
||||
-- local PatrolZone = Client:GetState( self, "PatrolZone" )
|
||||
-- if PatrolZone then
|
||||
-- PatrolZone = nil
|
||||
-- Client:ClearState( self, "PatrolZone" )
|
||||
-- end
|
||||
|
||||
if self.ToNearestAirbase == false and self.ToHomeAirbase == false then
|
||||
AIGroup:Destroy()
|
||||
else
|
||||
-- We test if there is no other CLIENT within the self.ReturnTresholdRange of the first unit of the AI group.
|
||||
-- If there is a CLIENT, the AI stays engaged and will not return.
|
||||
-- If there is no CLIENT within the self.ReturnTresholdRange, then the unit will return to the Airbase return method selected.
|
||||
|
||||
local PlayerInRange = { Value = false }
|
||||
local RangeZone = ZONE_RADIUS:New( 'RangeZone', AIGroup:GetVec2(), self.ReturnTresholdRange )
|
||||
|
||||
self:E( RangeZone )
|
||||
|
||||
_DATABASE:ForEachPlayer(
|
||||
--- @param Wrapper.Unit#UNIT RangeTestUnit
|
||||
function( RangeTestUnit, RangeZone, AIGroup, PlayerInRange )
|
||||
self:E( { PlayerInRange, RangeTestUnit.UnitName, RangeZone.ZoneName } )
|
||||
if RangeTestUnit:IsInZone( RangeZone ) == true then
|
||||
self:E( "in zone" )
|
||||
if RangeTestUnit:GetCoalition() ~= AIGroup:GetCoalition() then
|
||||
self:E( "in range" )
|
||||
PlayerInRange.Value = true
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
--- @param Core.Zone#ZONE_RADIUS RangeZone
|
||||
-- @param Wrapper.Group#GROUP AIGroup
|
||||
function( RangeZone, AIGroup, PlayerInRange )
|
||||
local AIGroupTemplate = AIGroup:GetTemplate()
|
||||
if PlayerInRange.Value == false then
|
||||
if self.ToHomeAirbase == true then
|
||||
local WayPointCount = #AIGroupTemplate.route.points
|
||||
local SwitchWayPointCommand = AIGroup:CommandSwitchWayPoint( 1, WayPointCount, 1 )
|
||||
AIGroup:SetCommand( SwitchWayPointCommand )
|
||||
AIGroup:MessageToRed( "Returning to home base ...", 30 )
|
||||
else
|
||||
-- Okay, we need to send this Group back to the nearest base of the Coalition of the AI.
|
||||
--TODO: i need to rework the POINT_VEC2 thing.
|
||||
local PointVec2 = POINT_VEC2:New( AIGroup:GetVec2().x, AIGroup:GetVec2().y )
|
||||
local ClosestAirbase = self.ReturnAirbaseSet:FindNearestAirbaseFromPointVec2( PointVec2 )
|
||||
self:T( ClosestAirbase.AirbaseName )
|
||||
AIGroup:MessageToRed( "Returning to " .. ClosestAirbase:GetName().. " ...", 30 )
|
||||
local RTBRoute = AIGroup:RouteReturnToAirbase( ClosestAirbase )
|
||||
AIGroupTemplate.route = RTBRoute
|
||||
AIGroup:Respawn( AIGroupTemplate )
|
||||
end
|
||||
end
|
||||
end
|
||||
, RangeZone, AIGroup, PlayerInRange
|
||||
)
|
||||
|
||||
end
|
||||
end
|
||||
else
|
||||
if not ClientAIAliveState or ClientAIAliveState == false then
|
||||
Client:SetState( self, 'AIAlive', true )
|
||||
|
||||
|
||||
-- OK, spawn a new group from the SpawnAI objects provided.
|
||||
local SpawnAICount = #self.SpawnAI
|
||||
local SpawnAIIndex = math.random( 1, SpawnAICount )
|
||||
local AIGroup = self.SpawnAI[SpawnAIIndex]:Spawn()
|
||||
AIGroup:E( "spawning new AIGroup" )
|
||||
--TODO: need to rework UnitName thing ...
|
||||
self.AIGroups[Client.UnitName] = AIGroup
|
||||
|
||||
--- Now test if the AIGroup needs to patrol a zone, otherwise let it follow its route...
|
||||
if self.PatrolZone then
|
||||
self.PatrolZones[#self.PatrolZones+1] = AI_PATROLZONE:New(
|
||||
self.PatrolZone.PatrolZone,
|
||||
self.PatrolZone.PatrolFloorAltitude,
|
||||
self.PatrolZone.PatrolCeilingAltitude,
|
||||
self.PatrolZone.PatrolMinSpeed,
|
||||
self.PatrolZone.PatrolMaxSpeed
|
||||
)
|
||||
|
||||
if self.PatrolZone.PatrolManageFuel == true then
|
||||
self.PatrolZones[#self.PatrolZones]:ManageFuel( self.PatrolZone.PatrolFuelTresholdPercentage, self.PatrolZone.PatrolOutOfFuelOrbitTime )
|
||||
end
|
||||
self.PatrolZones[#self.PatrolZones]:SetGroup( AIGroup )
|
||||
|
||||
--self.PatrolZones[#self.PatrolZones+1] = PatrolZone
|
||||
|
||||
--Client:SetState( self, "PatrolZone", PatrolZone )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -49,12 +49,12 @@ do -- TASK_SEAD
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddAction ( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddTransition( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
Fsm:AddAction ( "Accounted", "Success", "Success" )
|
||||
Fsm:AddAction ( "Failed", "Fail", "Failed" )
|
||||
Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
|
||||
@ -865,4 +865,22 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the Group.
|
||||
-- @param #GROUP self
|
||||
function GROUP:CalculateThreatLevelA2G()
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( self:GetUnits() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
return MaxThreatLevelA2G
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
@ -210,6 +210,13 @@ function IDENTIFIABLE:GetDesc()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Gets the CallSign of the IDENTIFIABLE, which is a blank by default.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string The CallSign of the IDENTIFIABLE.
|
||||
function IDENTIFIABLE:GetCallsign()
|
||||
return ''
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -280,12 +280,14 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
-- @return Core.Message#MESSAGE
|
||||
function POSITIONABLE:GetMessage( Message, Duration )
|
||||
function POSITIONABLE:GetMessage( Message, Duration, Name )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
return MESSAGE:New( Message, Duration, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")" )
|
||||
Name = Name or self:GetTypeName()
|
||||
return MESSAGE:New( Message, Duration, self:GetCallsign() .. " (" .. Name .. ")" )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -296,12 +298,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToAll( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToAll( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToAll()
|
||||
self:GetMessage( Message, Duration, Name ):ToAll()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -312,12 +315,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToCoalition( MessageCoalition )
|
||||
self:GetMessage( Message, Duration, Name ):ToCoalition( MessageCoalition )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -329,12 +333,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToRed( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToRed( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToRed()
|
||||
self:GetMessage( Message, Duration, Name ):ToRed()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -345,12 +350,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToBlue( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToBlue( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToBlue()
|
||||
self:GetMessage( Message, Duration, Name ):ToBlue()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -362,12 +368,13 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param Wrapper.Client#CLIENT Client The client object receiving the message.
|
||||
function POSITIONABLE:MessageToClient( Message, Duration, Client )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToClient( Message, Duration, Client, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToClient( Client )
|
||||
self:GetMessage( Message, Duration, Name ):ToClient( Client )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -379,13 +386,14 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message.
|
||||
function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
if DCSObject:isExist() then
|
||||
self:GetMessage( Message, Duration ):ToGroup( MessageGroup )
|
||||
self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup )
|
||||
end
|
||||
end
|
||||
|
||||
@ -397,12 +405,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:Message( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:Message( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToGroup( self )
|
||||
self:GetMessage( Message, Duration, Name ):ToGroup( self )
|
||||
end
|
||||
|
||||
return nil
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20161217_2210' )
|
||||
env.info( 'Moose Generation Timestamp: 20161218_1138' )
|
||||
local base = _G
|
||||
|
||||
Include = {}
|
||||
@ -8818,6 +8818,25 @@ function SET_UNIT:GetUnitThreatLevels()
|
||||
return UnitThreatLevels
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the SET_UNIT.
|
||||
-- @param #SET_UNIT self
|
||||
function SET_UNIT:CalculateThreatLevelA2G()
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( self:GetSet() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
return MaxThreatLevelA2G
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Returns if the @{Set} has targets having a radar (of a given type).
|
||||
-- @param #SET_UNIT self
|
||||
-- @param Dcs.DCSWrapper.Unit#Unit.RadarType RadarType
|
||||
@ -11141,6 +11160,8 @@ 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.
|
||||
|
||||
--- Send a message of the @{Task} to the Group of the Unit.
|
||||
-- @param #FSM_PROCESS self
|
||||
function FSM_PROCESS:Message( Message )
|
||||
@ -11149,6 +11170,12 @@ function FSM_PROCESS:Message( Message )
|
||||
local CC = self:GetCommandCenter()
|
||||
local TaskGroup = self.Controllable:GetGroup()
|
||||
|
||||
local PlayerName = self.Controllable:GetPlayerName() -- Only for a unit
|
||||
PlayerName = PlayerName and " (" .. PlayerName .. ")" or "" -- If PlayerName is nil, then keep it nil, otherwise add brackets.
|
||||
local Callsign = self.Controllable:GetCallsign()
|
||||
local Prefix = Callsign and " @ " .. Callsign .. PlayerName or ""
|
||||
|
||||
Message = Prefix .. ": " .. Message
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
end
|
||||
|
||||
@ -11619,6 +11646,13 @@ function IDENTIFIABLE:GetDesc()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Gets the CallSign of the IDENTIFIABLE, which is a blank by default.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string The CallSign of the IDENTIFIABLE.
|
||||
function IDENTIFIABLE:GetCallsign()
|
||||
return ''
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
@ -11909,12 +11943,14 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
-- @return Core.Message#MESSAGE
|
||||
function POSITIONABLE:GetMessage( Message, Duration )
|
||||
function POSITIONABLE:GetMessage( Message, Duration, Name )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
return MESSAGE:New( Message, Duration, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")" )
|
||||
Name = Name or self:GetTypeName()
|
||||
return MESSAGE:New( Message, Duration, self:GetCallsign() .. " (" .. Name .. ")" )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11925,12 +11961,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToAll( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToAll( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToAll()
|
||||
self:GetMessage( Message, Duration, Name ):ToAll()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11941,12 +11978,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToCoalition( MessageCoalition )
|
||||
self:GetMessage( Message, Duration, Name ):ToCoalition( MessageCoalition )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11958,12 +11996,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToRed( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToRed( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToRed()
|
||||
self:GetMessage( Message, Duration, Name ):ToRed()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11974,12 +12013,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToBlue( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToBlue( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToBlue()
|
||||
self:GetMessage( Message, Duration, Name ):ToBlue()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11991,12 +12031,13 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param Wrapper.Client#CLIENT Client The client object receiving the message.
|
||||
function POSITIONABLE:MessageToClient( Message, Duration, Client )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToClient( Message, Duration, Client, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToClient( Client )
|
||||
self:GetMessage( Message, Duration, Name ):ToClient( Client )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -12008,13 +12049,14 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message.
|
||||
function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
if DCSObject:isExist() then
|
||||
self:GetMessage( Message, Duration ):ToGroup( MessageGroup )
|
||||
self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup )
|
||||
end
|
||||
end
|
||||
|
||||
@ -12026,12 +12068,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:Message( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:Message( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToGroup( self )
|
||||
self:GetMessage( Message, Duration, Name ):ToGroup( self )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -15114,6 +15157,24 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the Group.
|
||||
-- @param #GROUP self
|
||||
function GROUP:CalculateThreatLevelA2G()
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( self:GetUnits() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
return MaxThreatLevelA2G
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- This module contains the UNIT class.
|
||||
--
|
||||
@ -25821,13 +25882,15 @@ do -- ACT_ROUTE
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE:onbeforeRoute( ProcessUnit, Event, From, To )
|
||||
self:F( { "BeforeRoute 1", self.DisplayCount, self.DisplayInterval } )
|
||||
|
||||
if ProcessUnit:IsAlive() then
|
||||
self:F( "BeforeRoute 2" )
|
||||
local HasArrived = self:onfuncHasArrived( ProcessUnit ) -- Polymorphic
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
self:T( { HasArrived = HasArrived } )
|
||||
if not HasArrived then
|
||||
self:__Report( 1 )
|
||||
self:Report()
|
||||
end
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
@ -25885,6 +25948,7 @@ do -- ACT_ROUTE_ZONE
|
||||
function ACT_ROUTE_ZONE:Init( FsmRoute )
|
||||
|
||||
self.TargetZone = FsmRoute.TargetZone
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
@ -26461,7 +26525,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
self.CommandCenterName = CommandCenterName or CommandCenterPositionable:GetName()
|
||||
self.CommandCenterCoalition = CommandCenterPositionable:GetCoalition()
|
||||
|
||||
self.Missions = setmetatable( {}, { __mode = "v" } )
|
||||
self.Missions = {}
|
||||
|
||||
self:EventOnBirth(
|
||||
--- @param #COMMANDCENTER self
|
||||
@ -26539,7 +26603,7 @@ end
|
||||
-- @return #string
|
||||
function COMMANDCENTER:GetName()
|
||||
|
||||
return self.HQName
|
||||
return self.CommandCenterName
|
||||
end
|
||||
|
||||
--- Gets the POSITIONABLE of the HQ command center.
|
||||
@ -26585,7 +26649,12 @@ end
|
||||
function COMMANDCENTER:SetMenu()
|
||||
self:F()
|
||||
|
||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "HQ" )
|
||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "Command Center (" .. self:GetName() .. ")" )
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission:RemoveMenu()
|
||||
end
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
@ -26615,9 +26684,14 @@ end
|
||||
|
||||
--- Send a CC message to a GROUP.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup )
|
||||
-- @param #string Message
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
|
||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup, Name )
|
||||
|
||||
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup )
|
||||
local Prefix = Name and "@ Group (" .. Name .. "): " or ''
|
||||
Message = Prefix .. Message
|
||||
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
@ -26865,7 +26939,6 @@ end
|
||||
|
||||
--- Sets the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
-- @param Core.Menu#MENU_COALITION CommandCenterMenu
|
||||
function MISSION:SetMenu()
|
||||
self:F()
|
||||
|
||||
@ -26875,6 +26948,17 @@ function MISSION:SetMenu()
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
function MISSION:RemoveMenu()
|
||||
self:F()
|
||||
|
||||
for _, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Task:RemoveMenu()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Gets the COMMANDCENTER.
|
||||
-- @param #MISSION self
|
||||
@ -28048,7 +28132,8 @@ function TASK:MessageToGroups( Message )
|
||||
local CC = Mission:GetCommandCenter()
|
||||
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
CC:MessageToGroup( Message, TaskGroup, TaskGroup:GetName() )
|
||||
end
|
||||
end
|
||||
|
||||
@ -28136,7 +28221,6 @@ function TASK:SetMenu()
|
||||
|
||||
self.SetGroup:Flush()
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
self:RemoveMenuForGroup( TaskGroup )
|
||||
if self:IsStatePlanned() or self:IsStateReplanned() then
|
||||
self:SetMenuForGroup( TaskGroup )
|
||||
end
|
||||
@ -28482,7 +28566,7 @@ function TASK:onenterAssigned( Event, From, To )
|
||||
|
||||
self:E("Task Assigned")
|
||||
|
||||
self:MessageToGroups( "Task " .. self:GetName() .. " has been assigned!" )
|
||||
self:MessageToGroups( "Task " .. self:GetName() .. " has been assigned to your group." )
|
||||
self:GetMission():__Start()
|
||||
end
|
||||
|
||||
@ -28601,10 +28685,12 @@ function TASK:ReportDetails()
|
||||
PlayerNames[#PlayerNames+1] = PlayerName
|
||||
end
|
||||
end
|
||||
PlayerNameText = table.concat( PlayerNames, ", " )
|
||||
local PlayerNameText = table.concat( PlayerNames, ", " )
|
||||
Report:Add( "Task " .. Name .. " - State '" .. State .. "' - Players " .. PlayerNameText )
|
||||
end
|
||||
|
||||
-- Loop each Process in the Task, and find Reporting Details.
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
@ -28994,7 +29080,6 @@ do -- DETECTION_DISPATCHER
|
||||
if Task then
|
||||
if Task:IsStatePlanned() and DetectedArea.Changed == true then
|
||||
self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
||||
Mission:RemoveTaskMenu( Task )
|
||||
Task = Mission:RemoveTask( Task )
|
||||
end
|
||||
end
|
||||
@ -29098,7 +29183,7 @@ do -- DETECTION_DISPATCHER
|
||||
end
|
||||
|
||||
-- TODO set menus using the HQ coordinator
|
||||
Mission:SetMenu()
|
||||
Mission:GetCommandCenter():SetMenu()
|
||||
|
||||
if #AreaMsg > 0 then
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
@ -29169,12 +29254,12 @@ do -- TASK_SEAD
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddAction ( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddTransition( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
Fsm:AddAction ( "Accounted", "Success", "Success" )
|
||||
Fsm:AddAction ( "Failed", "Fail", "Failed" )
|
||||
Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
@ -29243,19 +29328,19 @@ do -- TASK_A2G
|
||||
self.TargetZone = TargetZone
|
||||
self.FACUnit = FACUnit
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
local A2GUnitProcess = self:GetUnitProcess()
|
||||
|
||||
Fsm:AddProcess( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddAction ( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
A2GUnitProcess:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
A2GUnitProcess:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
A2GUnitProcess:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
A2GUnitProcess:AddTransition( "Arrived", "Update", "Updated" )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
--Fsm:AddProcess ( "Updated", "JTAC", PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) )
|
||||
Fsm:AddAction ( "Accounted", "Success", "Success" )
|
||||
Fsm:AddAction ( "Failed", "Fail", "Failed" )
|
||||
A2GUnitProcess:AddTransition( "Accounted", "Success", "Success" )
|
||||
A2GUnitProcess:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
function A2GUnitProcess:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
self:Account()
|
||||
self:Smoke()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
env.info( '*** MOOSE STATIC INCLUDE START *** ' )
|
||||
env.info( 'Moose Generation Timestamp: 20161217_2210' )
|
||||
env.info( 'Moose Generation Timestamp: 20161218_1138' )
|
||||
local base = _G
|
||||
|
||||
Include = {}
|
||||
@ -8818,6 +8818,25 @@ function SET_UNIT:GetUnitThreatLevels()
|
||||
return UnitThreatLevels
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the SET_UNIT.
|
||||
-- @param #SET_UNIT self
|
||||
function SET_UNIT:CalculateThreatLevelA2G()
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( self:GetSet() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
return MaxThreatLevelA2G
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Returns if the @{Set} has targets having a radar (of a given type).
|
||||
-- @param #SET_UNIT self
|
||||
-- @param Dcs.DCSWrapper.Unit#Unit.RadarType RadarType
|
||||
@ -11141,6 +11160,8 @@ 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.
|
||||
|
||||
--- Send a message of the @{Task} to the Group of the Unit.
|
||||
-- @param #FSM_PROCESS self
|
||||
function FSM_PROCESS:Message( Message )
|
||||
@ -11149,6 +11170,12 @@ function FSM_PROCESS:Message( Message )
|
||||
local CC = self:GetCommandCenter()
|
||||
local TaskGroup = self.Controllable:GetGroup()
|
||||
|
||||
local PlayerName = self.Controllable:GetPlayerName() -- Only for a unit
|
||||
PlayerName = PlayerName and " (" .. PlayerName .. ")" or "" -- If PlayerName is nil, then keep it nil, otherwise add brackets.
|
||||
local Callsign = self.Controllable:GetCallsign()
|
||||
local Prefix = Callsign and " @ " .. Callsign .. PlayerName or ""
|
||||
|
||||
Message = Prefix .. ": " .. Message
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
end
|
||||
|
||||
@ -11619,6 +11646,13 @@ function IDENTIFIABLE:GetDesc()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Gets the CallSign of the IDENTIFIABLE, which is a blank by default.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string The CallSign of the IDENTIFIABLE.
|
||||
function IDENTIFIABLE:GetCallsign()
|
||||
return ''
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
@ -11909,12 +11943,14 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
-- @return Core.Message#MESSAGE
|
||||
function POSITIONABLE:GetMessage( Message, Duration )
|
||||
function POSITIONABLE:GetMessage( Message, Duration, Name )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
return MESSAGE:New( Message, Duration, self:GetCallsign() .. " (" .. self:GetTypeName() .. ")" )
|
||||
Name = Name or self:GetTypeName()
|
||||
return MESSAGE:New( Message, Duration, self:GetCallsign() .. " (" .. Name .. ")" )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11925,12 +11961,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToAll( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToAll( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToAll()
|
||||
self:GetMessage( Message, Duration, Name ):ToAll()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11941,12 +11978,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToCoalition( MessageCoalition )
|
||||
self:GetMessage( Message, Duration, Name ):ToCoalition( MessageCoalition )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11958,12 +11996,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToRed( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToRed( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToRed()
|
||||
self:GetMessage( Message, Duration, Name ):ToRed()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11974,12 +12013,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:MessageToBlue( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToBlue( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToBlue()
|
||||
self:GetMessage( Message, Duration, Name ):ToBlue()
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -11991,12 +12031,13 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param Wrapper.Client#CLIENT Client The client object receiving the message.
|
||||
function POSITIONABLE:MessageToClient( Message, Duration, Client )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToClient( Message, Duration, Client, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToClient( Client )
|
||||
self:GetMessage( Message, Duration, Name ):ToClient( Client )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -12008,13 +12049,14 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
-- @param Wrapper.Group#GROUP MessageGroup The GROUP object receiving the message.
|
||||
function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToGroup( Message, Duration, MessageGroup, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
if DCSObject:isExist() then
|
||||
self:GetMessage( Message, Duration ):ToGroup( MessageGroup )
|
||||
self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup )
|
||||
end
|
||||
end
|
||||
|
||||
@ -12026,12 +12068,13 @@ end
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTypes#Duration Duration The duration of the message.
|
||||
function POSITIONABLE:Message( Message, Duration )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:Message( Message, Duration, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
self:GetMessage( Message, Duration ):ToGroup( self )
|
||||
self:GetMessage( Message, Duration, Name ):ToGroup( self )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -15114,6 +15157,24 @@ function GROUP:CopyRoute( Begin, End, Randomize, Radius )
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Calculate the maxium A2G threat level of the Group.
|
||||
-- @param #GROUP self
|
||||
function GROUP:CalculateThreatLevelA2G()
|
||||
|
||||
local MaxThreatLevelA2G = 0
|
||||
for UnitName, UnitData in pairs( self:GetUnits() ) do
|
||||
local ThreatUnit = UnitData -- Wrapper.Unit#UNIT
|
||||
local ThreatLevelA2G = ThreatUnit:GetThreatLevel()
|
||||
if ThreatLevelA2G > MaxThreatLevelA2G then
|
||||
MaxThreatLevelA2G = ThreatLevelA2G
|
||||
end
|
||||
end
|
||||
|
||||
self:T3( MaxThreatLevelA2G )
|
||||
return MaxThreatLevelA2G
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- This module contains the UNIT class.
|
||||
--
|
||||
@ -25821,13 +25882,15 @@ do -- ACT_ROUTE
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE:onbeforeRoute( ProcessUnit, Event, From, To )
|
||||
self:F( { "BeforeRoute 1", self.DisplayCount, self.DisplayInterval } )
|
||||
|
||||
if ProcessUnit:IsAlive() then
|
||||
self:F( "BeforeRoute 2" )
|
||||
local HasArrived = self:onfuncHasArrived( ProcessUnit ) -- Polymorphic
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
self:T( { HasArrived = HasArrived } )
|
||||
if not HasArrived then
|
||||
self:__Report( 1 )
|
||||
self:Report()
|
||||
end
|
||||
self.DisplayCount = 1
|
||||
else
|
||||
@ -25885,6 +25948,7 @@ do -- ACT_ROUTE_ZONE
|
||||
function ACT_ROUTE_ZONE:Init( FsmRoute )
|
||||
|
||||
self.TargetZone = FsmRoute.TargetZone
|
||||
|
||||
self.DisplayInterval = 30
|
||||
self.DisplayCount = 30
|
||||
self.DisplayMessage = true
|
||||
@ -26461,7 +26525,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
self.CommandCenterName = CommandCenterName or CommandCenterPositionable:GetName()
|
||||
self.CommandCenterCoalition = CommandCenterPositionable:GetCoalition()
|
||||
|
||||
self.Missions = setmetatable( {}, { __mode = "v" } )
|
||||
self.Missions = {}
|
||||
|
||||
self:EventOnBirth(
|
||||
--- @param #COMMANDCENTER self
|
||||
@ -26539,7 +26603,7 @@ end
|
||||
-- @return #string
|
||||
function COMMANDCENTER:GetName()
|
||||
|
||||
return self.HQName
|
||||
return self.CommandCenterName
|
||||
end
|
||||
|
||||
--- Gets the POSITIONABLE of the HQ command center.
|
||||
@ -26585,7 +26649,12 @@ end
|
||||
function COMMANDCENTER:SetMenu()
|
||||
self:F()
|
||||
|
||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "HQ" )
|
||||
self.CommandCenterMenu = self.CommandCenterMenu or MENU_COALITION:New( self.CommandCenterCoalition, "Command Center (" .. self:GetName() .. ")" )
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission:RemoveMenu()
|
||||
end
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
@ -26615,9 +26684,14 @@ end
|
||||
|
||||
--- Send a CC message to a GROUP.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup )
|
||||
-- @param #string Message
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown.
|
||||
function COMMANDCENTER:MessageToGroup( Message, TaskGroup, Name )
|
||||
|
||||
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup )
|
||||
local Prefix = Name and "@ Group (" .. Name .. "): " or ''
|
||||
Message = Prefix .. Message
|
||||
self:GetPositionable():MessageToGroup( Message , 20, TaskGroup, self:GetName() )
|
||||
|
||||
end
|
||||
|
||||
@ -26865,7 +26939,6 @@ end
|
||||
|
||||
--- Sets the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
-- @param Core.Menu#MENU_COALITION CommandCenterMenu
|
||||
function MISSION:SetMenu()
|
||||
self:F()
|
||||
|
||||
@ -26875,6 +26948,17 @@ function MISSION:SetMenu()
|
||||
end
|
||||
end
|
||||
|
||||
--- Removes the Planned Task menu.
|
||||
-- @param #MISSION self
|
||||
function MISSION:RemoveMenu()
|
||||
self:F()
|
||||
|
||||
for _, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
Task:RemoveMenu()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Gets the COMMANDCENTER.
|
||||
-- @param #MISSION self
|
||||
@ -28048,7 +28132,8 @@ function TASK:MessageToGroups( Message )
|
||||
local CC = Mission:GetCommandCenter()
|
||||
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
CC:MessageToGroup( Message, TaskGroup, TaskGroup:GetName() )
|
||||
end
|
||||
end
|
||||
|
||||
@ -28136,7 +28221,6 @@ function TASK:SetMenu()
|
||||
|
||||
self.SetGroup:Flush()
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
self:RemoveMenuForGroup( TaskGroup )
|
||||
if self:IsStatePlanned() or self:IsStateReplanned() then
|
||||
self:SetMenuForGroup( TaskGroup )
|
||||
end
|
||||
@ -28482,7 +28566,7 @@ function TASK:onenterAssigned( Event, From, To )
|
||||
|
||||
self:E("Task Assigned")
|
||||
|
||||
self:MessageToGroups( "Task " .. self:GetName() .. " has been assigned!" )
|
||||
self:MessageToGroups( "Task " .. self:GetName() .. " has been assigned to your group." )
|
||||
self:GetMission():__Start()
|
||||
end
|
||||
|
||||
@ -28601,10 +28685,12 @@ function TASK:ReportDetails()
|
||||
PlayerNames[#PlayerNames+1] = PlayerName
|
||||
end
|
||||
end
|
||||
PlayerNameText = table.concat( PlayerNames, ", " )
|
||||
local PlayerNameText = table.concat( PlayerNames, ", " )
|
||||
Report:Add( "Task " .. Name .. " - State '" .. State .. "' - Players " .. PlayerNameText )
|
||||
end
|
||||
|
||||
-- Loop each Process in the Task, and find Reporting Details.
|
||||
|
||||
return Report:Text()
|
||||
end
|
||||
|
||||
@ -28994,7 +29080,6 @@ do -- DETECTION_DISPATCHER
|
||||
if Task then
|
||||
if Task:IsStatePlanned() and DetectedArea.Changed == true then
|
||||
self:E( "Removing Tasking: " .. Task:GetTaskName() )
|
||||
Mission:RemoveTaskMenu( Task )
|
||||
Task = Mission:RemoveTask( Task )
|
||||
end
|
||||
end
|
||||
@ -29098,7 +29183,7 @@ do -- DETECTION_DISPATCHER
|
||||
end
|
||||
|
||||
-- TODO set menus using the HQ coordinator
|
||||
Mission:SetMenu()
|
||||
Mission:GetCommandCenter():SetMenu()
|
||||
|
||||
if #AreaMsg > 0 then
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
@ -29169,12 +29254,12 @@ do -- TASK_SEAD
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddAction ( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddTransition( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "SEAD" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
Fsm:AddAction ( "Accounted", "Success", "Success" )
|
||||
Fsm:AddAction ( "Failed", "Fail", "Failed" )
|
||||
Fsm:AddTransition( "Accounted", "Success", "Success" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
@ -29243,19 +29328,19 @@ do -- TASK_A2G
|
||||
self.TargetZone = TargetZone
|
||||
self.FACUnit = FACUnit
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
local A2GUnitProcess = self:GetUnitProcess()
|
||||
|
||||
Fsm:AddProcess( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
Fsm:AddProcess( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
Fsm:AddAction ( "Rejected", "Eject", "Planned" )
|
||||
Fsm:AddAction ( "Arrived", "Update", "Updated" )
|
||||
Fsm:AddProcess( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
|
||||
Fsm:AddProcess( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
A2GUnitProcess:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( "Attack the Area" ), { Assigned = "Route", Rejected = "Eject" } )
|
||||
A2GUnitProcess:AddProcess ( "Assigned", "Route", ACT_ROUTE_ZONE:New( self.TargetZone ), { Arrived = "Update" } )
|
||||
A2GUnitProcess:AddTransition( "Rejected", "Eject", "Planned" )
|
||||
A2GUnitProcess:AddTransition( "Arrived", "Update", "Updated" )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Account", ACT_ACCOUNT_DEADS:New( self.TargetSetUnit, "Attack" ), { Accounted = "Success" } )
|
||||
A2GUnitProcess:AddProcess ( "Updated", "Smoke", ACT_ASSIST_SMOKE_TARGETS_ZONE:New( self.TargetSetUnit, self.TargetZone ) )
|
||||
--Fsm:AddProcess ( "Updated", "JTAC", PROCESS_JTAC:New( self, TaskUnit, self.TargetSetUnit, self.FACUnit ) )
|
||||
Fsm:AddAction ( "Accounted", "Success", "Success" )
|
||||
Fsm:AddAction ( "Failed", "Fail", "Failed" )
|
||||
A2GUnitProcess:AddTransition( "Accounted", "Success", "Success" )
|
||||
A2GUnitProcess:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
function Fsm:onenterUpdated( TaskUnit )
|
||||
function A2GUnitProcess:onenterUpdated( TaskUnit )
|
||||
self:E( { self } )
|
||||
self:Account()
|
||||
self:Smoke()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,7 +1,7 @@
|
||||
|
||||
local HQ = GROUP:FindByName( "HQ", "Bravo HQ" )
|
||||
|
||||
local CommandCenter = COMMANDCENTER:New( HQ )
|
||||
local CommandCenter = COMMANDCENTER:New( HQ, "Lima" )
|
||||
|
||||
local Scoring = SCORING:New( "Detect Demo" )
|
||||
|
||||
|
||||
Binary file not shown.
@ -110,7 +110,11 @@ local TargetZone = ZONE:New( "Target Zone" )
|
||||
-- 2. The set of groups of planes that pilots can join.
|
||||
-- 3. The name of the Task... This can be any name, and will be provided when the Pilot joins the task.
|
||||
-- 4. A type of the Task. When Tasks are in state Planned, then a menu can be provided that group the task based on this given type.
|
||||
local SEADTask = TASK:New( Mission, SEADSet, "SEAD Radars Vector 1", "SEAD" ) -- Tasking.Task#TASK
|
||||
local SEADTask = TASK:New(
|
||||
Mission,
|
||||
SEADSet,
|
||||
"SEAD Radars Vector 1",
|
||||
"SEAD" ) -- Tasking.Task#TASK
|
||||
|
||||
-- This is now an important part of the Task process definition.
|
||||
-- Each TASK contains a "Process Template".
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user