mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
First version
This commit is contained in:
commit
fcceb278ec
1358
Moose Development/Moose/AI/AI_Escort.lua
Normal file
1358
Moose Development/Moose/AI/AI_Escort.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -136,6 +136,13 @@ function AI_FORMATION:New( FollowUnit, FollowGroupSet, FollowName, FollowBriefin
|
|||||||
self.FollowUnit = FollowUnit -- Wrapper.Unit#UNIT
|
self.FollowUnit = FollowUnit -- Wrapper.Unit#UNIT
|
||||||
self.FollowGroupSet = FollowGroupSet -- Core.Set#SET_GROUP
|
self.FollowGroupSet = FollowGroupSet -- Core.Set#SET_GROUP
|
||||||
|
|
||||||
|
self.FollowGroupSet:ForEachGroup(
|
||||||
|
function( FollowGroup )
|
||||||
|
self:E("Following")
|
||||||
|
FollowGroup.Following = true
|
||||||
|
end
|
||||||
|
)
|
||||||
|
|
||||||
self:SetFlightRandomization( 2 )
|
self:SetFlightRandomization( 2 )
|
||||||
|
|
||||||
self:SetStartState( "None" )
|
self:SetStartState( "None" )
|
||||||
@ -906,6 +913,31 @@ function AI_FORMATION:SetFlightRandomization( FlightRandomization ) --R2.1
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- This releases the air unit in your flight from the formation flight.
|
||||||
|
-- @param #AI_FORMATION self
|
||||||
|
-- @param Wrapper.Group#GROUP FollowGroup FollowGroup.
|
||||||
|
-- @return #AI_FORMATION
|
||||||
|
function AI_FORMATION:ReleaseFormation( FollowGroup )
|
||||||
|
|
||||||
|
FollowGroup.Following = false
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- This joins up the air unit in your formation flight.
|
||||||
|
-- @param #AI_FORMATION self
|
||||||
|
-- @param Wrapper.Group#GROUP FollowGroup FollowGroup.
|
||||||
|
-- @return #AI_FORMATION
|
||||||
|
function AI_FORMATION:JoinFormation( FollowGroup )
|
||||||
|
|
||||||
|
FollowGroup.Following = true
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Stop function. Formation will not be updated any more.
|
--- Stop function. Formation will not be updated any more.
|
||||||
-- @param #AI_FORMATION self
|
-- @param #AI_FORMATION self
|
||||||
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
||||||
@ -960,109 +992,112 @@ function AI_FORMATION:onenterFollowing( FollowGroupSet ) --R2.1
|
|||||||
--- @param Wrapper.Group#GROUP FollowGroup
|
--- @param Wrapper.Group#GROUP FollowGroup
|
||||||
-- @param Wrapper.Unit#UNIT ClientUnit
|
-- @param Wrapper.Unit#UNIT ClientUnit
|
||||||
function( FollowGroup, Formation, ClientUnit, CT1, CV1, CT2, CV2 )
|
function( FollowGroup, Formation, ClientUnit, CT1, CV1, CT2, CV2 )
|
||||||
|
|
||||||
|
if FollowGroup.Following == true then
|
||||||
|
|
||||||
FollowGroup:OptionROTEvadeFire()
|
FollowGroup:OptionROTEvadeFire()
|
||||||
FollowGroup:OptionROEReturnFire()
|
FollowGroup:OptionROEReturnFire()
|
||||||
|
|
||||||
local GroupUnit = FollowGroup:GetUnit( 1 )
|
local GroupUnit = FollowGroup:GetUnit( 1 )
|
||||||
local FollowFormation = FollowGroup:GetState( self, "FormationVec3" )
|
local FollowFormation = FollowGroup:GetState( self, "FormationVec3" )
|
||||||
if FollowFormation then
|
if FollowFormation then
|
||||||
local FollowDistance = FollowFormation.x
|
local FollowDistance = FollowFormation.x
|
||||||
|
|
||||||
local GT1 = GroupUnit:GetState( self, "GT1" )
|
|
||||||
|
|
||||||
if CT1 == nil or CT1 == 0 or GT1 == nil or GT1 == 0 then
|
|
||||||
GroupUnit:SetState( self, "GV1", GroupUnit:GetPointVec3() )
|
|
||||||
GroupUnit:SetState( self, "GT1", timer.getTime() )
|
|
||||||
else
|
|
||||||
local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5
|
|
||||||
local CT = CT2 - CT1
|
|
||||||
|
|
||||||
local CS = ( 3600 / CT ) * ( CD / 1000 ) / 3.6
|
|
||||||
|
|
||||||
local CDv = { x = CV2.x - CV1.x, y = CV2.y - CV1.y, z = CV2.z - CV1.z }
|
|
||||||
local Ca = math.atan2( CDv.x, CDv.z )
|
|
||||||
|
|
||||||
local GT1 = GroupUnit:GetState( self, "GT1" )
|
local GT1 = GroupUnit:GetState( self, "GT1" )
|
||||||
local GT2 = timer.getTime()
|
|
||||||
local GV1 = GroupUnit:GetState( self, "GV1" )
|
if CT1 == nil or CT1 == 0 or GT1 == nil or GT1 == 0 then
|
||||||
local GV2 = GroupUnit:GetPointVec3()
|
GroupUnit:SetState( self, "GV1", GroupUnit:GetPointVec3() )
|
||||||
GV2:AddX( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
GroupUnit:SetState( self, "GT1", timer.getTime() )
|
||||||
GV2:AddY( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
else
|
||||||
GV2:AddZ( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5
|
||||||
GroupUnit:SetState( self, "GT1", GT2 )
|
local CT = CT2 - CT1
|
||||||
GroupUnit:SetState( self, "GV1", GV2 )
|
|
||||||
|
local CS = ( 3600 / CT ) * ( CD / 1000 ) / 3.6
|
||||||
|
|
||||||
local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5
|
local CDv = { x = CV2.x - CV1.x, y = CV2.y - CV1.y, z = CV2.z - CV1.z }
|
||||||
local GT = GT2 - GT1
|
local Ca = math.atan2( CDv.x, CDv.z )
|
||||||
|
|
||||||
|
local GT1 = GroupUnit:GetState( self, "GT1" )
|
||||||
-- Calculate the distance
|
local GT2 = timer.getTime()
|
||||||
local GDv = { x = GV2.x - CV1.x, y = GV2.y - CV1.y, z = GV2.z - CV1.z }
|
local GV1 = GroupUnit:GetState( self, "GV1" )
|
||||||
local Alpha_T = math.atan2( GDv.x, GDv.z ) - math.atan2( CDv.x, CDv.z )
|
local GV2 = GroupUnit:GetPointVec3()
|
||||||
local Alpha_R = ( Alpha_T < 0 ) and Alpha_T + 2 * math.pi or Alpha_T
|
GV2:AddX( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
||||||
local Position = math.cos( Alpha_R )
|
GV2:AddY( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
||||||
local GD = ( ( GDv.x )^2 + ( GDv.z )^2 ) ^ 0.5
|
GV2:AddZ( math.random( -Formation.FlightRandomization / 2, Formation.FlightRandomization / 2 ) )
|
||||||
local Distance = GD * Position + - CS * 0.5
|
GroupUnit:SetState( self, "GT1", GT2 )
|
||||||
|
GroupUnit:SetState( self, "GV1", GV2 )
|
||||||
-- Calculate the group direction vector
|
|
||||||
local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z }
|
|
||||||
|
local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5
|
||||||
-- Calculate GH2, GH2 with the same height as CV2.
|
local GT = GT2 - GT1
|
||||||
local GH2 = { x = GV2.x, y = CV2.y + FollowFormation.y, z = GV2.z }
|
|
||||||
|
|
||||||
-- Calculate the angle of GV to the orthonormal plane
|
-- Calculate the distance
|
||||||
local alpha = math.atan2( GV.x, GV.z )
|
local GDv = { x = GV2.x - CV1.x, y = GV2.y - CV1.y, z = GV2.z - CV1.z }
|
||||||
|
local Alpha_T = math.atan2( GDv.x, GDv.z ) - math.atan2( CDv.x, CDv.z )
|
||||||
local GVx = FollowFormation.z * math.cos( Ca ) + FollowFormation.x * math.sin( Ca )
|
local Alpha_R = ( Alpha_T < 0 ) and Alpha_T + 2 * math.pi or Alpha_T
|
||||||
local GVz = FollowFormation.x * math.cos( Ca ) - FollowFormation.z * math.sin( Ca )
|
local Position = math.cos( Alpha_R )
|
||||||
|
local GD = ( ( GDv.x )^2 + ( GDv.z )^2 ) ^ 0.5
|
||||||
|
local Distance = GD * Position + - CS * 0.5
|
||||||
-- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2.
|
|
||||||
-- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2))
|
-- Calculate the group direction vector
|
||||||
local CVI = { x = CV2.x + CS * 10 * math.sin(Ca),
|
local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z }
|
||||||
y = GH2.y - ( Distance + FollowFormation.x ) / 5, -- + FollowFormation.y,
|
|
||||||
z = CV2.z + CS * 10 * math.cos(Ca),
|
-- Calculate GH2, GH2 with the same height as CV2.
|
||||||
}
|
local GH2 = { x = GV2.x, y = CV2.y + FollowFormation.y, z = GV2.z }
|
||||||
|
|
||||||
-- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction.
|
-- Calculate the angle of GV to the orthonormal plane
|
||||||
local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z }
|
local alpha = math.atan2( GV.x, GV.z )
|
||||||
|
|
||||||
-- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s.
|
local GVx = FollowFormation.z * math.cos( Ca ) + FollowFormation.x * math.sin( Ca )
|
||||||
-- We need to calculate this vector to predict the point the escort group needs to fly to according its speed.
|
local GVz = FollowFormation.x * math.cos( Ca ) - FollowFormation.z * math.sin( Ca )
|
||||||
-- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right...
|
|
||||||
local DVu = { x = DV.x / FollowDistance, y = DV.y, z = DV.z / FollowDistance }
|
|
||||||
|
-- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2.
|
||||||
-- Now we can calculate the group destination vector GDV.
|
-- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2))
|
||||||
local GDV = { x = CVI.x, y = CVI.y, z = CVI.z }
|
local CVI = { x = CV2.x + CS * 10 * math.sin(Ca),
|
||||||
|
y = GH2.y - ( Distance + FollowFormation.x ) / 5, -- + FollowFormation.y,
|
||||||
local ADDx = FollowFormation.x * math.cos(alpha) - FollowFormation.z * math.sin(alpha)
|
z = CV2.z + CS * 10 * math.cos(Ca),
|
||||||
local ADDz = FollowFormation.z * math.cos(alpha) + FollowFormation.x * math.sin(alpha)
|
}
|
||||||
|
|
||||||
local GDV_Formation = {
|
-- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction.
|
||||||
x = GDV.x - GVx,
|
local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z }
|
||||||
y = GDV.y,
|
|
||||||
z = GDV.z - GVz
|
-- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s.
|
||||||
}
|
-- We need to calculate this vector to predict the point the escort group needs to fly to according its speed.
|
||||||
|
-- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right...
|
||||||
if self.SmokeDirectionVector == true then
|
local DVu = { x = DV.x / FollowDistance, y = DV.y, z = DV.z / FollowDistance }
|
||||||
trigger.action.smoke( GDV, trigger.smokeColor.Green )
|
|
||||||
trigger.action.smoke( GDV_Formation, trigger.smokeColor.White )
|
-- Now we can calculate the group destination vector GDV.
|
||||||
|
local GDV = { x = CVI.x, y = CVI.y, z = CVI.z }
|
||||||
|
|
||||||
|
local ADDx = FollowFormation.x * math.cos(alpha) - FollowFormation.z * math.sin(alpha)
|
||||||
|
local ADDz = FollowFormation.z * math.cos(alpha) + FollowFormation.x * math.sin(alpha)
|
||||||
|
|
||||||
|
local GDV_Formation = {
|
||||||
|
x = GDV.x - GVx,
|
||||||
|
y = GDV.y,
|
||||||
|
z = GDV.z - GVz
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.SmokeDirectionVector == true then
|
||||||
|
trigger.action.smoke( GDV, trigger.smokeColor.Green )
|
||||||
|
trigger.action.smoke( GDV_Formation, trigger.smokeColor.White )
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local Time = 60
|
||||||
|
|
||||||
|
local Speed = - ( Distance + FollowFormation.x ) / Time
|
||||||
|
local GS = Speed + CS
|
||||||
|
if Speed < 0 then
|
||||||
|
Speed = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Now route the escort to the desired point with the desired speed.
|
||||||
|
FollowGroup:RouteToVec3( GDV_Formation, GS ) -- DCS models speed in Mps (Miles per second)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local Time = 60
|
|
||||||
|
|
||||||
local Speed = - ( Distance + FollowFormation.x ) / Time
|
|
||||||
local GS = Speed + CS
|
|
||||||
if Speed < 0 then
|
|
||||||
Speed = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Now route the escort to the desired point with the desired speed.
|
|
||||||
FollowGroup:RouteToVec3( GDV_Formation, GS ) -- DCS models speed in Mps (Miles per second)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|||||||
@ -2478,6 +2478,37 @@ do -- DETECTION_AREAS
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Report summary of a detected item using a given numeric index.
|
||||||
|
-- @param #DETECTION_AREAS self
|
||||||
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||||
|
-- @param Wrapper.Group#GROUP AttackGroup The group to get the settings for.
|
||||||
|
-- @param Core.Settings#SETTINGS Settings (Optional) Message formatting settings to use.
|
||||||
|
-- @return Core.Report#REPORT The report of the detection items.
|
||||||
|
function DETECTION_AREAS:DetectedItemReportMenu( DetectedItem, AttackGroup, Settings )
|
||||||
|
self:F( { DetectedItem = DetectedItem } )
|
||||||
|
|
||||||
|
local DetectedItemID = self:GetDetectedItemID( DetectedItem )
|
||||||
|
|
||||||
|
if DetectedItem then
|
||||||
|
local DetectedSet = self:GetDetectedItemSet( DetectedItem )
|
||||||
|
local ReportSummaryItem
|
||||||
|
|
||||||
|
local DetectedZone = self:GetDetectedItemZone( DetectedItem )
|
||||||
|
local DetectedItemCoordinate = DetectedZone:GetCoordinate()
|
||||||
|
local DetectedItemCoordText = DetectedItemCoordinate:ToString( AttackGroup, Settings )
|
||||||
|
|
||||||
|
local ThreatLevelA2G = self:GetDetectedItemThreatLevel( DetectedItem )
|
||||||
|
|
||||||
|
local Report = REPORT:New()
|
||||||
|
Report:Add( string.format( "Threat: [%s%s]", string.rep( "■", ThreatLevelA2G ), string.rep( "□", 10-ThreatLevelA2G ) ) )
|
||||||
|
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
|
||||||
|
|
||||||
|
return Report
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Report summary of a detected item using a given numeric index.
|
--- Report summary of a detected item using a given numeric index.
|
||||||
-- @param #DETECTION_AREAS self
|
-- @param #DETECTION_AREAS self
|
||||||
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
-- @param #DETECTION_BASE.DetectedItem DetectedItem The DetectedItem.
|
||||||
@ -2503,9 +2534,9 @@ do -- DETECTION_AREAS
|
|||||||
|
|
||||||
local Report = REPORT:New()
|
local Report = REPORT:New()
|
||||||
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
|
Report:Add(DetectedItemID .. ", " .. DetectedItemCoordText)
|
||||||
Report:Add( string.format( "Threat: [%s]", string.rep( "■", ThreatLevelA2G ), string.rep( "□", 10-ThreatLevelA2G ) ) )
|
Report:Add( string.format( "Threat: [%s%s]", string.rep( "■", ThreatLevelA2G ), string.rep( "□", 10-ThreatLevelA2G ) ) )
|
||||||
Report:Add( string.format("Type: %2d of %s", DetectedItemsCount, DetectedItemsTypes ) )
|
Report:Add( string.format("Type: %2d of %s", DetectedItemsCount, DetectedItemsTypes ) )
|
||||||
Report:Add( string.format("Detected: %s", DetectedItem.IsDetected and "yes" or "no" ) )
|
--Report:Add( string.format("Detected: %s", DetectedItem.IsDetected and "yes" or "no" ) )
|
||||||
|
|
||||||
return Report
|
return Report
|
||||||
end
|
end
|
||||||
|
|||||||
@ -84,6 +84,7 @@ __Moose.Include( 'Scripts/Moose/AI/AI_Cap.lua' )
|
|||||||
__Moose.Include( 'Scripts/Moose/AI/AI_Cas.lua' )
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cas.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/AI/AI_Bai.lua' )
|
__Moose.Include( 'Scripts/Moose/AI/AI_Bai.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/AI/AI_Formation.lua' )
|
__Moose.Include( 'Scripts/Moose/AI/AI_Formation.lua' )
|
||||||
|
__Moose.Include( 'Scripts/Moose/AI/AI_Escort.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo.lua' )
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_APC.lua' )
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_APC.lua' )
|
||||||
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Helicopter.lua' )
|
__Moose.Include( 'Scripts/Moose/AI/AI_Cargo_Helicopter.lua' )
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user