mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
SEAD/SHORAD - Add AGM-88 player modes handling
This commit is contained in:
parent
ab4411e5bb
commit
aec6dd1246
@ -133,16 +133,15 @@ function SEAD:New( SEADGroupPrefixes, Padding )
|
|||||||
|
|
||||||
self.CallBack = nil
|
self.CallBack = nil
|
||||||
self.UseCallBack = false
|
self.UseCallBack = false
|
||||||
self:AddTransition("*", "ManageEvasion", "*")
|
|
||||||
self:AddTransition("*", "CalculateHitZone", "*")
|
|
||||||
|
|
||||||
self:HandleEvent( EVENTS.Shot, self.HandleEventShot )
|
self:HandleEvent( EVENTS.Shot, self.HandleEventShot )
|
||||||
|
|
||||||
-- Start State.
|
-- Start State.
|
||||||
self:SetStartState("Running")
|
self:SetStartState("Running")
|
||||||
|
self:AddTransition("*", "ManageEvasion", "*")
|
||||||
|
self:AddTransition("*", "CalculateHitZone", "*")
|
||||||
|
|
||||||
|
self:I("*** SEAD - Started Version 0.4.2")
|
||||||
self:I("*** SEAD - Started Version 0.4.1")
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -300,28 +299,32 @@ function SEAD:onafterCalculateHitZone(From,Event,To,SEADWeapon,pos0,height,SEADG
|
|||||||
Ropt = Ropt * 0.98
|
Ropt = Ropt * 0.98
|
||||||
end
|
end
|
||||||
|
|
||||||
local predpos= pos0:Translate(Ropt,wph)
|
-- look at a couple of zones across the trajectory
|
||||||
if predpos then
|
for n=1,3 do
|
||||||
|
local dist = Ropt - ((n-1)*20000)
|
||||||
local targetzone = ZONE_RADIUS:New("Target Zone",predpos:GetVec2(),20000)
|
local predpos= pos0:Translate(dist,wph)
|
||||||
|
if predpos then
|
||||||
if self.debug then
|
|
||||||
predpos:MarkToAll(string.format("height=%dm | heading=%d | velocity=%d | Ropt=%dm",mheight,wph,mveloc,Ropt),false)
|
local targetzone = ZONE_RADIUS:New("Target Zone",predpos:GetVec2(),20000)
|
||||||
targetzone:DrawZone(coalition.side.BLUE,{0,0,1},0.2,nil,nil,3,true)
|
|
||||||
end
|
if self.debug then
|
||||||
|
predpos:MarkToAll(string.format("height=%dm | heading=%d | velocity=%ddeg | Ropt=%dm",mheight,wph,mveloc,Ropt),false)
|
||||||
local seadset = SET_GROUP:New():FilterPrefixes(self.SEADGroupPrefixes):FilterOnce()
|
targetzone:DrawZone(coalition.side.BLUE,{0,0,1},0.2,nil,nil,3,true)
|
||||||
local tgtcoord = targetzone:GetRandomPointVec2()
|
end
|
||||||
local tgtgrp = seadset:FindNearestGroupFromPointVec2(tgtcoord)
|
|
||||||
local _targetgroup = nil
|
local seadset = SET_GROUP:New():FilterPrefixes(self.SEADGroupPrefixes):FilterOnce()
|
||||||
local _targetgroupname = "none"
|
local tgtcoord = targetzone:GetRandomPointVec2()
|
||||||
local _targetskill = "Random"
|
local tgtgrp = seadset:FindNearestGroupFromPointVec2(tgtcoord)
|
||||||
if tgtgrp and tgtgrp:IsAlive() then
|
local _targetgroup = nil
|
||||||
_targetgroup = tgtgrp
|
local _targetgroupname = "none"
|
||||||
_targetgroupname = tgtgrp:GetName() -- group name
|
local _targetskill = "Random"
|
||||||
_targetskill = tgtgrp:GetUnit(1):GetSkill()
|
if tgtgrp and tgtgrp:IsAlive() then
|
||||||
self:T("*** Found Target = ".. _targetgroupname)
|
_targetgroup = tgtgrp
|
||||||
self:ManageEvasion(_targetskill,_targetgroup,pos0,"AGM_88",SEADGroup, 20)
|
_targetgroupname = tgtgrp:GetName() -- group name
|
||||||
|
_targetskill = tgtgrp:GetUnit(1):GetSkill()
|
||||||
|
self:T("*** Found Target = ".. _targetgroupname)
|
||||||
|
self:ManageEvasion(_targetskill,_targetgroup,pos0,"AGM_88",SEADGroup, 20)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -453,8 +456,9 @@ function SEAD:HandleEventShot( EventData )
|
|||||||
local _targetskill = "Random"
|
local _targetskill = "Random"
|
||||||
local _targetgroupname = "none"
|
local _targetgroupname = "none"
|
||||||
local _target = EventData.Weapon:getTarget() -- Identify target
|
local _target = EventData.Weapon:getTarget() -- Identify target
|
||||||
if not _target then
|
if not _target or self.debug then -- AGM-88 w/o target data
|
||||||
if string.find(SEADWeaponName,"AGM_88",1,true) then
|
if string.find(SEADWeaponName,"AGM_88",1,true) then
|
||||||
|
self:I("**** Tracking AGM-88 with no target data.")
|
||||||
local pos0 = SEADPlane:GetCoordinate()
|
local pos0 = SEADPlane:GetCoordinate()
|
||||||
local fheight = SEADPlane:GetHeight()
|
local fheight = SEADPlane:GetHeight()
|
||||||
self:__CalculateHitZone(20,SEADWeapon,pos0,fheight,SEADGroup)
|
self:__CalculateHitZone(20,SEADWeapon,pos0,fheight,SEADGroup)
|
||||||
|
|||||||
@ -146,7 +146,7 @@ do
|
|||||||
-- @param #boolean UseEmOnOff Use Emissions On/Off rather than Alarm State Red/Green (default: use Emissions switch)
|
-- @param #boolean UseEmOnOff Use Emissions On/Off rather than Alarm State Red/Green (default: use Emissions switch)
|
||||||
-- @retunr #SHORAD self
|
-- @retunr #SHORAD self
|
||||||
function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition, UseEmOnOff)
|
function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition, UseEmOnOff)
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, FSM:New() )
|
||||||
self:T({Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition})
|
self:T({Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition})
|
||||||
|
|
||||||
local GroupSet = SET_GROUP:New():FilterPrefixes(ShoradPrefix):FilterCoalitions(Coalition):FilterCategoryGround():FilterStart()
|
local GroupSet = SET_GROUP:New():FilterPrefixes(ShoradPrefix):FilterCoalitions(Coalition):FilterCategoryGround():FilterStart()
|
||||||
@ -164,11 +164,17 @@ do
|
|||||||
self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin
|
self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin
|
||||||
self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin
|
self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin
|
||||||
self.UseEmOnOff = UseEmOnOff or false -- Decide if we are using Emission on/off (default) or AlarmState red/green
|
self.UseEmOnOff = UseEmOnOff or false -- Decide if we are using Emission on/off (default) or AlarmState red/green
|
||||||
self:I("*** SHORAD - Started Version 0.2.10")
|
self:I("*** SHORAD - Started Version 0.3.1")
|
||||||
-- Set the string id for output to DCS.log file.
|
-- Set the string id for output to DCS.log file.
|
||||||
self.lid=string.format("SHORAD %s | ", self.name)
|
self.lid=string.format("SHORAD %s | ", self.name)
|
||||||
self:_InitState()
|
self:_InitState()
|
||||||
self:HandleEvent(EVENTS.Shot, self.HandleEventShot)
|
self:HandleEvent(EVENTS.Shot, self.HandleEventShot)
|
||||||
|
|
||||||
|
-- Start State.
|
||||||
|
self:SetStartState("Running")
|
||||||
|
self:AddTransition("*", "WakeUpShorad", "*")
|
||||||
|
self:AddTransition("*", "CalculateHitZone", "*")
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -402,6 +408,7 @@ do
|
|||||||
-- @return #boolean Returns true for a detection, else false
|
-- @return #boolean Returns true for a detection, else false
|
||||||
function SHORAD:_ShotIsDetected()
|
function SHORAD:_ShotIsDetected()
|
||||||
self:T(self.lid .. " _ShotIsDetected")
|
self:T(self.lid .. " _ShotIsDetected")
|
||||||
|
if self.debug then return true end
|
||||||
local IsDetected = false
|
local IsDetected = false
|
||||||
local DetectionProb = math.random(self.DefenseLowProb, self.DefenseHighProb) -- reference value
|
local DetectionProb = math.random(self.DefenseLowProb, self.DefenseHighProb) -- reference value
|
||||||
local ActualDetection = math.random(1,100) -- value for this shot
|
local ActualDetection = math.random(1,100) -- value for this shot
|
||||||
@ -425,7 +432,7 @@ do
|
|||||||
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
-- mymantis = MANTIS:New("BlueMantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
|
||||||
-- mymantis:AddShorad(myshorad,720)
|
-- mymantis:AddShorad(myshorad,720)
|
||||||
-- mymantis:Start()
|
-- mymantis:Start()
|
||||||
function SHORAD:WakeUpShorad(TargetGroup, Radius, ActiveTimer, TargetCat)
|
function SHORAD:onafterWakeUpShorad(From, Event, To, TargetGroup, Radius, ActiveTimer, TargetCat)
|
||||||
self:T(self.lid .. " WakeUpShorad")
|
self:T(self.lid .. " WakeUpShorad")
|
||||||
self:T({TargetGroup, Radius, ActiveTimer, TargetCat})
|
self:T({TargetGroup, Radius, ActiveTimer, TargetCat})
|
||||||
local targetcat = TargetCat or Object.Category.UNIT
|
local targetcat = TargetCat or Object.Category.UNIT
|
||||||
@ -479,6 +486,76 @@ do
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- (Internal) Calculate hit zone of an AGM-88
|
||||||
|
-- @param #SHORAD self
|
||||||
|
-- @param #table SEADWeapon DCS.Weapon object
|
||||||
|
-- @param Core.Point#COORDINATE pos0 Position of the plane when it fired
|
||||||
|
-- @param #number height Height when the missile was fired
|
||||||
|
-- @param Wrapper.Group#GROUP SEADGroup Attacker group
|
||||||
|
-- @return #SHORAD self
|
||||||
|
function SHORAD:onafterCalculateHitZone(From,Event,To,SEADWeapon,pos0,height,SEADGroup)
|
||||||
|
self:T("**** Calculating hit zone")
|
||||||
|
if SEADWeapon and SEADWeapon:isExist() then
|
||||||
|
--local pos = SEADWeapon:getPoint()
|
||||||
|
|
||||||
|
-- postion and height
|
||||||
|
local position = SEADWeapon:getPosition()
|
||||||
|
local mheight = height
|
||||||
|
-- heading
|
||||||
|
local wph = math.atan2(position.x.z, position.x.x)
|
||||||
|
if wph < 0 then
|
||||||
|
wph=wph+2*math.pi
|
||||||
|
end
|
||||||
|
wph=math.deg(wph)
|
||||||
|
|
||||||
|
-- velocity
|
||||||
|
local wpndata = SEAD.HarmData["AGM_88"]
|
||||||
|
local mveloc = math.floor(wpndata[2] * 340.29)
|
||||||
|
local c1 = (2*mheight*9.81)/(mveloc^2)
|
||||||
|
local c2 = (mveloc^2) / 9.81
|
||||||
|
local Ropt = c2 * math.sqrt(c1+1)
|
||||||
|
if height <= 5000 then
|
||||||
|
Ropt = Ropt * 0.72
|
||||||
|
elseif height <= 7500 then
|
||||||
|
Ropt = Ropt * 0.82
|
||||||
|
elseif height <= 10000 then
|
||||||
|
Ropt = Ropt * 0.87
|
||||||
|
elseif height <= 12500 then
|
||||||
|
Ropt = Ropt * 0.98
|
||||||
|
end
|
||||||
|
|
||||||
|
-- look at a couple of zones across the trajectory
|
||||||
|
for n=1,3 do
|
||||||
|
local dist = Ropt - ((n-1)*20000)
|
||||||
|
local predpos= pos0:Translate(dist,wph)
|
||||||
|
if predpos then
|
||||||
|
|
||||||
|
local targetzone = ZONE_RADIUS:New("Target Zone",predpos:GetVec2(),20000)
|
||||||
|
|
||||||
|
if self.debug then
|
||||||
|
predpos:MarkToAll(string.format("height=%dm | heading=%d | velocity=%ddeg | Ropt=%dm",mheight,wph,mveloc,Ropt),false)
|
||||||
|
targetzone:DrawZone(coalition.side.BLUE,{0,0,1},0.2,nil,nil,3,true)
|
||||||
|
end
|
||||||
|
|
||||||
|
local seadset = self.Groupset
|
||||||
|
local tgtcoord = targetzone:GetRandomPointVec2()
|
||||||
|
local tgtgrp = seadset:FindNearestGroupFromPointVec2(tgtcoord)
|
||||||
|
local _targetgroup = nil
|
||||||
|
local _targetgroupname = "none"
|
||||||
|
local _targetskill = "Random"
|
||||||
|
if tgtgrp and tgtgrp:IsAlive() then
|
||||||
|
_targetgroup = tgtgrp
|
||||||
|
_targetgroupname = tgtgrp:GetName() -- group name
|
||||||
|
_targetskill = tgtgrp:GetUnit(1):GetSkill()
|
||||||
|
self:T("*** Found Target = ".. _targetgroupname)
|
||||||
|
self:WakeUpShorad(_targetgroupname, self.Radius, self.ActiveTimer, Object.Category.UNIT)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Main function - work on the EventData
|
--- Main function - work on the EventData
|
||||||
-- @param #SHORAD self
|
-- @param #SHORAD self
|
||||||
-- @param Core.Event#EVENTDATA EventData The event details table data set
|
-- @param Core.Event#EVENTDATA EventData The event details table data set
|
||||||
@ -507,7 +584,15 @@ do
|
|||||||
-- get target data
|
-- get target data
|
||||||
local targetdata = EventData.Weapon:getTarget() -- Identify target
|
local targetdata = EventData.Weapon:getTarget() -- Identify target
|
||||||
-- Is there target data?
|
-- Is there target data?
|
||||||
if not targetdata then return end
|
if not targetdata or self.debug then
|
||||||
|
if string.find(ShootingWeaponName,"AGM_88",1,true) then
|
||||||
|
self:I("**** Tracking AGM-88 with no target data.")
|
||||||
|
local pos0 = EventData.IniUnit:GetCoordinate()
|
||||||
|
local fheight = EventData.IniUnit:GetHeight()
|
||||||
|
self:__CalculateHitZone(20,ShootingWeapon,pos0,fheight,EventData.IniGroup)
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
local targetcat = targetdata:getCategory() -- Identify category
|
local targetcat = targetdata:getCategory() -- Identify category
|
||||||
self:T(string.format("Target Category (3=STATIC, 1=UNIT)= %s",tostring(targetcat)))
|
self:T(string.format("Target Category (3=STATIC, 1=UNIT)= %s",tostring(targetcat)))
|
||||||
@ -573,6 +658,7 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return self
|
||||||
end
|
end
|
||||||
--
|
--
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user