Update Skynet and Mist.

This commit is contained in:
Dan Albert 2020-12-06 13:36:53 -08:00
parent edfaaacd04
commit e544063c40
5 changed files with 1043 additions and 7247 deletions

View File

@ -5,7 +5,7 @@
"specificOptions": [],
"scriptsWorkOrders": [
{
"file": "mist_4_3_74.lua",
"file": "mist_4_4_90.lua",
"mnemonic": "mist"
},
{

File diff suppressed because it is too large Load Diff

View File

@ -9,10 +9,6 @@
}
],
"scriptsWorkOrders": [
{
"file": "mist_4_3_74.lua",
"mnemonic": "mist"
},
{
"file": "JTACAutoLase.lua",
"mnemonic": "jtacautolase-script"

View File

@ -1,4 +1,4 @@
env.info("--- SKYNET VERSION: 1.1.3 | BUILD TIME: 30.09.2020 1816Z ---")
env.info("--- SKYNET VERSION: 1.2.0 | BUILD TIME: 21.11.2020 1159Z ---")
do
--this file contains the required units per sam type
samTypesDB = {
@ -554,8 +554,10 @@ function SkynetIADS:addEarlyWarningRadar(earlyWarningRadarUnitName)
ewRadar:setCachedTargetsMaxAge(self:getCachedTargetsMaxAge())
-- for performance improvement, if iads is not scanning no update coverage update needs to be done, will be executed once when iads activates
if self.ewRadarScanMistTaskID ~= nil then
self:updateIADSCoverage()
self:buildRadarCoverageForEarlyWarningRadar(ewRadar)
end
ewRadar:setActAsEW(true)
ewRadar:setToCorrectAutonomousState()
ewRadar:goLive()
table.insert(self.earlyWarningRadars, ewRadar)
if self:getDebugSettings().addedEWRadar then
@ -623,12 +625,12 @@ function SkynetIADS:addSAMSite(samSiteName)
self:setCoalition(samSiteDCS)
local samSite = SkynetIADSSamSite:create(samSiteDCS, self)
samSite:setupElements()
samSite:goLive()
-- for performance improvement, if iads is not scanning no update coverage update needs to be done, will be executed once when iads activates
if self.ewRadarScanMistTaskID ~= nil then
self:updateIADSCoverage()
self:buildRadarCoverageForSAMSite(samSite)
end
samSite:setCachedTargetsMaxAge(self:getCachedTargetsMaxAge())
samSite:goLive()
if samSite:getNatoName() == "UNKNOWN" then
self:printOutput("you have added an SAM Site that Skynet IADS can not handle: "..samSite:getDCSName(), true)
samSite:cleanUp()
@ -695,47 +697,30 @@ function SkynetIADS:addCommandCenter(commandCenter)
self:setCoalition(commandCenter)
local comCenter = SkynetIADSCommandCenter:create(commandCenter, self)
table.insert(self.commandCenters, comCenter)
-- when IADS is active the radars will be added to the new command center. If it not active this will happen when radar coverage is built
if self.ewRadarScanMistTaskID ~= nil then
self:addRadarsToCommandCenters()
end
return comCenter
end
function SkynetIADS:isCommandCenterUsable()
local hasWorkingCommandCenter = (#self.commandCenters == 0)
for i = 1, #self.commandCenters do
local comCenter = self.commandCenters[i]
if comCenter:isDestroyed() == false and comCenter:hasWorkingPowerSource() then
hasWorkingCommandCenter = true
break
else
hasWorkingCommandCenter = false
end
if #self:getCommandCenters() == 0 then
return true
end
return hasWorkingCommandCenter
local usableComCenters = self:getUsableAbstractRadarElemtentsOfTable(self:getCommandCenters())
return (#usableComCenters > 0)
end
function SkynetIADS:getCommandCenters()
return self.commandCenters
end
function SkynetIADS:setSAMSitesToAutonomousMode()
for i= 1, #self.samSites do
samSite = self.samSites[i]
samSite:goAutonomous()
end
end
function SkynetIADS.evaluateContacts(self)
if self:isCommandCenterUsable() == false then
if self:getDebugSettings().noWorkingCommmandCenter then
self:printOutput("No Working Command Center")
end
self:setSAMSitesToAutonomousMode()
return
end
local ewRadars = self:getUsableEarlyWarningRadars()
local samSites = self:getUsableSAMSites()
-- rewrote this part of the code to keep loops to a minimum
--will add SAM Sites acting as EW Rardars to the ewRadars array:
for i = 1, #samSites do
@ -761,13 +746,13 @@ function SkynetIADS.evaluateContacts(self)
local ewRadar = ewRadars[i]
--call go live in case ewRadar had to shut down (HARM attack)
ewRadar:goLive()
-- if an awacs has traveled more than a predeterminded distance we update the autonomous state of the sams
-- if an awacs has traveled more than a predeterminded distance we update the autonomous state of the SAMs
if getmetatable(ewRadar) == SkynetIADSAWACSRadar and ewRadar:isUpdateOfAutonomousStateOfSAMSitesRequired() then
self:updateAutonomousStatesOfSAMSites()
self:buildRadarCoverageForEarlyWarningRadar(ewRadar)
end
local ewContacts = ewRadar:getDetectedTargets()
if #ewContacts > 0 then
local samSitesUnderCoverage = ewRadar:getSAMSitesInCoveredArea()
local samSitesUnderCoverage = ewRadar:getUsableChildRadars()
for j = 1, #samSitesUnderCoverage do
local samSiteUnterCoverage = samSitesUnderCoverage[j]
-- only if a SAM site is not active we add it to the hash of SAM sites to be iterated later on
@ -817,62 +802,115 @@ function SkynetIADS:cleanAgedTargets()
self.contacts = contactsToKeep
end
function SkynetIADS:buildSAMSitesInCoveredArea()
local samSites = self:getUsableSAMSites()
for i = 1, #samSites do
local samSite = samSites[i]
samSite:updateSAMSitesInCoveredArea()
end
--TODO unit test this method:
function SkynetIADS:getAbstracRadarElements()
local abstractRadarElements = {}
local ewRadars = self:getEarlyWarningRadars()
local samSites = self:getSAMSites()
local ewRadars = self:getUsableEarlyWarningRadars()
for i = 1, #ewRadars do
local ewRadar = ewRadars[i]
ewRadar:updateSAMSitesInCoveredArea()
table.insert(abstractRadarElements, ewRadar)
end
end
function SkynetIADS:updateIADSCoverage()
self:buildSAMSitesInCoveredArea()
self:enforceRebuildAutonomousStateOfSAMSites()
--update moose connector with radar group names Skynet is able to use
self:getMooseConnector():update()
end
function SkynetIADS:updateAutonomousStatesOfSAMSites(deadUnit)
--deat unit is to prevent multiple calls via the event handling of SkynetIADSAbstractElement when a units power source or connection node is destroyed
if deadUnit == nil or self.destroyedUnitResponsibleForUpdateAutonomousStateOfSAMSite ~= deadUnit then
self:updateIADSCoverage()
self.destroyedUnitResponsibleForUpdateAutonomousStateOfSAMSite = deadUnit
end
end
function SkynetIADS:enforceRebuildAutonomousStateOfSAMSites()
local ewRadars = self:getUsableEarlyWarningRadars()
local samSites = self:getUsableSAMSites()
for i = 1, #samSites do
local samSite = samSites[i]
if samSite:getActAsEW() then
table.insert(ewRadars, samSite)
end
table.insert(abstractRadarElements, samSite)
end
return abstractRadarElements
end
function SkynetIADS:addRadarsToCommandCenters()
--we clear any existing radars that may have been added earlier
local comCenters = self:getCommandCenters()
for i = 1, #comCenters do
local comCenter = comCenters[i]
comCenter:clearChildRadars()
end
-- then we add child radars to the command centers
local abstractRadarElements = self:getAbstracRadarElements()
for i = 1, #abstractRadarElements do
local abstractRadar = abstractRadarElements[i]
self:addSingleRadarToCommandCenters(abstractRadar)
end
end
function SkynetIADS:addSingleRadarToCommandCenters(abstractRadarElement)
local comCenters = self:getCommandCenters()
for i = 1, #comCenters do
local comCenter = comCenters[i]
comCenter:addChildRadar(abstractRadarElement)
end
end
-- this method rebuilds the radar coverage of the IADS, a complete rebuild is only required the first time the IADS is activated
-- during runtime it is sufficient to call buildRadarCoverageForSAMSite or buildRadarCoverageForEarlyWarningRadar method that just updates the IADS for one unit, this saves script execution time
function SkynetIADS:buildRadarCoverage()
--to build the basic radar coverage we use all SAM sites. Checks if SAM site has power or a connection node is done when using the SAM site later on
local samSites = self:getSAMSites()
--first we clear all child and parent radars that may have been added previously
for i = 1, #samSites do
local samSite = samSites[i]
local inRange = false
for j = 1, #ewRadars do
if samSite:isInRadarDetectionRangeOf(ewRadars[j]) then
inRange = true
samSite:clearChildRadars()
samSite:clearParentRadars()
end
local ewRadars = self:getEarlyWarningRadars()
for i = 1, #ewRadars do
local ewRadar = ewRadars[i]
ewRadar:clearChildRadars()
end
--then we rebuild the radar coverage
local abstractRadarElements = self:getAbstracRadarElements()
for i = 1, #abstractRadarElements do
local abstract = abstractRadarElements[i]
self:buildRadarCoverageForAbstractRadarElement(abstract)
end
self:addRadarsToCommandCenters()
end
function SkynetIADS:buildRadarCoverageForAbstractRadarElement(abstractRadarElement)
local abstractRadarElements = self:getAbstracRadarElements()
for i = 1, #abstractRadarElements do
local aElementToCompare = abstractRadarElements[i]
if aElementToCompare ~= abstractRadarElement then
if aElementToCompare:isInRadarDetectionRangeOf(abstractRadarElement) then
if getmetatable(aElementToCompare) == SkynetIADSSamSite and getmetatable(abstractRadarElement) == SkynetIADSSamSite then
abstractRadarElement:addChildRadar(aElementToCompare)
end
if getmetatable(aElementToCompare) == SkynetIADSSamSite and getmetatable(abstractRadarElement) == SkynetIADSEWRadar then
abstractRadarElement:addChildRadar(aElementToCompare)
end
--EW Radars should not have parent Radars
if getmetatable(aElementToCompare) ~= SkynetIADSEWRadar then
aElementToCompare:addParentRadar(abstractRadarElement)
end
end
end
if inRange == false then
samSite:goAutonomous()
else
samSite:resetAutonomousState()
end
end
end
function SkynetIADS:buildRadarCoverageForSAMSite(samSite)
self:buildRadarCoverageForAbstractRadarElement(samSite)
self:addSingleRadarToCommandCenters(samSite)
end
function SkynetIADS:buildRadarCoverageForEarlyWarningRadar(ewRadar)
self:buildRadarCoverageForAbstractRadarElement(ewRadar)
self:addSingleRadarToCommandCenters(ewRadar)
end
function SkynetIADS:mergeContact(contact)
local existingContact = false
for i = 1, #self.contacts do
@ -887,6 +925,7 @@ function SkynetIADS:mergeContact(contact)
end
end
function SkynetIADS:getContacts()
return self.contacts
end
@ -909,7 +948,7 @@ function SkynetIADS.activate(self)
mist.removeFunction(self.ewRadarScanMistTaskID)
mist.removeFunction(self.samSetupMistTaskID)
self.ewRadarScanMistTaskID = mist.scheduleFunction(SkynetIADS.evaluateContacts, {self}, 1, self.contactUpdateInterval)
self:updateIADSCoverage()
self:buildRadarCoverage()
end
function SkynetIADS:setupSAMSitesAndThenActivate(setupTime)
@ -920,9 +959,7 @@ function SkynetIADS:setupSAMSitesAndThenActivate(setupTime)
for i = 1, #samSites do
local sam = samSites[i]
sam:goLive()
--stop harm scan, because this function will shut down point defences
sam:stopScanningForHARMs()
--point defences will go dark after sam:goLive() call on the SAM they are protecting, so we load them and call a separate goLive call here, some SAMs will therefore receive 2 goLive calls
--point defences will go dark after sam:goLive() call on the SAM they are protecting, so we load them by calling a separate goLive call here, point defence SAMs will therefore receive 2 goLive calls
-- this should not have a negative impact on performance
local pointDefences = sam:getPointDefences()
for j = 1, #pointDefences do
@ -930,21 +967,12 @@ function SkynetIADS:setupSAMSitesAndThenActivate(setupTime)
pointDefence:goLive()
end
end
self.samSetupMistTaskID = mist.scheduleFunction(SkynetIADS.postSetupSAMSites, {self}, timer.getTime() + self.samSetupTime)
end
function SkynetIADS.postSetupSAMSites(self)
local samSites = self:getSAMSites()
for i = 1, #samSites do
local sam = samSites[i]
--turn on the scan again otherwise SAMs that fired a missile while in setup will not turn off anymore
sam:scanForHarms()
end
self:activate()
self.samSetupMistTaskID = mist.scheduleFunction(SkynetIADS.activate, {self}, timer.getTime() + self.samSetupTime)
end
function SkynetIADS:deactivate()
mist.removeFunction(self.ewRadarScanMistTaskID)
mist.removeFunction(self.samSetupMistTaskID)
self:deativateSAMSites()
self:deactivateEarlyWarningRadars()
self:deactivateCommandCenters()
@ -1062,7 +1090,7 @@ function SkynetIADS:printDetailedEarlyWarningRadarStatus()
local intactPowerSources = numPowerSources - numDamagedPowerSources
local detectedTargets = ewRadar:getDetectedTargets()
local samSitesInCoveredArea = ewRadar:getSAMSitesInCoveredArea()
local samSitesInCoveredArea = ewRadar:getChildRadars()
local unitName = "DESTROYED"
@ -1137,7 +1165,7 @@ function SkynetIADS:printDetailedSAMSiteStatus()
local detectedTargets = samSite:getDetectedTargets()
local samSitesInCoveredArea = samSite:getSAMSitesInCoveredArea()
local samSitesInCoveredArea = samSite:getChildRadars()
env.info("GROUP: "..samSite:getDCSName().." | TYPE: "..samSite:getNatoName())
env.info("ACTIVE: "..tostring(isActive).." | AUTONOMOUS: "..tostring(isAutonomous).." | IS ACTING AS EW: "..tostring(samSite:getActAsEW()).." | DETECTED TARGETS: "..#detectedTargets.." | DEFENDING HARM: "..tostring(samSite:isDefendingHARM()).." | MISSILES IN FLIGHT:"..tostring(samSite:getNumberOfMissilesInFlight()))
@ -1180,29 +1208,29 @@ function SkynetIADS:printSystemStatus()
if self:getDebugSettings().IADSStatus then
local numComCenters = #self.commandCenters
local numIntactComCenters = 0
local numComCenters = #self:getCommandCenters()
local numDestroyedComCenters = 0
local numComCentersNoPower = 0
local numComCentersServingIADS = 0
local numComCentersNoConnectionNode = 0
local numIntactComCenters = 0
for i = 1, #self.commandCenters do
local commandCenter = self.commandCenters[i]
if commandCenter:hasWorkingPowerSource() == false then
numComCentersNoPower = numComCentersNoPower + 1
end
if commandCenter:hasActiveConnectionNode() == false then
numComCentersNoConnectionNode = numComCentersNoConnectionNode + 1
end
if commandCenter:isDestroyed() == false then
numIntactComCenters = numIntactComCenters + 1
end
if commandCenter:isDestroyed() == false and commandCenter:hasWorkingPowerSource() then
numComCentersServingIADS = numComCentersServingIADS + 1
end
end
numDestroyedComCenters = numComCenters - numIntactComCenters
self:printOutput("COMMAND CENTERS: Serving IADS: "..numComCentersServingIADS.." | Total: "..numComCenters.." | Intact: "..numIntactComCenters.." | Destroyed: "..numDestroyedComCenters.." | NoPower: "..numComCentersNoPower)
self:printOutput("COMMAND CENTERS: "..numComCenters.." | Destroyed: "..numDestroyedComCenters.." | NoPowr: "..numComCentersNoPower.." | NoCon: "..numComCentersNoConnectionNode)
local ewNoPower = 0
local ewTotal = #self:getEarlyWarningRadars()
local ewNoConnectionNode = 0
@ -1224,7 +1252,7 @@ function SkynetIADS:printSystemStatus()
ewRadarsInactive = ewTotal - ewActive
local numEWRadarsDestroyed = #self:getDestroyedEarlyWarningRadars()
self:printOutput("EW: "..ewTotal.." | Act: "..ewActive.." | Inact: "..ewRadarsInactive.." | Destroyed: "..numEWRadarsDestroyed.." | NoPowr: "..ewNoPower.." | NoCon: "..ewNoConnectionNode)
self:printOutput("EW: "..ewTotal.." | On: "..ewActive.." | Off: "..ewRadarsInactive.." | Destroyed: "..numEWRadarsDestroyed.." | NoPowr: "..ewNoPower.." | NoCon: "..ewNoConnectionNode)
local samSitesInactive = 0
local samSitesActive = 0
@ -1257,7 +1285,7 @@ function SkynetIADS:printSystemStatus()
end
samSitesInactive = samSitesTotal - samSitesActive
self:printOutput("SAM: "..samSitesTotal.." | Act: "..samSitesActive.." | Inact: "..samSitesInactive.." | Autonm: "..samSiteAutonomous.." | Raddest: "..samSiteRadarDestroyed.." | NoPowr: "..samSitesNoPower.." | NoCon: "..samSitesNoConnectionNode.." | NoAmmo: "..samSitesOutOfAmmo)
self:printOutput("SAM: "..samSitesTotal.." | On: "..samSitesActive.." | Off: "..samSitesInactive.." | Autonm: "..samSiteAutonomous.." | Raddest: "..samSiteRadarDestroyed.." | NoPowr: "..samSitesNoPower.." | NoCon: "..samSitesNoConnectionNode.." | NoAmmo: "..samSitesOutOfAmmo)
end
if self:getDebugSettings().contacts then
for i = 1, #self.contacts do
@ -1378,19 +1406,17 @@ function SkynetIADSAbstractDCSObjectWrapper:create(dcsObject)
setmetatable(instance, self)
self.__index = self
instance.dcsObject = dcsObject
if dcsObject and dcsObject:isExist() and getmetatable(dcsObject) == Unit then
--we store inital life here, because getLife0() returs a value that is lower that getLife() when no damage has happened...
instance.initialLife = dcsObject:getLife()
end
instance.name = dcsObject:getName()
instance.typeName = dcsObject:getTypeName()
return instance
end
function SkynetIADSAbstractDCSObjectWrapper:getName()
return self.dcsObject:getName()
return self.name
end
function SkynetIADSAbstractDCSObjectWrapper:getTypeName()
return self.dcsObject:getTypeName()
return self.typeName
end
function SkynetIADSAbstractDCSObjectWrapper:getPosition()
@ -1405,20 +1431,12 @@ function SkynetIADSAbstractDCSObjectWrapper:isExist()
end
end
function SkynetIADSAbstractDCSObjectWrapper:getLifePercentage()
if self.dcsObject and self.dcsObject:isExist() then
return self.dcsObject:getLife() / self.initialLife * 100
else
return 0
end
end
function SkynetIADSAbstractDCSObjectWrapper:getDCSRepresentation()
return self.dcsObject
end
end
do
SkynetIADSAbstractElement = {}
@ -1451,6 +1469,7 @@ end
function SkynetIADSAbstractElement:addPowerSource(powerSource)
table.insert(self.powerSources, powerSource)
self:informChildrenOfStateChange()
return self
end
@ -1460,7 +1479,7 @@ end
function SkynetIADSAbstractElement:addConnectionNode(connectionNode)
table.insert(self.connectionNodes, connectionNode)
self.iads:updateAutonomousStatesOfSAMSites()
self:informChildrenOfStateChange()
return self
end
@ -1526,11 +1545,10 @@ function SkynetIADSAbstractElement:onEvent(event)
if event.id == world.event.S_EVENT_DEAD then
if self:hasWorkingPowerSource() == false or self:isDestroyed() then
self:goDark()
self.iads:updateAutonomousStatesOfSAMSites(event.initiator)
self:informChildrenOfStateChange()
end
if self:hasActiveConnectionNode() == false then
self:goAutonomous()
self.iads:updateAutonomousStatesOfSAMSites(event.initiator)
self:informChildrenOfStateChange()
end
end
if event.id == world.event.S_EVENT_SHOT then
@ -1553,6 +1571,16 @@ function SkynetIADSAbstractElement:goAutonomous()
end
--placeholder method, can be implemented by subclasses
function SkynetIADSAbstractElement:setToCorrectAutonomousState()
end
--placeholder method, can be implemented by subclasses
function SkynetIADSAbstractElement:informChildrenOfStateChange()
end
-- helper code for class inheritance
function inheritsFrom( baseClass )
@ -1626,13 +1654,14 @@ function SkynetIADSAbstractRadarElement:create(dcsElementWithRadar, iads)
instance.launchers = {}
instance.trackingRadars = {}
instance.searchRadars = {}
instance.samSitesInCoveredArea = {}
instance.parentRadars = {}
instance.childRadars = {}
instance.missilesInFlight = {}
instance.pointDefences = {}
instance.ingnoreHARMSWhilePointDefencesHaveAmmo = false
instance.autonomousBehaviour = SkynetIADSAbstractRadarElement.AUTONOMOUS_STATE_DCS_AI
instance.goLiveRange = SkynetIADSAbstractRadarElement.GO_LIVE_WHEN_IN_KILL_ZONE
instance.isAutonomous = false
instance.isAutonomous = true
instance.harmDetectionChance = 0
instance.minHarmShutdownTime = 0
instance.maxHarmShutDownTime = 0
@ -1687,21 +1716,108 @@ function SkynetIADSAbstractRadarElement:getPointDefences()
return self.pointDefences
end
function SkynetIADSAbstractRadarElement:updateSAMSitesInCoveredArea()
local samSites = self.iads:getUsableSAMSites()
self.samSitesInCoveredArea = {}
for i = 1, #samSites do
local samSite = samSites[i]
if samSite:isInRadarDetectionRangeOf(self) and samSite ~= self then
table.insert(self.samSitesInCoveredArea, samSite)
end
end
return self.samSitesInCoveredArea
function SkynetIADSAbstractRadarElement:addParentRadar(parentRadar)
self:abstractAddRadar(parentRadar, self.parentRadars)
self:informChildrenOfStateChange()
end
function SkynetIADSAbstractRadarElement:getSAMSitesInCoveredArea()
return self.samSitesInCoveredArea
function SkynetIADSAbstractRadarElement:getParentRadars()
return self.parentRadars
end
function SkynetIADSAbstractRadarElement:clearParentRadars()
self.parentRadars = {}
end
function SkynetIADSAbstractRadarElement:abstractAddRadar(radar, tbl)
local isAdded = false
for i = 1, #tbl do
local child = tbl[i]
if child == radar then
isAdded = true
end
end
if isAdded == false then
table.insert(tbl, radar)
end
end
function SkynetIADSAbstractRadarElement:addChildRadar(childRadar)
self:abstractAddRadar(childRadar, self.childRadars)
end
function SkynetIADSAbstractRadarElement:getChildRadars()
return self.childRadars
end
function SkynetIADSAbstractRadarElement:clearChildRadars()
self.childRadars = {}
end
--TODO: unit test this method
function SkynetIADSAbstractRadarElement:getUsableChildRadars()
local usableRadars = {}
for i = 1, #self.childRadars do
local childRadar = self.childRadars[i]
if childRadar:hasWorkingPowerSource() and childRadar:hasActiveConnectionNode() then
table.insert(usableRadars, childRadar)
end
end
return usableRadars
end
function SkynetIADSAbstractRadarElement:informChildrenOfStateChange()
self:setToCorrectAutonomousState()
local children = self:getChildRadars()
for i = 1, #children do
local childRadar = children[i]
childRadar:setToCorrectAutonomousState()
end
self.iads:getMooseConnector():update()
end
function SkynetIADSAbstractRadarElement:setToCorrectAutonomousState()
local parents = self:getParentRadars()
for i = 1, #parents do
local parent = parents[i]
--of one parent exists that still is connected to the IADS, the SAM site does not have to go autonomous
--instead of isDestroyed() write method, hasWorkingSearchRadars()
if self:hasActiveConnectionNode() and self.iads:isCommandCenterUsable() and parent:hasWorkingPowerSource() and parent:hasActiveConnectionNode() and parent:getActAsEW() == true and parent:isDestroyed() == false then
self:resetAutonomousState()
return
end
end
self:goAutonomous()
end
function SkynetIADSAbstractRadarElement:setAutonomousBehaviour(mode)
if mode ~= nil then
self.autonomousBehaviour = mode
end
return self
end
function SkynetIADSAbstractRadarElement:getAutonomousBehaviour()
return self.autonomousBehaviour
end
function SkynetIADSAbstractRadarElement:resetAutonomousState()
self.isAutonomous = false
self:goDark()
end
function SkynetIADSAbstractRadarElement:goAutonomous()
self.isAutonomous = true
if self.autonomousBehaviour == SkynetIADSAbstractRadarElement.AUTONOMOUS_STATE_DARK then
self:goDark()
else
self:goLive()
end
end
function SkynetIADSAbstractRadarElement:getAutonomousState()
return self.isAutonomous
end
function SkynetIADSAbstractRadarElement:pointDefencesHaveRemainingAmmo(minNumberOfMissiles)
@ -1717,7 +1833,7 @@ function SkynetIADSAbstractRadarElement:pointDefencesHaveRemainingAmmo(minNumber
return returnValue
end
function SkynetIADSAbstractElement:pointDefencesHaveEnoughLaunchers(minNumberOfLaunchers)
function SkynetIADSAbstractRadarElement:pointDefencesHaveEnoughLaunchers(minNumberOfLaunchers)
local numOfLaunchers = 0
for i = 1, #self.pointDefences do
local pointDefence = self.pointDefences[i]
@ -1730,7 +1846,7 @@ function SkynetIADSAbstractElement:pointDefencesHaveEnoughLaunchers(minNumberOfL
return returnValue
end
function SkynetIADSAbstractElement:setIgnoreHARMSWhilePointDefencesHaveAmmo(state)
function SkynetIADSAbstractRadarElement:setIgnoreHARMSWhilePointDefencesHaveAmmo(state)
if state == true or state == false then
self.ingnoreHARMSWhilePointDefencesHaveAmmo = state
end
@ -1770,7 +1886,14 @@ end
function SkynetIADSAbstractRadarElement:setActAsEW(ewState)
if ewState == true or ewState == false then
local stateChange = false
if ewState ~= self.actAsEW then
stateChange = true
end
self.actAsEW = ewState
if stateChange then
self:informChildrenOfStateChange()
end
end
if self.actAsEW == true then
self:goLive()
@ -1967,7 +2090,6 @@ end
function SkynetIADSAbstractRadarElement:goLive()
if ( self.aiState == false and self:hasWorkingPowerSource() and self.harmSilenceID == nil)
and ( (self.isAutonomous == false) or (self.isAutonomous == true and self.autonomousBehaviour == SkynetIADSAbstractRadarElement.AUTONOMOUS_STATE_DCS_AI ) )
and (self:hasRemainingAmmo() == true )
then
if self:isDestroyed() == false then
@ -1976,8 +2098,8 @@ function SkynetIADSAbstractRadarElement:goLive()
cont:setOption(AI.Option.Ground.id.ALARM_STATE, AI.Option.Ground.val.ALARM_STATE.RED)
cont:setOption(AI.Option.Air.id.ROE, AI.Option.Air.val.ROE.WEAPON_FREE)
self.goLiveTime = timer.getTime()
self.aiState = true
end
self.aiState = true
self:pointDefencesStopActingAsEW()
if self.iads:getDebugSettings().radarWentLive then
self.iads:printOutput(self:getDescription().." going live")
@ -1994,21 +2116,9 @@ function SkynetIADSAbstractRadarElement:pointDefencesStopActingAsEW()
end
function SkynetIADSAbstractRadarElement:noDamageToRadars()
local radars = self:getRadars()
for i = 1, #radars do
local radar = radars[i]
if radar:getLifePercentage() < 100 then
return false
end
end
return true
end
function SkynetIADSAbstractRadarElement:goDark()
if ( self.aiState == true )
if (self:hasWorkingPowerSource() == false) or ( self.aiState == true )
and (self.harmSilenceID ~= nil or ( self.harmSilenceID == nil and #self:getDetectedTargets() == 0 and self:hasMissilesInFlight() == false) or ( self.harmSilenceID == nil and #self:getDetectedTargets() > 0 and self:hasMissilesInFlight() == false and self:hasRemainingAmmo() == false ) )
and ( self.isAutonomous == false or ( self.isAutonomous == true and self.autonomousBehaviour == SkynetIADSAbstractRadarElement.AUTONOMOUS_STATE_DARK ) )
then
if self:isDestroyed() == false then
local controller = self:getController()
@ -2108,36 +2218,6 @@ function SkynetIADSAbstractRadarElement:getDistanceToUnit(unitPosA, unitPosB)
return mist.utils.round(mist.utils.get2DDist(unitPosA, unitPosB, 0))
end
function SkynetIADSAbstractRadarElement:setAutonomousBehaviour(mode)
if mode ~= nil then
self.autonomousBehaviour = mode
end
return self
end
function SkynetIADSAbstractRadarElement:getAutonomousBehaviour()
return self.autonomousBehaviour
end
function SkynetIADSAbstractRadarElement:resetAutonomousState()
if self.isAutonomous == true then
self.isAutonomous = false
self:goDark()
end
end
function SkynetIADSAbstractRadarElement:goAutonomous()
if self.isAutonomous == false then
self.isAutonomous = true
self:goDark()
self:goLive()
end
end
function SkynetIADSAbstractRadarElement:getAutonomousState()
return self.isAutonomous
end
function SkynetIADSAbstractRadarElement:hasWorkingRadar()
local radars = self:getRadars()
for i = 1, #radars do
@ -2176,11 +2256,11 @@ function SkynetIADSAbstractRadarElement:scanForHarms()
self.harmScanID = mist.scheduleFunction(SkynetIADSAbstractRadarElement.evaluateIfTargetsContainHARMs, {self}, 1, 2)
end
function SkynetIADSAbstractElement:isScanningForHARMs()
function SkynetIADSAbstractRadarElement:isScanningForHARMs()
return self.harmScanID ~= nil
end
function SkynetIADSAbstractElement:isDefendingHARM()
function SkynetIADSAbstractRadarElement:isDefendingHARM()
return self.harmSilenceID ~= nil
end
@ -2191,7 +2271,7 @@ end
function SkynetIADSAbstractRadarElement:goSilentToEvadeHARM(timeToImpact)
self:finishHarmDefence(self)
self.objectsIdentifiedAsHarms = {}
--self.objectsIdentifiedAsHarms = {}
local harmTime = self:getHarmShutDownTime()
if self.iads:getDebugSettings().harmDefence then
self.iads:printOutput("HARM DEFENCE: "..self:getDCSName().." shutting down | FOR: "..harmTime.." seconds | TTI: "..timeToImpact)
@ -2281,20 +2361,23 @@ end
function SkynetIADSAbstractRadarElement:cleanUpOldObjectsIdentifiedAsHARMS()
local validObjects = {}
local validCount = 0
for unitName, unit in pairs(self.objectsIdentifiedAsHarms) do
local harm = unit['target']
if harm:getAge() <= self.objectsIdentifiedAsHarmsMaxTargetAge then
validObjects[harm:getName()] = {}
validObjects[harm:getName()]['target'] = harm
validObjects[harm:getName()]['count'] = unit['count']
validCount = validCount + 1
end
end
self.objectsIdentifiedAsHarms = validObjects
--stop point defences acting as ew (always on), will occur of activated via shallIgnoreHARMShutdown() in evaluateIfTargetsContainHARMs
if self:getNumberOfObjectsItentifiedAsHARMS() == 0 then
end
--stop point defences acting as ew (always on), will occur if activated via shallIgnoreHARMShutdown() in evaluateIfTargetsContainHARMs
--if in this iteration all harms where cleared we turn of the point defence. But in any other cases we dont turn of point defences, that interferes with other parts of the iads
-- when setting up the iads (letting pds go to read state)
if validCount == 0 and self:getNumberOfObjectsItentifiedAsHARMS() > 0 then
self:pointDefencesStopActingAsEW()
end
self.objectsIdentifiedAsHarms = validObjects
end
@ -2306,7 +2389,7 @@ function SkynetIADSAbstractRadarElement.evaluateIfTargetsContainHARMs(self)
self.lastJammerUpdate = 0
end
--we use the regular interval of this method to update to other states:
--we use the regular interval of this method to update to other states:
self:updateMissilesInFlight()
self:cleanUpOldObjectsIdentifiedAsHARMS()
@ -2374,6 +2457,7 @@ function SkynetIADSAWACSRadar:create(radarUnit, iads)
setmetatable(instance, self)
self.__index = self
instance.lastUpdatePosition = nil
instance.natoName = radarUnit:getTypeName()
return instance
end
@ -2384,9 +2468,6 @@ function SkynetIADSAWACSRadar:setupElements()
table.insert(self.searchRadars, radar)
end
function SkynetIADSAWACSRadar:getNatoName()
return self:getDCSRepresentation():getTypeName()
end
-- AWACs will not scan for HARMS
function SkynetIADSAWACSRadar:scanForHarms()
@ -2394,12 +2475,18 @@ function SkynetIADSAWACSRadar:scanForHarms()
end
function SkynetIADSAWACSRadar:getMaxAllowedMovementForAutonomousUpdateInNM()
local radarRange = mist.utils.metersToNM(self.searchRadars[1]:getMaxRangeFindingTarget())
return mist.utils.round(radarRange / 10)
--local radarRange = mist.utils.metersToNM(self.searchRadars[1]:getMaxRangeFindingTarget())
--return mist.utils.round(radarRange / 10)
--fixed to 10 nm miles to better fit small SAM sites
return 10
end
function SkynetIADSAWACSRadar:isUpdateOfAutonomousStateOfSAMSitesRequired()
return self:getDistanceTraveledSinceLastUpdate() > self:getMaxAllowedMovementForAutonomousUpdateInNM()
local isUpdateRequired = self:getDistanceTraveledSinceLastUpdate() > self:getMaxAllowedMovementForAutonomousUpdateInNM()
if isUpdateRequired then
self.lastUpdatePosition = nil
end
return isUpdateRequired
end
function SkynetIADSAWACSRadar:getDistanceTraveledSinceLastUpdate()
@ -2417,7 +2504,7 @@ end
do
SkynetIADSCommandCenter = {}
SkynetIADSCommandCenter = inheritsFrom(SkynetIADSAbstractElement)
SkynetIADSCommandCenter = inheritsFrom(SkynetIADSAbstractRadarElement)
function SkynetIADSCommandCenter:create(commandCenter, iads)
local instance = self:superClass():create(commandCenter, iads)
@ -2427,6 +2514,14 @@ function SkynetIADSCommandCenter:create(commandCenter, iads)
return instance
end
function SkynetIADSCommandCenter:goDark()
end
function SkynetIADSCommandCenter:goLive()
end
end
do
@ -2440,21 +2535,12 @@ function SkynetIADSContact:create(dcsRadarTarget)
instance.firstContactTime = timer.getAbsTime()
instance.lastTimeSeen = 0
instance.dcsRadarTarget = dcsRadarTarget
instance.name = instance.dcsObject:getName()
instance.typeName = instance.dcsObject:getTypeName()
instance.position = instance.dcsObject:getPosition()
instance.numOfTimesRefreshed = 0
instance.speed = 0
return instance
end
function SkynetIADSContact:getName()
return self.name
end
function SkynetIADSContact:getTypeName()
return self.typeName
end
function SkynetIADSContact:isTypeKnown()
return self.dcsRadarTarget.type
@ -2520,6 +2606,17 @@ function SkynetIADSEWRadar:create(radarUnit, iads)
return instance
end
--an Early Warning Radar has simplified check to detrmine if its autonomous or not
function SkynetIADSEWRadar:setToCorrectAutonomousState()
if self:hasActiveConnectionNode() and self:hasWorkingPowerSource() and self.iads:isCommandCenterUsable() then
self:resetAutonomousState()
self:goLive()
end
if self:hasActiveConnectionNode() == false or self.iads:isCommandCenterUsable() == false then
self:goAutonomous()
end
end
end
do