Added different formations to the menus.

This commit is contained in:
FlightControl 2019-04-08 06:42:00 +02:00
commit c657ba9218
3 changed files with 354 additions and 54 deletions

View File

@ -160,6 +160,9 @@ AI_ESCORT = {
TaskPoints = {}
}
--- @field Functional.Detection#DETECTION_AREAS
AI_ESCORT.Detection = nil
--- AI_ESCORT.Mode class
-- @type AI_ESCORT.MODE
-- @field #number FOLLOW
@ -268,7 +271,7 @@ end
--- Set a Detection method for the EscortUnit to be reported upon.
-- Detection methods are based on the derived classes from DETECTION_BASE.
-- @param #AI_ESCORT self
-- @param Function.Detection#DETECTION_BASE Detection
-- @param Functional.Detection#DETECTION_AREAS Detection
function AI_ESCORT:SetDetection( Detection )
self.Detection = Detection
@ -296,9 +299,19 @@ function AI_ESCORT:Menus()
-- self:MenuScanForTargets( 100, 60 )
self:MenuJoinUp()
self:MenuFormationTrail( 0, 50, 100 )
self:MenuFormationStack( 0, 0, 100, 100 )
self:MenuFormationLeftLine( 0, 0, 100, 100 )
self:MenuFormationRightLine( 0, 0, 100, 100 )
self:MenuFormationLeftWing( 0, 50, 0, 100, 100 )
self:MenuFormationRightWing( 0, 50, 0, 100, 100 )
self:MenuFormationCenterWing( 50, 50, 0, 50, 100, 100 )
self:MenuFormationBox( 50, 100, 0, 50, 50, 100, 10 )
self:MenuHoldAtEscortPosition( 1000, 500 )
self:MenuHoldAtLeaderPosition( 1000, 500 )
self:MenuFlare()
self:MenuSmoke()
@ -315,6 +328,230 @@ end
function AI_ESCORT:MenuFormation( Formation, ... )
if not self.FlightMenuFormation then
self.FlightMenuFormation = MENU_GROUP:New( self.EscortUnit:GetGroup(), "Formation", self.FlightMenu )
end
if not self["FlightMenuFormation"..Formation] then
self["FlightMenuFormation"..Formation] = MENU_GROUP_COMMAND:New( self.EscortUnit:GetGroup(), Formation, self.FlightMenuFormation,
function ( self, Formation, ... )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
function( EscortGroup, self, Formation, ... )
if EscortGroup:IsAir() then
self:E({Formation=Formation})
self["Formation"..Formation]( self, ... )
end
end, self, Formation, ...
)
end, self, Formation, ...
)
end
-- self.EscortGroupSet:ForEachGroupAlive(
-- --- @param Core.Group#GROUP EscortGroup
-- function( EscortGroup )
-- if EscortGroup:IsAir() then
-- if not EscortGroup.EscortMenuReportNavigation then
-- EscortGroup.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortUnit:GetGroup(), "Navigation", EscortGroup.EscortMenu )
-- end
--
-- if not EscortGroup["EscortMenuFormation"..Formation] then
-- EscortGroup["EscortMenuFormation"..Formation] = MENU_GROUP_COMMAND:New( self.EscortUnit:GetGroup(), Formation, EscortGroup.EscortMenuReportNavigation, AI_ESCORT["_EscortFormation"..Formation], self, EscortGroup, ... )
-- end
-- end
-- end
-- )
end
--- Defines --- Defines a menu slot to let the escort to join formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @return #AI_ESCORT
function AI_ESCORT:MenuJoinUp()
if not self.FlightMenuReportNavigation then
self.FlightMenuReportNavigation = MENU_GROUP:New( self.EscortUnit:GetGroup(), "Navigation", self.FlightMenu )
end
if not self.FlightMenuJoinUp then
self.FlightMenuJoinUp = MENU_GROUP_COMMAND:New( self.EscortUnit:GetGroup(), "Join Up", self.FlightMenuReportNavigation, AI_ESCORT._FlightJoinUp, self )
end
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
if not EscortGroup.EscortMenuReportNavigation then
EscortGroup.EscortMenuReportNavigation = MENU_GROUP:New( self.EscortUnit:GetGroup(), "Navigation", EscortGroup.EscortMenu )
end
if not EscortGroup.EscortMenuJoinUpAndFollow then
EscortGroup.EscortMenuJoinUpAndFollow = MENU_GROUP_COMMAND:New( self.EscortUnit:GetGroup(), "Join-Up", EscortGroup.EscortMenuReportNavigation, ESCORT._JoinUp, self, EscortGroup )
end
end
end
)
return self
end
--- Defines a menu slot to let the escort to join in a trail formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationTrail( XStart, XSpace, YStart )
self:MenuFormation( "Trail", XStart, XSpace, YStart )
return self
end
--- Defines a menu slot to let the escort to join in a stacked formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationStack( XStart, XSpace, YStart, YSpace )
self:MenuFormation( "Stack", XStart, XSpace, YStart, YSpace )
return self
end
--- Defines a menu slot to let the escort to join in a leFt wing formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationLeftLine( XStart, YStart, ZStart, ZSpace )
self:MenuFormation( "LeftLine", XStart, YStart, ZStart, ZSpace )
return self
end
--- Defines a menu slot to let the escort to join in a right line formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationRightLine( XStart, YStart, ZStart, ZSpace )
self:MenuFormation( "RightLine", XStart, YStart, ZStart, ZSpace )
return self
end
--- Defines a menu slot to let the escort to join in a left wing formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationLeftWing( XStart, XSpace, YStart, ZStart, ZSpace )
self:MenuFormation( "LeftWing", XStart, XSpace, YStart, ZStart, ZSpace )
return self
end
--- Defines a menu slot to let the escort to join in a right wing formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationRightWing( XStart, XSpace, YStart, ZStart, ZSpace )
self:MenuFormation( "RightWing", XStart, XSpace, YStart, ZStart, ZSpace )
return self
end
--- Defines a menu slot to let the escort to join in a center wing formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationCenterWing( XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
self:MenuFormation( "CenterWing", XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
return self
end
--- Defines a menu slot to let the escort to join in a vic formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationVic( XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
self:MenuFormation( "Vic", XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
return self
end
--- Defines a menu slot to let the escort to join in a box formation.
-- This menu will appear under **Formation**.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @param #nubmer ZStart The start position on the Z-axis in meters for the first group.
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
-- @param #number ZLevels The amount of levels on the Z-axis.
-- @return #AI_ESCORT
function AI_ESCORT:MenuFormationBox( XStart, XSpace, YStart, YSpace, ZStart, ZSpace, ZLevels )
self:MenuFormation( "Box", XStart, XSpace, YStart, YSpace, ZStart, ZSpace, ZLevels )
return self
end
--- Defines a menu slot to let the escort hold at their current position and stay low with a specified height during a specified time in seconds.
-- This menu will appear under **Hold position**.
@ -711,7 +948,7 @@ function AI_ESCORT:MenuReportTargets( Seconds )
-- Attack Targets
self.FlightMenuAttackNearbyTargets = MENU_GROUP:New( self.EscortUnit:GetGroup(), "Attack targets", self.FlightMenu )
self.FlightReportTargetsScheduler = SCHEDULER:New( self, self._FlightReportTargetsScheduler, {}, 1, Seconds )
self.FlightReportTargetsScheduler = SCHEDULER:New( self, self._FlightReportTargetsScheduler, {}, 5, Seconds )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
@ -910,15 +1147,82 @@ function AI_ESCORT:_FlightHoldPosition( OrbitGroup, OrbitHeight, OrbitSeconds )
end
--- @param #MENUPARAM MenuParam
function AI_ESCORT:_JoinUpAndFollow( Distance )
local EscortGroup = self.EscortGroup
function AI_ESCORT:_JoinUp( EscortGroup )
local EscortUnit = self.EscortUnit
self.Distance = Distance
self:JoinFormation( EscortGroup )
EscortGroup.EscortMode = AI_ESCORT.MODE.FOLLOW
end
function AI_ESCORT:_FlightJoinUp( EscortGroup )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_JoinUp( EscortGroup )
end
end
)
end
--- Lets the escort to join in a trail formation.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #nubmer YStart The start position on the Y-axis in meters for the first group.
-- @return #AI_ESCORT
function AI_ESCORT:_EscortFormationTrail( EscortGroup, XStart, XSpace, YStart )
self:FormationTrail( XStart, XSpace, YStart )
end
function AI_ESCORT:_FlightFormationTrail( XStart, XSpace, YStart )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_EscortFormationTrail( EscortGroup, XStart, XSpace, YStart )
end
end
)
end
--- Lets the escort to join in a stacked formation.
-- @param #AI_ESCORT self
-- @param #number XStart The start position on the X-axis in meters for the first group.
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
-- @param #number YStart The start position on the Y-axis in meters for the first group.
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
-- @return #AI_ESCORT
function AI_ESCORT:_EscortFormationStack( EscortGroup, XStart, XSpace, YStart, YSpace )
self:FormationStack( XStart, XSpace, YStart, YSpace )
end
function AI_ESCORT:_FlightFormationStack( XStart, XSpace, YStart, YSpace )
self.EscortGroupSet:ForEachGroupAlive(
--- @param Core.Group#GROUP EscortGroup
function( EscortGroup )
if EscortGroup:IsAir() then
self:_EscortFormationStack( EscortGroup, XStart, XSpace, YStart, YSpace )
end
end
)
self:JoinUpAndFollow( EscortGroup, EscortUnit, self.Distance )
end
@ -1021,7 +1325,7 @@ function AI_ESCORT:_FlightSwitchReportNearbyTargets( ReportTargets )
end
--- @param #MENUPARAM MenuParam
function AI_ESCORT:_ScanTargets( ScanDuration )
local EscortGroup = self.EscortGroup -- Wrapper.Group#GROUP
@ -1055,12 +1359,16 @@ end
-- @param Wrapper.Group#GROUP EscortGroup
function AI_ESCORT.___Resume( EscortGroup, self )
local PlayerGroup = self.EscortUnit:GetGroup()
if EscortGroup.EscortMode == AI_ESCORT.MODE.FOLLOW then
self:JoinFormation( EscortGroup )
EscortGroup:MessageTypeToClient( "Destroyed all targets. Rejoining.", MESSAGE.Type.Information, PlayerGroup )
end
end
--- @param #AI_ESCORT self
-- @param Wrapper.Group#GROUP EscortGroup The escort group that will attack the detected item.
-- @param Functional.Detection#DETECTION_BASE.DetectedItem DetectedItem
@ -1123,7 +1431,7 @@ function AI_ESCORT:_AttackTarget( EscortGroup, DetectedItem )
end
EscortGroup:MessageTypeToGroup( "Engaging Designated Unit!", MESSAGE.Type.Information, EscortUnit )
EscortGroup:MessageTypeToGroup( "Engaging!", MESSAGE.Type.Information, EscortUnit )
end
@ -1170,11 +1478,11 @@ function AI_ESCORT:_AssistTarget( EscortGroup, DetectedItem )
)
EscortGroup:MessageTypeToGroup( "Assisting with the destroying the enemy unit!", MESSAGE.Type.Information, EscortUnit:GetGroup() )
EscortGroup:MessageTypeToGroup( "Assisting attack!", MESSAGE.Type.Information, EscortUnit:GetGroup() )
end
--- @param #MENUPARAM MenuParam
function AI_ESCORT:_ROE( EscortGroup, EscortROEFunction, EscortROEMessage )
local EscortUnit = self.EscortUnit
@ -1183,7 +1491,7 @@ function AI_ESCORT:_ROE( EscortGroup, EscortROEFunction, EscortROEMessage )
EscortGroup:MessageTypeToGroup( EscortROEMessage, MESSAGE.Type.Information, EscortUnit:GetGroup() )
end
--- @param #MENUPARAM MenuParam
function AI_ESCORT:_ROT( EscortGroup, EscortROTFunction, EscortROTMessage )
local EscortUnit = self.EscortUnit
@ -1192,7 +1500,7 @@ function AI_ESCORT:_ROT( EscortGroup, EscortROTFunction, EscortROTMessage )
EscortGroup:MessageTypeToGroup( EscortROTMessage, MESSAGE.Type.Information, EscortUnit:GetGroup() )
end
--- @param #MENUPARAM MenuParam
function AI_ESCORT:_ResumeMission( WayPoint )
local EscortGroup = self.EscortGroup
@ -1212,6 +1520,7 @@ function AI_ESCORT:_ResumeMission( WayPoint )
EscortGroup:MessageToClient( "Resuming mission from waypoint " .. WayPoint .. ".", 10, EscortUnit )
end
--- Registers the waypoints
-- @param #AI_ESCORT self
-- @return #table
@ -1248,12 +1557,7 @@ function AI_ESCORT:_ReportTargetsScheduler( EscortGroup )
end
local DetectedItems = self.Detection:GetDetectedItems()
self:F( DetectedItems )
local DetectedTargets = false
local DetectedMsgs = {}
local ClientEscortTargets = self.Detection
--local EscortUnit = EscortGroupData:GetUnit( 1 )
@ -1262,15 +1566,11 @@ function AI_ESCORT:_ReportTargetsScheduler( EscortGroup )
local DetectedItemReportSummary = self.Detection:DetectedItemReportMenu( DetectedItem, EscortGroup, _DATABASE:GetPlayerSettings( self.EscortUnit:GetPlayerName() ) )
local DetectedMenu = DetectedItemReportSummary:Text("\n")
if EscortGroup:IsAir() then
local DetectedMsg = DetectedItemReportSummary:Text("\n")
DetectedMsgs[#DetectedMsgs+1] = DetectedMsg
self:T( DetectedMsg )
MENU_GROUP_COMMAND:New( self.EscortUnit:GetGroup(),
DetectedMsg,
DetectedMenu,
EscortGroup.EscortMenuAttackNearbyTargets,
AI_ESCORT._AttackTarget,
self,
@ -1279,13 +1579,9 @@ function AI_ESCORT:_ReportTargetsScheduler( EscortGroup )
)
else
if self.EscortMenuTargetAssistance then
local DetectedMsg = DetectedItemReportSummary:Text("\n")
self:T( DetectedMsg )
local MenuTargetAssistance = MENU_GROUP:New( self.EscortUnit:GetGroup(), EscortGroupName, EscortGroup.EscortMenuTargetAssistance )
MENU_GROUP_COMMAND:New( self.EscortUnit:GetGroup(),
DetectedMsg,
DetectedMenu,
MenuTargetAssistance,
AI_ESCORT._AssistTarget,
self,
@ -1295,15 +1591,9 @@ function AI_ESCORT:_ReportTargetsScheduler( EscortGroup )
end
end
DetectedTargets = true
end
self:F( DetectedMsgs )
if DetectedTargets then
EscortGroup:MessageTypeToGroup( "Reporting detected targets:\n" .. table.concat( DetectedMsgs, "\n" ), MESSAGE.Type.Information, self.EscortUnit:GetGroup() )
else
EscortGroup:MessageTypeToGroup( "No targets detected.", MESSAGE.Type.Information, self.EscortUnit:GetGroup() )
end
return true
else
end
@ -1312,14 +1602,20 @@ function AI_ESCORT:_ReportTargetsScheduler( EscortGroup )
return false
end
--- Report Targets Scheduler.
--- Report Targets Scheduler for the flight. The report is generated from the perspective of the player plane, and is reported by the first plane in the formation set.
-- @param #AI_ESCORT self
-- @param Wrapper.Group#GROUP EscortGroup
function AI_ESCORT:_FlightReportTargetsScheduler()
self:F("FlightReportTargetScheduler")
local EscortGroup = self.EscortGroupSet:GetFirst() -- Wrapper.Group#GROUP
local DetectedTargetsReport = REPORT:New( "Reporting detected targets:\n" ) -- A new report to display the detected targets as a message to the player.
if self.EscortUnit:IsAlive() then
if self.EscortUnit:IsAlive() and EscortGroup:IsAlive() then
local ClientGroup = self.EscortUnit:GetGroup()
self.FlightMenuAttackNearbyTargets:RemoveSubMenus()
@ -1327,20 +1623,16 @@ function AI_ESCORT:_FlightReportTargetsScheduler()
local DetectedTargets = false
local DetectedMsgs = {}
local ClientEscortTargets = self.Detection
--local EscortUnit = EscortGroupData:GetUnit( 1 )
for DetectedItemIndex, DetectedItem in pairs( DetectedItems ) do
self:F( { DetectedItemIndex, DetectedItem } )
local DetectedItemReportSummary = self.Detection:DetectedItemReportMenu( DetectedItem, nil, _DATABASE:GetPlayerSettings( self.EscortUnit:GetPlayerName() ) )
DetectedTargets = true -- There are detected targets, when the content of the for loop is executed. We use it to display a message.
local DetectedItemReportSummary = self.Detection:DetectedItemReportMenu( DetectedItem, ClientGroup, _DATABASE:GetPlayerSettings( self.EscortUnit:GetPlayerName() ) )
local DetectedMsg = DetectedItemReportSummary:Text("\n")
DetectedMsgs[#DetectedMsgs+1] = DetectedMsg
self:T( DetectedMsg )
local DetectedMsg = DetectedItemReportSummary:Text(", ")
DetectedTargetsReport:AddIndent( DetectedMsg, "-" )
MENU_GROUP_COMMAND:New( self.EscortUnit:GetGroup(),
DetectedMsg,
@ -1351,6 +1643,12 @@ function AI_ESCORT:_FlightReportTargetsScheduler()
)
end
if DetectedTargets then
EscortGroup:MessageTypeToGroup( DetectedTargetsReport:Text( "\n" ), MESSAGE.Type.Information, self.EscortUnit:GetGroup() )
-- else
-- EscortGroup:MessageTypeToGroup( "No targets detected.", MESSAGE.Type.Information, self.EscortUnit:GetGroup() )
end
return true
end

View File

@ -70,11 +70,12 @@ function REPORT:Add( Text )
return self
end
--- Add a new line to a REPORT.
--- Add a new line to a REPORT, but indented. A separator character can be specified to separate the reported lines visually.
-- @param #REPORT self
-- @param #string Text
-- @param #string Text The report text.
-- @param #string Separator (optional) The start of each report line can begin with an optional separator character. This can be a "-", or "#", or "*". You're free to choose what you find the best.
-- @return #REPORT
function REPORT:AddIndent( Text, Separator ) --R2.1
function REPORT:AddIndent( Text, Separator )
self.Report[#self.Report+1] = ( ( Separator and Separator .. string.rep( " ", self.Indent - 1 ) ) or string.rep(" ", self.Indent ) ) .. Text:gsub("\n","\n"..string.rep( " ", self.Indent ) )
return self
end

View File

@ -2500,8 +2500,9 @@ do -- DETECTION_AREAS
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( DetectedItem )
local Report = REPORT:New()
Report:Add( DetectedItemID )
Report:Add( string.format( "Threat: [%s%s]", string.rep( "", ThreatLevelA2G ), string.rep( "", 10-ThreatLevelA2G ) ) )
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
Report:Add( DetectedItemCoordText )
return Report
end