diff --git a/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua index fa6177178..b9552e00b 100644 --- a/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2G_Dispatcher.lua @@ -4043,6 +4043,107 @@ do -- AI_A2G_DISPATCHER return ShortestDistance end + + --- Shows the tactical display. + -- @param #AI_A2G_DISPATCHER self + function AI_A2G_DISPATCHER:ShowTacticalDisplay( Detection ) + + local AreaMsg = {} + local TaskMsg = {} + local ChangeMsg = {} + + local TaskReport = REPORT:New() + + local DefenseTotal = 0 + + local Report = REPORT:New( "\nTactical Overview" ) + + local DefenderGroupCount = 0 + local DefendersTotal = 0 + + -- Now that all obsolete tasks are removed, loop through the detected targets. + --for DetectedItemID, DetectedItem in pairs( Detection:GetDetectedItems() ) do + for DetectedItemID, DetectedItem in UTILS.spairs( Detection:GetDetectedItems(), function( t, a, b ) return self:Order(t[a]) < self:Order(t[b]) end ) do + + if not self.Detection:IsDetectedItemLocked( DetectedItem ) == true then + local DetectedItem = DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem + local DetectedSet = DetectedItem.Set -- Core.Set#SET_UNIT + local DetectedCount = DetectedSet:Count() + local DetectedZone = DetectedItem.Zone + + self:F( { "Target ID", DetectedItem.ItemID } ) + + self:F( { DefenseLimit = self.DefenseLimit, DefenseTotal = DefenseTotal } ) + DetectedSet:Flush( self ) + + local DetectedID = DetectedItem.ID + local DetectionIndex = DetectedItem.Index + local DetectedItemChanged = DetectedItem.Changed + + -- Show tactical situation + local ThreatLevel = DetectedItem.Set:CalculateThreatLevelA2G() + Report:Add( string.format( " - %1s%s ( %4s ): ( #%d - %4s ) %s" , ( DetectedItem.IsDetected == true ) and "!" or " ", DetectedItem.ItemID, DetectedItem.Index, DetectedItem.Set:Count(), DetectedItem.Type or " --- ", string.rep( "■", ThreatLevel ) ) ) + for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do + local Defender = Defender -- Wrapper.Group#GROUP + if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then + if Defender:IsAlive() then + DefenderGroupCount = DefenderGroupCount + 1 + local Fuel = Defender:GetFuelMin() * 100 + local Damage = Defender:GetLife() / Defender:GetLife0() * 100 + Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", + Defender:GetName(), + DefenderTask.Type, + DefenderTask.Fsm:GetState(), + Defender:GetSize(), + Fuel, + Damage, + Defender:HasTask() == true and "Executing" or "Idle" ) ) + end + end + end + end + end + + Report:Add( "\n - No Targets:") + local TaskCount = 0 + for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do + TaskCount = TaskCount + 1 + local Defender = Defender -- Wrapper.Group#GROUP + if not DefenderTask.Target then + if Defender:IsAlive() then + local DefenderHasTask = Defender:HasTask() + local Fuel = Defender:GetFuelMin() * 100 + local Damage = Defender:GetLife() / Defender:GetLife0() * 100 + DefenderGroupCount = DefenderGroupCount + 1 + Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", + Defender:GetName(), + DefenderTask.Type, + DefenderTask.Fsm:GetState(), + Defender:GetSize(), + Fuel, + Damage, + Defender:HasTask() == true and "Executing" or "Idle" ) ) + end + end + end + Report:Add( string.format( "\n - %d Tasks - %d Defender Groups", TaskCount, DefenderGroupCount ) ) + + Report:Add( string.format( "\n - %d Queued Aircraft Launches", #self.DefenseQueue ) ) + for DefenseQueueID, DefenseQueueItem in pairs( self.DefenseQueue ) do + local DefenseQueueItem = DefenseQueueItem -- #AI_A2G_DISPATCHER.DefenseQueueItem + Report:Add( string.format( " - %s - %s", DefenseQueueItem.SquadronName, DefenseQueueItem.DefenderSquadron.TakeoffTime, DefenseQueueItem.DefenderSquadron.TakeoffInterval) ) + + end + + Report:Add( string.format( "\n - Squadron Resources: ", #self.DefenseQueue ) ) + for DefenderSquadronName, DefenderSquadron in pairs( self.DefenderSquadrons ) do + Report:Add( string.format( " - %s - %d", DefenderSquadronName, DefenderSquadron.ResourceCount and DefenderSquadron.ResourceCount or "n/a" ) ) + end + + self:F( Report:Text( "\n" ) ) + trigger.action.outText( Report:Text( "\n" ), 25 ) + + end --- Assigns A2G AI Tasks in relation to the detected items. -- @param #AI_A2G_DISPATCHER self diff --git a/Moose Development/Moose/Tasking/TaskInfo.lua b/Moose Development/Moose/Tasking/TaskInfo.lua index 8f2d6231a..54c59410d 100644 --- a/Moose Development/Moose/Tasking/TaskInfo.lua +++ b/Moose Development/Moose/Tasking/TaskInfo.lua @@ -52,7 +52,7 @@ end --- Add taskinfo. -- @param #TASKINFO self --- @param #string The info key. +-- @param #string Key The info key. -- @param Data The data of the info. -- @param #number Order The display order, which is a number from 0 to 100. -- @param #TASKINFO.Detail Detail The detail Level. diff --git a/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua b/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua index 74dff588e..c7c3227da 100644 --- a/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua +++ b/Moose Development/Moose/Tasking/Task_Capture_Dispatcher.lua @@ -194,6 +194,25 @@ do -- TASK_CAPTURE_DISPATCHER end + --- Link a task capture dispatcher from the other coalition to understand its plan for defenses. + -- This is used for the tactical overview, so the players also know the zones attacked by the other coalition! + -- @param #TASK_CAPTURE_DISPATCHER self + -- @param #TASK_CAPTURE_DISPATCHER DefenseTaskCaptureDispatcher + function TASK_CAPTURE_DISPATCHER:SetDefenseTaskCaptureDispatcher( DefenseTaskCaptureDispatcher ) + + self.DefenseTaskCaptureDispatcher = DefenseTaskCaptureDispatcher + end + + + --- Get the linked task capture dispatcher from the other coalition to understand its plan for defenses. + -- This is used for the tactical overview, so the players also know the zones attacked by the other coalition! + -- @param #TASK_CAPTURE_DISPATCHER self + -- @return #TASK_CAPTURE_DISPATCHER + function TASK_CAPTURE_DISPATCHER:GetDefenseTaskCaptureDispatcher() + + return self.DefenseTaskCaptureDispatcher + end + --- Add a capture zone task. -- @param #TASK_CAPTURE_DISPATCHER self @@ -274,6 +293,9 @@ do -- TASK_CAPTURE_DISPATCHER CaptureZone.Task.TaskPrefix = CaptureZone.TaskPrefix -- We keep the TaskPrefix for further reference! Mission:AddTask( CaptureZone.Task ) TaskReport:Add( TaskName ) + + -- Link the Task Dispatcher to the capture zone task, because it is used on the UpdateTaskInfo. + CaptureZone.Task:SetDispatcher( self ) CaptureZone.Task:UpdateTaskInfo() function CaptureZone.Task.OnEnterAssigned( Task, From, Event, To ) diff --git a/Moose Development/Moose/Tasking/Task_Capture_Zone.lua b/Moose Development/Moose/Tasking/Task_Capture_Zone.lua index 9ab0f35c7..73032a60d 100644 --- a/Moose Development/Moose/Tasking/Task_Capture_Zone.lua +++ b/Moose Development/Moose/Tasking/Task_Capture_Zone.lua @@ -228,11 +228,28 @@ do -- TASK_CAPTURE_ZONE local ZoneCoordinate = self.ZoneGoal:GetZone():GetCoordinate() self.TaskInfo:AddTaskName( 0, "MSOD", Persist ) self.TaskInfo:AddCoordinate( ZoneCoordinate, 1, "SOD", Persist ) - self.TaskInfo:AddText( "Zone Name", self.ZoneGoal:GetZoneName(), 10, "MOD", Persist ) - self.TaskInfo:AddText( "Zone Coalition", self.ZoneGoal:GetCoalitionName(), 11, "MOD", Persist ) +-- self.TaskInfo:AddText( "Zone Name", self.ZoneGoal:GetZoneName(), 10, "MOD", Persist ) +-- self.TaskInfo:AddText( "Zone Coalition", self.ZoneGoal:GetCoalitionName(), 11, "MOD", Persist ) local SetUnit = self.ZoneGoal.Zone:GetScannedSetUnit() local ThreatLevel, ThreatText = SetUnit:CalculateThreatLevelA2G() self.TaskInfo:AddThreat( ThreatText, ThreatLevel, 20, "MOD", Persist ) + + if self.Dispatcher then + local DefenseTaskCaptureDispatcher = self.Dispatcher:GetDefenseTaskCaptureDispatcher() -- Tasking.Task_Capture_Dispatcher#TASK_CAPTURE_DISPATCHER + + if DefenseTaskCaptureDispatcher then + -- Loop through all zones of the Defenses, and check which zone has an assigned task! + for TaskName, CaptureZone in pairs( DefenseTaskCaptureDispatcher.Zones or {} ) do + local Task = CaptureZone.Task -- Tasking.Task_Capture_Zone#TASK_CAPTURE_ZONE + if Task then + if Task:IsStateAssigned() then + self.TaskInfo:AddInfo( "Defense", Task.ZoneGoal:GetName() .. ", " .. Task.ZoneGoal:GetZone():GetCoordinate(), 30, "MOD", Persist ) + end + end + end + end + end + end