diff --git a/Moose Development/Moose/Core/Report.lua b/Moose Development/Moose/Core/Report.lua new file mode 100644 index 000000000..653e1f696 --- /dev/null +++ b/Moose Development/Moose/Core/Report.lua @@ -0,0 +1,86 @@ +--- The REPORT class +-- @type REPORT +-- @extends Core.Base#BASE +REPORT = { + ClassName = "REPORT", + Title = "", +} + +--- Create a new REPORT. +-- @param #REPORT self +-- @param #string Title +-- @return #REPORT +function REPORT:New( Title ) + + local self = BASE:Inherit( self, BASE:New() ) -- #REPORT + + self.Report = {} + + self:SetTitle( Title or "" ) + self:SetIndent( 3 ) + + return self +end + +--- Has the REPORT Text? +-- @param #REPORT self +-- @return #boolean +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 + 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 + return self +end + +--- Add a new line to a REPORT. +-- @param #REPORT self +-- @param #string Text +-- @return #REPORT +function REPORT:AddIndent( Text ) --R2.1 + self.Report[#self.Report+1] = 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. +-- @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 "" + return ReportText +end + +--- Sets the title of the report. +-- @param #REPORT self +-- @param #string Title The title of the report. +-- @return #REPORT +function REPORT:SetTitle( Title ) + self.Title = Title + return self +end + +--- Gets the amount of report items contained in the report. +-- @param #REPORT self +-- @return #number Returns the number of report items contained in the report. 0 is returned if no report items are contained in the report. The title is not counted for. +function REPORT:GetCount() + return #self.Report +end diff --git a/Moose Development/Moose/Functional/Designate.lua b/Moose Development/Moose/Functional/Designate.lua index e38afb988..77ac3f147 100644 --- a/Moose Development/Moose/Functional/Designate.lua +++ b/Moose Development/Moose/Functional/Designate.lua @@ -70,10 +70,14 @@ do -- DESIGNATE -- The RecceSet is continuously detecting for potential Targets, executing its task as part of the DetectionObject. -- Once Targets have been detected, the DesignateObject will trigger the **Detect Event**. -- + -- In order to prevent an overflow in the DesignateObject of detected targets, there is a maximum + -- amount of DetectionItems that can be put in **scope** of the DesignateObject. + -- We call this the **MaximumDesignations** term. + -- -- As part of the Detect Event, the DetectionItems list is used by the DesignateObject to provide the Players with: -- -- * The RecceGroups are reporting to each AttackGroup, sending **Messages** containing the Threat Level and the TargetSet composition. - -- * **Menu options** are created and updated for each AttackGroup, containing the Threat Level and the TargetSet composition. + -- * **Menu options** are created and updated for each AttackGroup, containing the Detection ID and the Coordinates. -- -- A Player can then select an action from the Designate Menu. -- @@ -109,7 +113,7 @@ do -- DESIGNATE -- -- ### 2.1 DESIGNATE States -- - -- * **Designating** ( Group ): The process is not started yet. + -- * **Designating** ( Group ): The designation process. -- -- ### 2.2 DESIGNATE Events -- @@ -119,9 +123,17 @@ do -- DESIGNATE -- * **@{#DESIGNATE.Smoke}**: Smoke the targets with the specified Index. -- * **@{#DESIGNATE.Status}**: Report designation status. -- - -- ## 3. Laser codes + -- ## 3. Maximum Designations -- - -- ### 3.1 Set possible laser codes + -- In order to prevent an overflow of designations due to many Detected Targets, there is a + -- Maximum Designations scope that is set in the DesignationObject. + -- + -- The method @{#DESIGNATE.SetMaximumDesignations}() will put a limit on the amount of designations put in scope of the DesignationObject. + -- Using the menu system, the player can "forget" a designation, so that gradually a new designation can be put in scope when detected. + -- + -- ## 4. Laser codes + -- + -- ### 4.1 Set possible laser codes -- -- An array of laser codes can be provided, that will be used by the DESIGNATE when lasing. -- The laser code is communicated by the Recce when it is lasing a larget. @@ -139,11 +151,11 @@ do -- DESIGNATE -- -- The above sets a collection of possible laser codes that can be assigned. **Note the { } notation!** -- - -- ### 3.2 Auto generate laser codes + -- ### 4.2 Auto generate laser codes -- -- Use the method @{#DESIGNATE.GenerateLaserCodes}() to generate all possible laser codes. Logic implemented and advised by Ciribob! -- - -- ## 4. Autolase to automatically lase detected targets. + -- ## 5. Autolase to automatically lase detected targets. -- -- DetectionItems can be auto lased once detected by Recces. As such, there is almost no action required from the Players using the Designate Menu. -- The **auto lase** function can be activated through the Designation Menu. @@ -154,7 +166,7 @@ do -- DESIGNATE -- -- Activate the auto lasing. -- - -- ## 5. Target prioritization on threat level + -- ## 6. Target prioritization on threat level -- -- Targets can be detected of different types in one DetectionItem. Depending on the type of the Target, a different threat level applies in an Air to Ground combat context. -- SAMs are of a higher threat than normal tanks. So, if the Target type was recognized, the Recces will select those targets that form the biggest threat first, @@ -376,12 +388,15 @@ do -- DESIGNATE self:SetAutoLase( false ) -- set self.Autolase self:SetThreatLevelPrioritization( false ) -- self.ThreatLevelPrioritization, default is threat level priorization off + self:SetMaximumDesignations( 5 ) -- Sets the maximum designations. The default is 5 designations. self.LaserCodesUsed = {} self.Detection:__Start( 2 ) + self:__Detect( -15 ) + return self end @@ -405,6 +420,16 @@ do -- DESIGNATE end + --- Set the maximum amount of designations. + -- @param #DESIGNATE self + -- @param #number MaximumDesignations + -- @return #DESIGNATE + function DESIGNATE:SetMaximumDesignations( MaximumDesignations ) + self.MaximumDesignations = MaximumDesignations + return self + end + + --- Set an array of possible laser codes. -- Each new lase will select a code from this table. -- @param #DESIGNATE self @@ -490,7 +515,7 @@ do -- DESIGNATE CC:MessageToSetGroup( "Auto Lase " .. AutoLaseOnOff .. ".", 15, self.AttackSet ) end - self:ActivateAutoLase() + self:CoordinateLase() self:SetDesignateMenu() return self @@ -525,15 +550,93 @@ do -- DESIGNATE -- @return #DESIGNATE function DESIGNATE:onafterDetect() - self:__Detect( -60 ) + self:__Detect( -math.random( 60 ) ) - self:ActivateAutoLase() + self:DesignationScope() + self:CoordinateLase() self:SendStatus() self:SetDesignateMenu() return self end + + --- Adapt the designation scope according the detected items. + -- @param #DESIGNATE self + -- @return #DESIGNATE + function DESIGNATE:DesignationScope() + + local DetectedItems = self.Detection:GetDetectedItems() + + local DetectedItemCount = 0 + + for DesignateIndex, Designating in pairs( self.Designating ) do + local DetectedItem = DetectedItems[DesignateIndex] + if DetectedItem then + -- Check LOS... + local IsDetected = self.Detection:IsDetectedItemDetected( DetectedItem ) + self:F({IsDetected = IsDetected, DetectedItem }) + if IsDetected == false then + self:F("Removing") + -- This Detection is obsolete, remove from the designate scope + self.Designating[DesignateIndex] = nil + self.AttackSet:ForEachGroup( + function( AttackGroup ) + local DetectionText = self.Detection:DetectedItemReportSummary( DesignateIndex, AttackGroup ):Text( ", " ) + self.CC:GetPositionable():MessageToGroup( "Targets out of LOS\n" .. DetectionText, 10, AttackGroup, "Designate" ) + end + ) + else + DetectedItemCount = DetectedItemCount + 1 + end + else + -- This Detection is obsolete, remove from the designate scope + self.Designating[DesignateIndex] = nil + end + end + + if DetectedItemCount < 5 then + for DesignateIndex, DetectedItem in pairs( DetectedItems ) do + local IsDetected = self.Detection:IsDetectedItemDetected( DetectedItem ) + if IsDetected == true then + if self.Designating[DesignateIndex] == nil then + -- ok, we added one item to the designate scope. + self.AttackSet:ForEachGroup( + function( AttackGroup ) + local DetectionText = self.Detection:DetectedItemReportSummary( DesignateIndex, AttackGroup ):Text( ", " ) + self.CC:GetPositionable():MessageToGroup( "Targets detected at \n" .. DetectionText, 10, AttackGroup, "Designate" ) + end + ) + self.Designating[DesignateIndex] = "" + break + end + end + end + end + + return self + end + + --- Coordinates the Auto Lase. + -- @param #DESIGNATE self + -- @return #DESIGNATE + function DESIGNATE:CoordinateLase() + + local DetectedItems = self.Detection:GetDetectedItems() + + for DesignateIndex, Designating in pairs( self.Designating ) do + local DetectedItem = DetectedItems[DesignateIndex] + if DetectedItem then + if self.AutoLase then + self:LaseOn( DesignateIndex, self.LaseDuration ) + end + end + end + + return self + end + + --- Sends the status to the Attack Groups. -- @param #DESIGNATE self -- @param Wrapper.Group#GROUP AttackGroup @@ -550,20 +653,23 @@ do -- DESIGNATE if self.FlashStatusMenu[AttackGroup] or ( MenuAttackGroup and ( AttackGroup:GetName() == MenuAttackGroup:GetName() ) ) then - local DetectedReport = REPORT:New( "Targets designated:\n" ) + local DetectedReport = REPORT:New( "Detected Targets: \n" ) local DetectedItems = self.Detection:GetDetectedItems() - for Index, DetectedItemData in pairs( DetectedItems ) do - - local Report = self.Detection:DetectedItemReportSummary( Index, AttackGroup ) - DetectedReport:Add(" - " .. Report) + for DesignateIndex, Designating in pairs( self.Designating ) do + local DetectedItem = DetectedItems[DesignateIndex] + if DetectedItem then + local Report = self.Detection:DetectedItemReportSummary( DesignateIndex, AttackGroup ):Text( ", " ) + DetectedReport:Add( " - " .. Report ) + DetectedReport:Add( string.rep( "-", 140 ) ) + end end local CC = self.CC:GetPositionable() CC:MessageToGroup( DetectedReport:Text( "\n" ), Duration, AttackGroup ) - local DesignationReport = REPORT:New( "Targets marked:\n" ) + local DesignationReport = REPORT:New( "Marking Targets:\n" ) self.RecceSet:ForEachGroup( function( RecceGroup ) @@ -585,40 +691,6 @@ do -- DESIGNATE return self end - --- Coordinates the Auto Lase. - -- @param #DESIGNATE self - -- @return #DESIGNATE - function DESIGNATE:ActivateAutoLase() - - self.AttackSet:Flush() - - self.AttackSet:ForEachGroup( - - --- @param Wrapper.Group#GROUP GroupReport - function( AttackGroup ) - - local DetectedItems = self.Detection:GetDetectedItems() - - local DetectedItemCount = 0 - - for Index, DetectedItemData in pairs( DetectedItems ) do - if self.AutoLase then - if not self.Designating[Index] then - self:LaseOn( Index, self.LaseDuration ) - end - end - - DetectedItemCount = DetectedItemCount + 1 - if DetectedItemCount >= 5 then - break - end - end - end - ) - - return self - end - --- Sets the Designate Menu. -- @param #DESIGNATE self -- @return #DESIGNATE @@ -665,38 +737,43 @@ do -- DESIGNATE local DetectedItemCount = 0 - for Index, DetectedItemData in pairs( DetectedItems ) do + for DesignateIndex, Designating in pairs( self.Designating ) do + + local DetectedItem = DetectedItems[DesignateIndex] + + if DetectedItem then - local Report = self.Detection:DetectedItemMenu( Index, AttackGroup ) - - if not self.Designating[Index] then - local DetectedMenu = MENU_GROUP:New( AttackGroup, Report, MenuDesignate ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Lase target 60 secs", DetectedMenu, self.MenuLaseOn, self, Index, 60 ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Lase target 120 secs", DetectedMenu, self.MenuLaseOn, self, Index, 120 ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Smoke red", DetectedMenu, self.MenuSmoke, self, Index, SMOKECOLOR.Red ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Smoke blue", DetectedMenu, self.MenuSmoke, self, Index, SMOKECOLOR.Blue ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Smoke green", DetectedMenu, self.MenuSmoke, self, Index, SMOKECOLOR.Green ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Smoke white", DetectedMenu, self.MenuSmoke, self, Index, SMOKECOLOR.White ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Smoke orange", DetectedMenu, self.MenuSmoke, self, Index, SMOKECOLOR.Orange ):SetTime( MenuTime ):SetTag( "Designate" ) - MENU_GROUP_COMMAND:New( AttackGroup, "Illuminate", DetectedMenu, self.MenuIlluminate, self, Index ):SetTime( MenuTime ):SetTag( "Designate" ) - else - if self.Designating[Index] == "Laser" then - Report = "Lasing " .. Report - elseif self.Designating[Index] == "Smoke" then - Report = "Smoking " .. Report - elseif self.Designating[Index] == "Illuminate" then - Report = "Illuminating " .. Report - end - local DetectedMenu = MENU_GROUP:New( AttackGroup, Report, MenuDesignate ):SetTime( MenuTime ):SetTag( "Designate" ) - if self.Designating[Index] == "Laser" then - MENU_GROUP_COMMAND:New( AttackGroup, "Stop lasing", DetectedMenu, self.MenuLaseOff, self, Index ):SetTime( MenuTime ):SetTag( "Designate" ) + local Coord = self.Detection:GetDetectedItemCoordinate( DesignateIndex ) + local ID = self.Detection:GetDetectedItemID( DesignateIndex ) + local MenuText = ID .. ", " .. Coord:ToString( AttackGroup ) + + if Designating == "" then + MenuText = "(-) " .. MenuText + local DetectedMenu = MENU_GROUP:New( AttackGroup, MenuText, MenuDesignate ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Search other target", DetectedMenu, self.MenuForget, self, DesignateIndex ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Lase target 60 secs", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 60 ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Lase target 120 secs", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 120 ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Smoke red", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Red ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Smoke blue", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Blue ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Smoke green", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Green ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Smoke white", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.White ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Smoke orange", DetectedMenu, self.MenuSmoke, self, DesignateIndex, SMOKECOLOR.Orange ):SetTime( MenuTime ):SetTag( "Designate" ) + MENU_GROUP_COMMAND:New( AttackGroup, "Illuminate", DetectedMenu, self.MenuIlluminate, self, DesignateIndex ):SetTime( MenuTime ):SetTag( "Designate" ) else + if Designating == "Laser" then + MenuText = "(L) " .. MenuText + elseif Designating == "Smoke" then + MenuText = "(S) " .. MenuText + elseif Designating == "Illuminate" then + MenuText = "(I) " .. MenuText + end + local DetectedMenu = MENU_GROUP:New( AttackGroup, MenuText, MenuDesignate ):SetTime( MenuTime ):SetTag( "Designate" ) + if Designating == "Laser" then + MENU_GROUP_COMMAND:New( AttackGroup, "Stop lasing", DetectedMenu, self.MenuLaseOff, self, DesignateIndex ):SetTime( MenuTime ):SetTag( "Designate" ) + else + end end end - DetectedItemCount = DetectedItemCount + 1 - if DetectedItemCount >= 5 then - break - end end MenuDesignate:Remove( MenuTime, "Designate" ) end @@ -725,6 +802,16 @@ do -- DESIGNATE end + --- + -- @param #DESIGNATE self + function DESIGNATE:MenuForget( Index ) + + self:E("Forget") + + self.Designating[Index] = nil + self:SetDesignateMenu() + end + --- -- @param #DESIGNATE self function DESIGNATE:MenuAutoLase( AutoLase ) @@ -741,7 +828,7 @@ do -- DESIGNATE self:E("Designate through Smoke") self.Designating[Index] = "Smoke" - self:__Smoke( 1, Index, Color ) + self:Smoke( Index, Color ) end --- @@ -762,6 +849,7 @@ do -- DESIGNATE self:E("Designate through Lase") self:__LaseOn( 1, Index, Duration ) + self:SetDesignateMenu() end --- @@ -770,8 +858,9 @@ do -- DESIGNATE self:E("Lasing off") - self.Designating[Index] = nil + self.Designating[Index] = "" self:__LaseOff( 1, Index ) + self:SetDesignateMenu() end --- @@ -858,7 +947,7 @@ do -- DESIGNATE end ) - self:__Lasing( 15, Index, Duration ) + self:__Lasing( 30, Index, Duration ) self:SetDesignateMenu() @@ -910,10 +999,10 @@ do -- DESIGNATE local RecceUnit = RecceGroup:GetUnit( 1 ) if RecceUnit then RecceUnit:MessageToSetGroup( "Smoking " .. SmokeUnit:GetTypeName() .. ".", 5, self.AttackSet ) - SCHEDULER:New( self, + SCHEDULER:New( nil, function() if SmokeUnit:IsAlive() then - SmokeUnit:Smoke( Color, 150 ) + SmokeUnit:Smoke( Color, 50 ) end self:Done( Index ) end, {}, math.random( 5, 20 ) diff --git a/Moose Development/Moose/Functional/Detection.lua b/Moose Development/Moose/Functional/Detection.lua index 64c62604f..0ed0ecaa0 100644 --- a/Moose Development/Moose/Functional/Detection.lua +++ b/Moose Development/Moose/Functional/Detection.lua @@ -692,6 +692,8 @@ do -- DETECTION_BASE self.DetectedObjects[DetectedObjectName].Distance = Distance self.DetectedObjects[DetectedObjectName].DetectionTimeStamp = DetectionTimeStamp + self:F( { DetectedObject = self.DetectedObjects[DetectedObjectName] } ) + local DetectedUnit = UNIT:FindByName( DetectedObjectName ) DetectedUnits[DetectedObjectName] = DetectedUnit @@ -1493,6 +1495,7 @@ do -- DETECTION_BASE for UnitName, UnitData in pairs( DetectedItem.Set:GetSet() ) do local DetectedObject = self.DetectedObjects[UnitName] + self:F({UnitName = UnitName, IsDetected = DetectedObject.IsDetected}) if DetectedObject.IsDetected then IsDetected = true break @@ -1514,37 +1517,6 @@ do -- DETECTION_BASE return DetectedItem.IsDetected end - do -- Coordinates - - --- Get the COORDINATE of a detection item using a given numeric index. - -- @param #DETECTION_BASE self - -- @param #number Index - -- @return Core.Point#COORDINATE - function DETECTION_BASE:GetDetectedItemCoordinate( Index ) - - -- If the Zone is set, return the coordinate of the Zone. - local DetectedItemSet = self:GetDetectedSet( Index ) - local FirstUnit = DetectedItemSet:GetFirst() - - local DetectedZone = self:GetDetectedItemZone( Index ) - if DetectedZone then - local Coordinate = DetectedZone:GetPointVec2() - Coordinate:SetHeading(FirstUnit:GetHeading()) - Coordinate:SetAlt( FirstUnit:GetAltitude() ) - return Coordinate - end - - -- If no Zone is set, return the coordinate of the first unit in the Set - if FirstUnit then - local Coordinate = FirstUnit:GetPointVec3() - FirstUnit:SetHeading(FirstUnit:GetHeading()) - return Coordinate - end - - return nil - end - - end do -- Zones @@ -1566,6 +1538,32 @@ do -- DETECTION_BASE end + --- Get the detected item coordinate. + -- @param #DETECTION_BASE self + -- @param Index + -- @return Core.Point#COORDINATE + function DETECTION_BASE:GetDetectedItemCoordinate( Index ) + self:F( { Index = Index } ) + return nil + end + + + --- Has the detected item LOS (Line Of Sight) with one of the Recce? + -- @param #DETECTION_BASE self + -- @param Index + -- @return #boolean true is LOS, false if no LOS. + function DETECTION_BASE:HasDetectedItemLOS( Index ) + self:F( { Index = Index } ) + + local DetectedItem = self:GetDetectedItem( Index ) + if DetectedItem then + return DetectedItem.LOS + end + + return nil + end + + --- Menu of a detected item using a given numeric index. -- @param #DETECTION_BASE self -- @param Index @@ -1581,7 +1579,7 @@ do -- DETECTION_BASE -- @param Index -- @param Wrapper.Group#GROUP AttackGroup The group to generate the report for. -- @param Core.Settings#SETTINGS Settings Message formatting settings to use. - -- @return #string + -- @return Core.Report#REPORT function DETECTION_BASE:DetectedItemReportSummary( Index, AttackGroup, Settings ) self:F( Index ) return nil @@ -1657,6 +1655,27 @@ do -- DETECTION_UNITS return self end + --- Get the detected item coordinate. + -- @param #DETECTION_UNITS self + -- @param Index + -- @return Core.Point#COORDINATE + function DETECTION_UNITS:GetDetectedItemCoordinate( Index ) + self:F( { Index = Index } ) + + local DetectedItem = self:GetDetectedItem( Index ) + local DetectedSet = self:GetDetectedSet( Index ) + + if DetectedSet then + local DetectedItemUnit = DetectedSet:GetFirst() -- Wrapper.Unit#UNIT + if DetectedItemUnit and DetectedItemUnit:IsAlive() then + local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate() + DetectedItemCoordinate:SetHeading( DetectedItemUnit:GetHeading() ) + return DetectedItemCoordinate + end + end + end + + --- Make text documenting the changes of the detected zone. -- @param #DETECTION_UNITS self -- @param #DETECTION_UNITS.DetectedItem DetectedItem @@ -1827,7 +1846,7 @@ do -- DETECTION_UNITS -- @param Index -- @param Wrapper.Group#GROUP AttackGroup The group to generate the report for. -- @param Core.Settings#SETTINGS Settings Message formatting settings to use. - -- @return #string + -- @return Core.Report#REPORT The report of the detection items. function DETECTION_UNITS:DetectedItemReportSummary( Index, AttackGroup, Settings ) self:F( { Index, self.DetectedItems } ) @@ -1874,20 +1893,14 @@ do -- DETECTION_UNITS local ThreatLevelA2G = DetectedItemUnit:GetThreatLevel( DetectedItem ) - ReportSummary = string.format( - "%s - %s\n - Threat: [%s]\n - Type: %s%s", - DetectedItemID, - DetectedItemCoordText, - string.rep( "■", ThreatLevelA2G ), - UnitCategoryText, - UnitDistanceText - ) + local Report = REPORT:New() + Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText) + Report:Add( string.format( "Threat: [%s]", string.rep( "■", ThreatLevelA2G ) ) ) + Report:Add( string.format("Type: %s%s", UnitCategoryText, UnitDistanceText ) ) + return Report end - - self:T( ReportSummary ) - - return ReportSummary end + return nil end @@ -1946,6 +1959,25 @@ do -- DETECTION_TYPES return self end + + --- Get the detected item coordinate. + -- @param #DETECTION_TYPES self + -- @param DetectedTypeName + -- @return #Core.Point#COORDINATE + function DETECTION_TYPES:GetDetectedItemCoordinate( DetectedTypeName ) + self:F( { DetectedTypeName = DetectedTypeName } ) + + local DetectedItem = self:GetDetectedItem( DetectedTypeName ) + local DetectedSet = self:GetDetectedSet( DetectedTypeName ) + + if DetectedItem then + local DetectedItemUnit = DetectedSet:GetFirst() + local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate() + DetectedItemCoordinate:SetHeading( DetectedItemUnit:GetHeading() ) + return DetectedItemCoordinate + end + end + --- Make text documenting the changes of the detected zone. -- @param #DETECTION_TYPES self @@ -2055,6 +2087,7 @@ do -- DETECTION_TYPES --self:NearestFAC( DetectedItem ) end + end --- Menu of a DetectedItem using a given numeric index. @@ -2095,7 +2128,7 @@ do -- DETECTION_TYPES -- @param Index -- @param Wrapper.Group#GROUP AttackGroup The group to generate the report for. -- @param Core.Settings#SETTINGS Settings Message formatting settings to use. - -- @return #string + -- @return Core.Report#REPORT The report of the detection items. function DETECTION_TYPES:DetectedItemReportSummary( DetectedTypeName, AttackGroup, Settings ) self:F( DetectedTypeName ) @@ -2115,17 +2148,11 @@ do -- DETECTION_TYPES local DetectedItemCoordinate = DetectedItemUnit:GetCoordinate() local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings ) - local ReportSummary = string.format( - "%s - %s\n - Threat: [%s]\n - Type: %2d of %s", - DetectedItemID, - DetectedItemCoordText, - string.rep( "■", ThreatLevelA2G ), - DetectedItemsCount, - DetectedItemType - ) - self:T( ReportSummary ) - - return ReportSummary + local Report = REPORT:New() + Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText) + Report:Add( string.format( "Threat: [%s]", string.rep( "■", ThreatLevelA2G ) ) ) + Report:Add( string.format("Type: %2d of %s", DetectedItemsCount, DetectedItemType ) ) + return Report end end @@ -2217,6 +2244,33 @@ do -- DETECTION_AREAS return self end + --- Get the detected item coordinate. + -- In this case, the coordinate is the center of the zone of the area, not the center unit! + -- So if units move, the retrieved coordinate can be different from the units positions. + -- @param #DETECTION_AREAS self + -- @param Index + -- @return Core.Point#COORDINATE The coordinate. + function DETECTION_AREAS:GetDetectedItemCoordinate( Index ) + self:F( { Index = Index } ) + + local DetectedItem = self:GetDetectedItem( Index ) + local DetectedItemSet = self:GetDetectedSet( Index ) + local FirstUnit = DetectedItemSet:GetFirst() + + if DetectedItem then + local DetectedZone = self:GetDetectedItemZone( Index ) + -- TODO: Rework to COORDINATE. Problem with SetAlt. + local DetectedItemCoordinate = DetectedZone:GetPointVec2() + -- These need to be done to understand the heading and altitude of the first unit in the zone. + DetectedItemCoordinate:SetHeading( FirstUnit:GetHeading() ) + DetectedItemCoordinate:SetAlt( FirstUnit:GetAltitude() ) + + return DetectedItemCoordinate + end + + return nil + end + --- Menu of a detected item using a given numeric index. -- @param #DETECTION_AREAS self -- @param Index @@ -2252,7 +2306,7 @@ do -- DETECTION_AREAS -- @param Index -- @param Wrapper.Group#GROUP AttackGroup The group to get the settings for. -- @param Core.Settings#SETTINGS Settings (Optional) Message formatting settings to use. - -- @return #string + -- @return Core.Report#REPORT The report of the detection items. function DETECTION_AREAS:DetectedItemReportSummary( Index, AttackGroup, Settings ) self:F( Index ) @@ -2271,16 +2325,12 @@ do -- DETECTION_AREAS local DetectedItemsCount = DetectedSet:Count() local DetectedItemsTypes = DetectedSet:GetTypeNames() - local ReportSummary = string.format( - "%s - %s\n - Threat: [%s]\n - Type: %2d of %s", - DetectedItemID, - DetectedItemCoordText, - string.rep( "■", ThreatLevelA2G ), - DetectedItemsCount, - DetectedItemsTypes - ) + local Report = REPORT:New() + Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText) + Report:Add( string.format( "Threat: [%s]", string.rep( "■", ThreatLevelA2G ) ) ) + Report:Add( string.format("Type: %2d of %s", DetectedItemsCount, DetectedItemsTypes ) ) - return ReportSummary + return Report end return nil diff --git a/Moose Development/Moose/Functional/Escort.lua b/Moose Development/Moose/Functional/Escort.lua index 4540156db..697a00e00 100644 --- a/Moose Development/Moose/Functional/Escort.lua +++ b/Moose Development/Moose/Functional/Escort.lua @@ -1171,7 +1171,7 @@ function ESCORT:_ReportTargetsScheduler() if ClientEscortGroupName == EscortGroupName then - DetectedMsgs[#DetectedMsgs+1] = DetectedItemReportSummary + DetectedMsgs[#DetectedMsgs+1] = DetectedItemReportSummary:Text("\n") MENU_CLIENT_COMMAND:New( self.EscortClient, DetectedItemReportSummary, diff --git a/Moose Development/Moose/Tasking/CommandCenter.lua b/Moose Development/Moose/Tasking/CommandCenter.lua index 0a21af439..5fbefd0df 100644 --- a/Moose Development/Moose/Tasking/CommandCenter.lua +++ b/Moose Development/Moose/Tasking/CommandCenter.lua @@ -13,92 +13,6 @@ ---- The REPORT class --- @type REPORT --- @extends Core.Base#BASE -REPORT = { - ClassName = "REPORT", - Title = "", -} - ---- Create a new REPORT. --- @param #REPORT self --- @param #string Title --- @return #REPORT -function REPORT:New( Title ) - - local self = BASE:Inherit( self, BASE:New() ) -- #REPORT - - self.Report = {} - - self:SetTitle( Title or "" ) - self:SetIndent( 3 ) - - return self -end - ---- Has the REPORT Text? --- @param #REPORT self --- @return #boolean -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 - 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 - return self -end - ---- Add a new line to a REPORT. --- @param #REPORT self --- @param #string Text --- @return #REPORT -function REPORT:AddIndent( Text ) --R2.1 - self.Report[#self.Report+1] = 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. --- @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 "" - return ReportText -end - ---- Sets the title of the report. --- @param #REPORT self --- @param #string Title The title of the report. --- @return #REPORT -function REPORT:SetTitle( Title ) - self.Title = Title - return self -end - ---- Gets the amount of report items contained in the report. --- @param #REPORT self --- @return #number Returns the number of report items contained in the report. 0 is returned if no report items are contained in the report. The title is not counted for. -function REPORT:GetCount() - return #self.Report -end --- The COMMANDCENTER class diff --git a/Moose Mission Setup/Moose.files b/Moose Mission Setup/Moose.files index e708d9016..1f686de8b 100644 --- a/Moose Mission Setup/Moose.files +++ b/Moose Mission Setup/Moose.files @@ -2,6 +2,7 @@ Utilities/Routines.lua Utilities/Utils.lua Core/Base.lua +Core/Report.lua Core/Scheduler.lua Core/ScheduleDispatcher.lua Core/Event.lua diff --git a/Moose Mission Setup/Moose.lua b/Moose Mission Setup/Moose.lua index 994b284cc..1cd7ba934 100644 --- a/Moose Mission Setup/Moose.lua +++ b/Moose Mission Setup/Moose.lua @@ -1,5 +1,5 @@ env.info( '*** MOOSE DYNAMIC INCLUDE START *** ' ) -env.info( 'Moose Generation Timestamp: 20170725_0806' ) +env.info( 'Moose Generation Timestamp: 20170811_0800' ) local base = _G @@ -24,6 +24,7 @@ __Moose.Includes = {} __Moose.Include( 'Utilities/Routines.lua' ) __Moose.Include( 'Utilities/Utils.lua' ) __Moose.Include( 'Core/Base.lua' ) +__Moose.Include( 'Core/Report.lua' ) __Moose.Include( 'Core/Scheduler.lua' ) __Moose.Include( 'Core/ScheduleDispatcher.lua' ) __Moose.Include( 'Core/Event.lua' ) diff --git a/docs/Documentation/AI_A2A.html b/docs/Documentation/AI_A2A.html index 34f484bce..6d716e063 100644 --- a/docs/Documentation/AI_A2A.html +++ b/docs/Documentation/AI_A2A.html @@ -661,7 +661,6 @@
The COMMANDCENTER class governs multiple missions, the tasking and the reporting.
- - -Set special Reference Zones known by the Command Center to guide airborne pilots during WWII.
-REPORT| REPORT:Add(Text) | -
- Add a new line to a REPORT. - |
-
| REPORT:AddIndent(Text) | -
- Add a new line to a REPORT. - |
-
| REPORT.ClassName | -- - | -
| REPORT:GetCount() | -
- Gets the amount of report items contained in the report. - |
-
| REPORT:HasText() | -
- Has the REPORT Text? - |
-
| REPORT.Indent | -- - | -
| REPORT:New(Title) | -
- Create a new REPORT. - |
-
| REPORT.Report | -- - | -
| REPORT:SetIndent(Indent) | -
- Set indent of a REPORT. - |
-
| REPORT:SetTitle(Title) | -
- Sets the title of the report. - |
-
| REPORT:Text(Delimiter) | -
- Produces the text of the report, taking into account an optional delimeter, which is \n by default. - |
-
| REPORT.Title | -- |
CommandCenterREPORTThe REPORT class
- -Add a new line to a REPORT.
- -#string Text :
Add a new line to a REPORT.
- -#string Text :
Gets the amount of report items contained in the report.
- -#number: -Returns the number of report items contained in the report. 0 is returned if no report items are contained in the report. The title is not counted for.
- -Has the REPORT Text?
- -#boolean:
- - -Create a new REPORT.
- -#string Title :
Set indent of a REPORT.
- -#number Indent :
Sets the title of the report.
- -#string Title :
-The title of the report.
Produces the text of the report, taking into account an optional delimeter, which is \n by default.
- -#string Delimiter :
-(optional) A delimiter text.
#string: -The report text.
- -Controllable Option methods change the behaviour of the Controllable while being alive.
diff --git a/docs/Documentation/Designate.html b/docs/Documentation/Designate.html index 36c6d0e0f..a076cec3d 100644 --- a/docs/Documentation/Designate.html +++ b/docs/Documentation/Designate.html @@ -108,6 +108,7 @@Functional -- Management of target Designation.
+Lase, smoke and illuminate targets.
--
DESIGNATE| DESIGNATE:ActivateAutoLase() | -
- Coordinates the Auto Lase. - |
- |||
| DESIGNATE.AttackSet | @@ -184,12 +179,24 @@ each detected set of potential targets can be lased or smoked... | DESIGNATE.CC | + | +|
| DESIGNATE:CoordinateLase() | +
+ Coordinates the Auto Lase. |
|||
| DESIGNATE.Designating | + | +|||
| DESIGNATE:DesignationScope() | +
+ Adapt the designation scope according the detected items. |
|||
| DESIGNATE.LaserCodesUsed | + | +|||
| DESIGNATE.MaximumDesignations | ++ | |||
| DESIGNATE:MenuFlashStatus(AttackGroup, Flash) | + | +|||
| DESIGNATE:MenuForget(Index) | ++ | |||
| DESIGNATE:SetLaserCodes(<, LaserCodes) |
Set an array of possible laser codes. + |
+ |||
| DESIGNATE:SetMaximumDesignations(MaximumDesignations) | +
+ Set the maximum amount of designations. |
|||
| DETECTION_AREAS:GetChangeText(DetectedItem) |
Make text documenting the changes of the detected zone. + |
+ |||
| DETECTION_AREAS:GetDetectedItemCoordinate(Index) | +
+ Get the detected item coordinate. |
|||
| DETECTION_BASE:GetDetectedItemCoordinate(Index) |
- Get the COORDINATE of a detection item using a given numeric index. +Get the detected item coordinate. |
|||
| DETECTION_BASE:GetPlayersNearBy(DetectedItem) |
Returns friendly units nearby the FAC units ... + |
+ |||
| DETECTION_BASE:HasDetectedItemLOS(Index) | +
+ Has the detected item LOS (Line Of Sight) with one of the Recce? |
|||
| DETECTION_TYPES:GetChangeText(DetectedItem) |
Make text documenting the changes of the detected zone. + |
+ |||
| DETECTION_TYPES:GetDetectedItemCoordinate(DetectedTypeName) | +
+ Get the detected item coordinate. |
|||
| DETECTION_UNITS:GetChangeText(DetectedItem) |
Make text documenting the changes of the detected zone. + |
+ |||
| DETECTION_UNITS:GetDetectedItemCoordinate(Index) | +
+ Get the detected item coordinate. |
|||
| MENU_GROUP:RemoveSubMenus(MenuTime, MenuTag, Menutag) | +MENU_GROUP:RemoveSubMenus(MenuTime, MenuTag) |
Removes the sub menus recursively of this MENU_GROUP. |
@@ -1619,7 +1619,7 @@ A Tag or Key to filter the menus to be refreshed with the Tag set.
SPAWN:_TranslateRotate(SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, SpawnY, SpawnAngle) | + | +
| SPAWN.uncontrolled | ++ |
Overwrite unit names by default with group name.
-