This commit is contained in:
Applevangelist
2025-12-15 12:12:20 +01:00
parent ec41d7310b
commit 7605c2f4f5
4 changed files with 80 additions and 26 deletions
+7 -5
View File
@@ -1270,8 +1270,10 @@ end
-- @return Core.Set#SET_UNIT Set of units and statics inside the zone.
function ZONE_RADIUS:GetScannedSetUnit(Coalition)
local SetUnit = SET_UNIT:New()
self.SetUnit = self.SetUnit or SET_UNIT:New()
self.SetUnit:Clear(false)
self.SetUnit.Set={}
if self.ScanData then
for ObjectID, UnitObject in pairs( self.ScanData.Units ) do
local UnitObject = UnitObject -- DCS#Unit
@@ -1283,18 +1285,18 @@ function ZONE_RADIUS:GetScannedSetUnit(Coalition)
if Coalition == nil then includeoncoalition = true end
--self:I(string.format("Unit name %s coalition %s filter coalition = %s include = %s",FoundUnit:GetName(),tostring(FoundCoalition),tostring(Coalition),tostring(includeoncoalition)))
if FoundUnit and includeoncoalition then
SetUnit:AddUnit( FoundUnit )
self.SetUnit:AddUnit( FoundUnit )
else
local FoundStatic = STATIC:FindByName( UnitObject:getName(), false )
if FoundStatic then
SetUnit:AddUnit( FoundStatic )
self.SetUnit:AddUnit( FoundStatic )
end
end
end
end
end
return SetUnit
return self.SetUnit
end
--- Get a set of scanned groups.
+20 -9
View File
@@ -404,7 +404,7 @@ MANTIS.SamData = {
["HQ-2"] = { Range=50, Blindspot=6, Height=35, Type="Medium", Radar="HQ_2_Guideline_LN" },
["TAMIR IDFA"] = { Range=20, Blindspot=0.6, Height=12.3, Type="Short", Radar="IRON_DOME_LN" },
["STUNNER IDFA"] = { Range=250, Blindspot=1, Height=45, Type="Long", Radar="DAVID_SLING_LN" },
["NIKE"] = { Range=155, Blindspot=6, Height=30, Type="Long", Radar="HIPAR" },
["Nike"] = { Range=155, Blindspot=6, Height=30, Type="Long", Radar="HIPAR" },
["Dog Ear"] = { Range=11, Blindspot=0, Height=9, Type="Point", Radar="Dog Ear", Point="true" },
-- CH Added to DCS core 2.9.19.x
["Pantsir S1"] = { Range=20, Blindspot=1.2, Height=15, Type="Point", Radar="PantsirS1" , Point="true" },
@@ -530,7 +530,7 @@ do
--@param #string samprefix Prefixes for the SAM groups from the ME, e.g. all groups starting with "Red Sam..."
--@param #string ewrprefix Prefixes for the EWR groups from the ME, e.g. all groups starting with "Red EWR..."
--@param #string hq Group name of your HQ (optional)
--@param #string coalition Coalition side of your setup, e.g. "blue", "red" or "neutral"
--@param #string Coalition Coalition side of your setup, e.g. "blue", "red" or "neutral"
--@param #boolean dynamic Use constant (true) filtering or just filter once (false, default) (optional)
--@param #string awacs Group name of your Awacs (optional)
--@param #boolean EmOnOff Make MANTIS switch Emissions on and off instead of changing the alarm state between RED and GREEN (optional)
@@ -554,7 +554,7 @@ do
-- mybluemantis = MANTIS:New("bluemantis","Blue SAM","Blue EWR",nil,"blue",false,"Blue Awacs")
-- mybluemantis:Start()
--
function MANTIS:New(name,samprefix,ewrprefix,hq,coalition,dynamic,awacs, EmOnOff, Padding, Zones)
function MANTIS:New(name,samprefix,ewrprefix,hq,Coalition,dynamic,awacs, EmOnOff, Padding, Zones)
-- Inherit everything from BASE class.
@@ -573,7 +573,8 @@ do
self.SAM_Templates_Prefix = samprefix or "Red SAM"
self.EWR_Templates_Prefix = ewrprefix or "Red EWR"
self.HQ_Template_CC = hq or nil
self.Coalition = coalition or "red"
self.Coalition = Coalition or "red"
self.coalition = Coalition == "blue" and coalition.side.BLUE or coalition.side.RED
self.SAM_Table = {}
self.SAM_Table_Long = {}
self.SAM_Table_Medium = {}
@@ -1501,11 +1502,19 @@ do
local coord = grp:GetCoordinate()
local dist = 0
local include = true
if grp:IsGround() then include = false end
if grp:GetCoalition() == self.coalition then include = false end
if coord and SamCoordinate and grp:IsHelicopter() then
dist = coord:Get2DDistance(SamCoordinate) or 0
if dist > self.ShoradActDistance then include = false end -- we do not want long range shooting at helos
end
if grp:GetHeight(true) < height and include == true then
if self.debug then
local text = "Looking at Group: "..grp:GetName() or "N/A"
text = text .. " Include = "..tostring(include)
MESSAGE:New(text,10,"MANTIS"):ToAllIf(self.verbose):ToLog()
end
local grpalt = grp:GetHeight(true)
if grpalt < height and grpalt > 10 and include == true then
table.insert(set,coord)
end
end
@@ -1610,16 +1619,18 @@ do
self.intelset = {}
local IntelOne = INTEL:New(groupset,self.Coalition,self.name.." IntelOne")
local IntelOne = INTEL:New(groupset,self.coalition,self.name.." IntelOne")
IntelOne.DetectAccoustic = self.DetectAccoustic
IntelOne.DetectAccousticRadius = self.DetectAccousticRadius or 2000
IntelOne.DetectAccousticUnitTypes = self.DetectAccousticCategories or {Unit.Category.HELICOPTER}
--IntelOne:SetClusterAnalysis(true,true,true)
IntelOne:Start()
local IntelTwo = INTEL:New(samset,self.Coalition,self.name.." IntelTwo")
local IntelTwo = INTEL:New(samset,self.coalition,self.name.." IntelTwo")
IntelTwo.DetectAccoustic = self.DetectAccoustic
IntelTwo.DetectAccousticRadius = self.DetectAccousticRadius or 2000
IntelTwo.DetectAccousticUnitTypes = self.DetectAccousticCategories or {Unit.Category.HELICOPTER}
--IntelTwo:SetClusterAnalysis(true,true,true)
IntelTwo:Start()
local CacheTime = self.DLinkCacheTime or 120
@@ -2025,7 +2036,7 @@ do
self:__RedState(1,samgroup)
end
-- DONE Restrict on Distance
if shortsam == true and self.SmokeDecoy == true and Distance < self.DetectAccousticRadius*2 then
if shortsam == true and self.SmokeDecoy == true and Distance < self.DetectAccousticRadius*1.5 then
self:T("Smoking")
self:_SmokeUnits(samgroup)
end
@@ -2218,7 +2229,7 @@ do
end
--]]
if self.autoshorad then
self.Shorad = SHORAD:New(self.name.."-SHORAD","SHORAD",self.SAM_Group,self.ShoradActDistance,self.ShoradTime,self.coalition,self.UseEmOnOff)
self.Shorad = SHORAD:New(self.name.."-SHORAD","SHORAD",self.SAM_Group,self.ShoradActDistance,self.ShoradTime,self.Coalition,self.UseEmOnOff,self.SmokeDecoy,self.SmokeDecoyColor)
self.Shorad:SetDefenseLimits(80,95)
self.ShoradLink = true
self.Shorad.Groupset=self.ShoradGroupSet
+46 -5
View File
@@ -48,7 +48,9 @@
-- @field #number minscootdist Min distance of the next zone
-- @field #number maxscootdist Max distance of the next zone
-- @field #boolean scootrandomcoord If true, use a random coordinate in the zone and not the center
-- @field #string scootformation Formation to take for scooting, e.g. "Vee" or "Cone"
-- @field #string scootformation Formation to take for scooting, e.g. "Vee" or "Cone"
-- @field #boolean SmokeDecoy = false,
-- @field #number SmokeDecoyColor = SMOKECOLOR.White
-- @extends Core.Base#BASE
@@ -114,7 +116,9 @@ SHORAD = {
SkateZones = nil,
minscootdist = 100,
maxscootdist = 3000,
scootrandomcoord = false,
scootrandomcoord = false,
SmokeDecoy = false,
SmokeDecoyColor = SMOKECOLOR.White
}
-----------------------------------------------------------------------
@@ -161,8 +165,10 @@ do
-- @param #number ActiveTimer Determines how many seconds the systems stay on red alert after wake-up call
-- @param #string Coalition Coalition, i.e. "blue", "red", or "neutral"
-- @param #boolean UseEmOnOff Use Emissions On/Off rather than Alarm State Red/Green (default: use Emissions switch)
-- @param #boolean SmokeDecoy Throw smoke decoy when getting activated. Defaults to false.
-- @param #number SmokeDecoyColor SMOLECOLOR to use. Defaults to SMOLECOLOR.White
-- @return #SHORAD self
function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition, UseEmOnOff)
function SHORAD:New(Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition, UseEmOnOff, SmokeDecoy, SmokeDecoyColor)
local self = BASE:Inherit( self, FSM:New() )
self:T({Name, ShoradPrefix, Samset, Radius, ActiveTimer, Coalition})
@@ -171,6 +177,7 @@ do
self.name = Name or "MyShorad"
self.Prefixes = ShoradPrefix or "SAM SHORAD"
self.Radius = Radius or 20000
if type(Coalition) == "number" then Coalition = string.lower(UTILS.GetCoalitionName(Coalition)) end
self.Coalition = Coalition or "blue"
self.Samset = Samset or GroupSet
self.ActiveTimer = ActiveTimer or 600
@@ -181,8 +188,15 @@ do
self.DefenseLowProb = 70 -- probability to detect a missile shot, low margin
self.DefenseHighProb = 90 -- probability to detect a missile shot, high margin
self.UseEmOnOff = true -- Decide if we are using Emission on/off (default) or AlarmState red/green
if UseEmOnOff == false then self.UseEmOnOff = UseEmOnOff end
self:I("*** SHORAD - Started Version 0.3.4")
if SmokeDecoy then
self.SmokeDecoy = SmokeDecoy
self.SmokeDecoyColor = SmokeDecoyColor or SMOKECOLOR.White
end
self:I("*** SHORAD - Started Version 0.3.5")
-- Set the string id for output to DCS.log file.
self.lid=string.format("SHORAD %s | ", self.name)
self:_InitState()
@@ -451,6 +465,32 @@ do
return returnname
end
--- Smoke a SHORAD Group
-- @param #SHORAD self
-- @param Wrapper.Group#GROUP Group The Shorad Group to Smoke
-- @return self
function SHORAD:_SmokeUnits(Group)
if self.SmokeDecoy == true then
if Group and Group:IsAlive() then
local units = Group:GetUnits()
for _,_unit in pairs(units) do
local unit = _unit -- Wrapper.Unit#UNIT
if unit and unit:IsAlive() then
local coordinate = unit:GetCoordinate()
if coordinate then
coordinate:SwitchSmokeOffsetOn()
coordinate:Smoke(self.SmokeDecoyColor,Duration,nil,Name,true,1,20)
coordinate:Smoke(self.SmokeDecoyColor,Duration,nil,Name,true,180,20)
coordinate:Smoke(self.SmokeDecoyColor,Duration,nil,Name,true,270,20)
coordinate:Smoke(self.SmokeDecoyColor,Duration,nil,Name,true,90,20)
end
end
end
end
end
return self
end
--- Calculate if the missile shot is detected
-- @param #SHORAD self
-- @return #boolean Returns true for a detection, else false
@@ -537,7 +577,7 @@ do
local text = string.format("Shot at SHORAD %s! Evading!", _group:GetName())
self:T(text)
local m = MESSAGE:New(text,10,"SHORAD"):ToAllIf(self.debug)
self:_SmokeUnits(_group)
--Shoot and Scoot
if self.shootandscoot then
self:__ShootAndScoot(1,_group)
@@ -552,6 +592,7 @@ do
_group:EnableEmission(true)
end
_group:OptionAlarmStateRed()
self:_SmokeUnits(_group)
if self.ActiveGroups[groupname] == nil then -- no timer yet for this group
self.ActiveGroups[groupname] = { Timing = ActiveTimer }
local endtime = timer.getTime() + (ActiveTimer * math.random(75,100) / 100 ) -- randomize wakeup a bit
+7 -7
View File
@@ -41,7 +41,7 @@
-- @field #number statusupdate Time interval in seconds after which the status is refreshed. Default 60 sec. Should be negative.
-- @field #boolean DetectAccoustic If true, also detect by sound (ie proximity).
-- @field #number DetectAccousticRadius Radius dfor accoustic detection, defaults to 2000 meters.
-- @field #table DetectAccousticUnitTypes Types of units we can detect accousticly. Defaults to {Unit.Category.GROUND_UNIT,Unit.Category.HELICOPTER}
-- @field #table DetectAccousticUnitTypes Types of units we can detect accousticly. Defaults to {Unit.Category.HELICOPTER}
-- @extends Core.Fsm#FSM
--- Top Secret!
@@ -107,7 +107,7 @@ INTEL = {
detectStatics = false,
DetectAccoustic = false,
DetectAccousticRadius = 1000,
DetectAccousticUnitTypes = {Unit.Category.GROUND_UNIT,Unit.Category.HELICOPTER},
DetectAccousticUnitTypes = {Unit.Category.HELICOPTER},
}
--- Detected item info.
@@ -412,7 +412,7 @@ end
function INTEL:SetAccousticDetectionOn(Radius,UnitCategories)
self.DetectAccoustic = true
self.DetectAccousticRadius = Radius or 1000
self.DetectAccousticUnitTypes = UnitCategories or {Unit.Category.GROUND_UNIT,Unit.Category.HELICOPTER}
self.DetectAccousticUnitTypes = UnitCategories or {Unit.Category.HELICOPTER}
return self
end
@@ -865,7 +865,7 @@ function INTEL:UpdateIntel()
detectionzone = ZONE_GROUP:New(group.IdentifiableName.."INTEL_DETECT_ACCZONE",group,self.DetectAccousticRadius or 2000)
group:SetProperty("INTEL_DETECT_ACCZONE",detectionzone)
end
if recce then
if recce and recce:IsGround() then
self:GetDetectedUnitsAccoustic(recce,DetectedUnits,RecceDetecting,detectionzone)
end
end
@@ -1252,18 +1252,18 @@ function INTEL:GetDetectedUnitsAccoustic(Recce,DetectedUnits,RecceDetecting,dete
if detectionzone then
-- Get detected units
local reccename = Recce:GetName()
detectionzone:Scan({Object.Category.UNIT},self.DetectAccousticUnitTypes)
local DetectAccousticUnitTypes = self.DetectAccousticUnitTypes or {Unit.Category.HELICOPTER}
detectionzone:Scan({Object.Category.UNIT},DetectAccousticUnitTypes)
local unitset = detectionzone:GetScannedSetUnit(othercoalition) -- Core.Set#SET_UNIT
self:T("Accoustic detection found #Units "..unitset:CountAlive())
for _,_unit in pairs(unitset.Set or {}) do
if _unit and _unit:IsAlive() then
if _unit and _unit:IsAlive() and _unit:GetCoalition() ~= self.coalition then
local name = _unit:GetName() or "none"
DetectedUnits[name]=_unit
RecceDetecting[name]=reccename
self:T("Unit name = "..name)
end
end
unitset = nil
end
end