Add EWRS plugin.

Fixes https://github.com/Khopa/dcs_liberation/issues/323
This commit is contained in:
Dan Albert 2020-12-21 00:02:48 -08:00
parent 2d7fc33726
commit a2f218d56d
5 changed files with 866 additions and 0 deletions

View File

@ -4,6 +4,8 @@ Saves from 2.3 are not compatible with 2.4.
## Features/Improvements
* **[Plugins]** [The EWRS plugin](https://github.com/Bob7heBuilder/EWRS) is now included.
## Fixes
# 2.3.2

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Bob7heBuilder
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,830 @@
--[[
Early Warning Radar Script - 1.5.3 - 07/11/2016
Allows use of units with radars to provide Bearing Range and Altitude information via text display to player aircraft
Features:
- Uses in-game radar information to detect targets so terrain masking, beaming, low altitude flying, etc is effective for avoiding detection
- Dynamic. If valid units with radar are created during a mission (eg. via chopper with CTLD), they will be added to the EWRS radar network
- Can allow / disable BRA messages to fighters or sides
- Uses player aircraft or mission bullseye for BRA reference, can be changed via F10 radio menu or restricted to one reference in the script settings
- Can switch between imperial (feet, knots, NM) or metric (meters, km/h, km) measurements using F10 radio menu
- Ability to change the message display time and automated update interval
- Can choose to disable automated messages and allow players to request BRA from F10 menu
- Can allow players to request Bogey Dope at any time through F10 radio menu
Built and Tested in DCS 1.5 - See https://github.com/Bob7heBuilder/EWRS for the latest version
This script uses MIST 4.0.57 or later - https://github.com/mrSkortch/MissionScriptingTools
At the moment, because of limitations within DCS to not show messages to individual units, the reference, measurements, and messages
are done per group. So a group of 4 fighters will each receive 4 BRA messages. Each message however, will have the player's name
in it, that its refering to. Its unfortunate, but nothing I can do about it.
Changes:
- 1.3 - Added Option to allow picture report to be requested thru F10 menu instead of an automated display
- Fixed bug where a known unit type would sometimes still display as ???
- 1.4 - Added setting to be able to limit the amount of threats displayed in a picture report
- Added option to enable Bogey Dopes
* Mission designer can turn on / off in script settings
* Pilots can request thru the F10 menu and it will show the BRA to the nearest hostile aircraft that has
been detected. It will always reference the requesting pilot's own aircraft.
- Finally implemented a cleaner workaround for some ground units being detected and listed in picture report
- 1.4.1 - Added some ships to search radar list, you will need to remove the comment markers (--) at the start of the line to activate
- 1.5 - Added ability to request picture of friendly aircraft positions referencing your own aircraft - Mission designer chooses if this feature is active or not
- 1.5.1 - Added Gazelle to acCategories
- 1.5.2 - Added F5E to acCategories
- 1.5.3 - Fixed bug with maxThreatDisplay set at 0 not displaying any threats
- Added Mistral Gazelle
- Added C-101CC
]]
ewrs = {} --DO NOT REMOVE
ewrs.HELO = 1
ewrs.ATTACK = 2
ewrs.FIGHTER = 3
----SCRIPT OPTIONS----
ewrs.messageUpdateInterval = 30 --How often EWRS will update automated BRA messages (seconds)
ewrs.messageDisplayTime = 25 --How long EWRS BRA messages will show for (seconds)
ewrs.restrictToOneReference = false -- Disables the ability to change the BRA calls from pilot's own aircraft or bullseye. If this is true, set ewrs.defaultReference to the option you want to restrict to.
ewrs.defaultReference = "self" --The default reference for BRA calls - can be changed via f10 radio menu if ewrs.restrictToOneReference is false (self or bulls)
ewrs.defaultMeasurements = "imperial" --Default measurement units - can be changed via f10 radio menu (imperial or metric)
ewrs.disableFightersBRA = false -- disables BRA messages to fighters when true
ewrs.enableRedTeam = true -- enables / disables EWRS for the red team
ewrs.enableBlueTeam = true -- enables / disables EWRS for the blue team
ewrs.disableMessageWhenNoThreats = true -- disables message when no threats are detected - Thanks Rivvern - NOTE: If using ewrs.onDemand = true, this has no effect
ewrs.useImprovedDetectionLogic = true --this makes the messages more realistic. If the radar doesn't know the type or distance to the detected threat, it will be reflected in the picture report / BRA message
ewrs.onDemand = false --Setting to true will disable the automated messages to everyone and will add an F10 menu to get picture / BRA message.
ewrs.maxThreatDisplay = 5 -- Max amounts of threats to display on picture report (0 will display all)
ewrs.allowBogeyDope = true -- Allows pilots to request a bogey dope even with the automated messages running. It will display only the cloest threat, and will always reference the players own aircraft.
ewrs.allowFriendlyPicture = true -- Allows pilots to request picture of friendly aircraft
ewrs.maxFriendlyDisplay = 5 -- Limits the amount of friendly aircraft shown on friendly picture
--[[
Units with radar to use as part of the EWRS radar network
If you want to shorten the range of SAM radar detection, use their track radars instead of their search radars
NOTE that track radars require a search radar to detect targets (but the search radars do not need to be included in the list)
I haven't tested detection with ships (that have radar), but should work.
]]
ewrs.validSearchRadars = {
"p-10 s125 sr", --SA-3 Search Radar
"Kub 1S91 str", --SA-6 Search and Track Radar
"S-300PS 64H6E sr", --SA-10 Search Radar
"S-300 PS 40B6MD sr", --SA-10 Search Radar
"SA-11 Buk SR 9518M1", --SA-11 Search Radar
"55G6 EWR", --Early Warning Radar
"1L13 EWR", --Early Warning Radar
"A-50", --AWACS
"E-2D", --AWACS
"E-3A", --AWACS
"Roland Radar", --Roland Search Radar
"Hawk sr", --Hawk SAM Search Radar
"Patriot str", --Patriot SAM Search and Track Radar
--Ships - I've left these commented out because I don't know which ones have radar
--and which ones don't. Just remove the comment to activate them (the '--' at the start of the line)
--"MOSCOW", -- CG 1164 Moskva
--"TICONDEROG", -- CG-60 Normandy
--"PIOTR", -- CGN 1144.2 Pyotr Velikiy
--"KUZNECOW", -- CV 1143.5 Admiral Kuzentsov
--"VINSON", -- CVN-70 Carl Vinson
--"REZKY", -- FF 1135M Rezky
--"NEUSTRASH", -- FFG 11540 Neustrashimy
--"PERRY", -- FFG-7CL Oliver Hazzard Perry
--"ALBATROS", -- FFL 1124.4 Grisha
--"MOLNIYA", -- FSG 1241.1MP Molniya
}
--[[
Aircraft Type ENUMs
This is used to restrict BRA messages to fighters
Change the ewrs.TYPE for each aircraft (in ewrs.acCategories) to suit your needs
For now, BRA will be displayed to everyone unless ewrs.disableFightersBRA is true.
When this is true, anything in the list below that == ewrs.FIGHTER will NOT receive BRA messages
]]
ewrs.acCategories = { --Have I left anything out? Please let me know if I have
[ "A-10A" ] = ewrs.ATTACK ,
[ "A-10C" ] = ewrs.ATTACK ,
[ "Bf-109K-4" ] = ewrs.ATTACK ,
[ "C-101EB" ] = ewrs.ATTACK ,
[ "C-101CC" ] = ewrs.ATTACK ,
[ "F-15C" ] = ewrs.FIGHTER ,
[ "F-5E-3" ] = ewrs.ATTACK ,
[ "FW-190D9" ] = ewrs.ATTACK ,
[ "F-86F Sabre" ] = ewrs.FIGHTER ,
[ "Hawk" ] = ewrs.ATTACK ,
[ "Ka-50" ] = ewrs.HELO ,
[ "L-39C" ] = ewrs.ATTACK ,
[ "L-39ZA" ] = ewrs.ATTACK ,
[ "Mi-8MT" ] = ewrs.HELO ,
[ "MiG-15bis" ] = ewrs.ATTACK ,
[ "MiG-21Bis" ] = ewrs.ATTACK ,
[ "MiG-29A" ] = ewrs.FIGHTER ,
[ "MiG-29S" ] = ewrs.FIGHTER ,
[ "M-2000C" ] = ewrs.FIGHTER ,
[ "P-51D" ] = ewrs.ATTACK ,
[ "SA342M" ] = ewrs.HELO ,
[ "SA342L" ] = ewrs.HELO ,
[ "SA342Mistral" ] = ewrs.HELO ,
[ "Su-25" ] = ewrs.ATTACK ,
[ "Su-25T" ] = ewrs.ATTACK ,
[ "Su-27" ] = ewrs.FIGHTER ,
[ "Su-33" ] = ewrs.FIGHTER ,
[ "TF-51D" ] = ewrs.ATTACK ,
[ "UH-1H" ] = ewrs.HELO ,
}
----END OF SCRIPT OPTIONS----
----INTERNAL FUNCTIONS ***** Be Careful changing things below here ***** ----
function ewrs.getDistance(obj1PosX, obj1PosZ, obj2PosX, obj2PosZ)
local xDiff = obj1PosX - obj2PosX
local yDiff = obj1PosZ - obj2PosZ
return math.sqrt(xDiff * xDiff + yDiff * yDiff) -- meters
end
function ewrs.getBearing(obj1PosX, obj1PosZ, obj2PosX, obj2PosZ)
local bearing = math.atan2(obj2PosZ - obj1PosZ, obj2PosX - obj1PosX)
if bearing < 0 then
bearing = bearing + 2 * math.pi
end
bearing = bearing * 180 / math.pi
return bearing -- degrees
end
function ewrs.getHeading(vec)
local heading = math.atan2(vec.z,vec.x)
if heading < 0 then
heading = heading + 2 * math.pi
end
heading = heading * 180 / math.pi
return heading -- degrees
end
function ewrs.getSpeed(velocity)
local speed = math.sqrt(velocity.x^2 + velocity.y^2 + velocity.z^2) --m/s
return speed -- m/s
end
function ewrs.update()
timer.scheduleFunction(ewrs.update, nil, timer.getTime() + 5)
ewrs.buildActivePlayers()
ewrs.buildF10Menu()
end
function ewrs.buildThreatTable(activePlayer, bogeyDope)
local function sortRanges(v1,v2)
return v1.range < v2.range
end
local targets = {}
if activePlayer.side == 2 then
targets = ewrs.currentlyDetectedRedUnits
else
targets = ewrs.currentlyDetectedBlueUnits
end
local bogeyDope = bogeyDope or false
local referenceX
local referenceZ
if ewrs.groupSettings[tostring(activePlayer.groupID)].reference == "self" or bogeyDope then
local _self = Unit.getByName(activePlayer.unitname)
local selfpos = _self:getPosition()
referenceX = selfpos.p.x
referenceZ = selfpos.p.z
else
local bullseye = coalition.getMainRefPoint(activePlayer.side)
referenceX = bullseye.x
referenceZ = bullseye.z
end
local threatTable = {}
for k,v in pairs(targets) do
local velocity = v["object"]:getVelocity()
local bogeypos = v["object"]:getPosition()
local bogeyType = nil
if ewrs.useImprovedDetectionLogic then
if v["type"] then
bogeyType = v["object"]:getTypeName()
else
bogeyType = " ??? "
end
else
bogeyType = v["object"]:getTypeName()
end
local bearing = ewrs.getBearing(referenceX,referenceZ,bogeypos.p.x,bogeypos.p.z)
local heading = ewrs.getHeading(velocity)
local range = ewrs.getDistance(referenceX,referenceZ,bogeypos.p.x,bogeypos.p.z) -- meters
local altitude = bogeypos.p.y --meters
local speed = ewrs.getSpeed(velocity) --m/s
if ewrs.groupSettings[tostring(activePlayer.groupID)].measurements == "metric" then
range = range / 1000 --change to KM
speed = mist.utils.mpsToKmph(speed)
--altitude already in meters
else
range = mist.utils.metersToNM(range)
speed = mist.utils.mpsToKnots(speed)
altitude = mist.utils.metersToFeet(altitude)
end
if ewrs.useImprovedDetectionLogic then
if not v["distance"] then
range = ewrs.notAvailable
end
end
local j = #threatTable + 1
threatTable[j] = {}
threatTable[j].unitType = bogeyType
threatTable[j].bearing = bearing
threatTable[j].range = range
threatTable[j].altitude = altitude
threatTable[j].speed = speed
threatTable[j].heading = heading
end
table.sort(threatTable,sortRanges)
return threatTable
end
function ewrs.outText(activePlayer, threatTable, bogeyDope, greeting)
local status, result = pcall(function()
local message = {}
local altUnits
local speedUnits
local rangeUnits
local bogeyDope = bogeyDope or false
if ewrs.groupSettings[tostring(activePlayer.groupID)].measurements == "metric" then
altUnits = "m"
speedUnits = "Km/h"
rangeUnits = "Km"
else
altUnits = "ft"
speedUnits = "Knts"
rangeUnits = "NM"
end
if #threatTable >= 1 then
local maxThreats = nil
local messageGreeting = nil
if greeting == nil then
if bogeyDope then
maxThreats = 1
messageGreeting = "EWRS Bogey Dope for: " .. activePlayer.player
else
if ewrs.maxThreatDisplay == 0 then
maxThreats = 999
else
maxThreats = ewrs.maxThreatDisplay
end
messageGreeting = "EWRS Picture Report for: " .. activePlayer.player .. " -- Reference: " .. ewrs.groupSettings[tostring(activePlayer.groupID)].reference
end
else
messageGreeting = greeting
maxThreats = ewrs.maxFriendlyDisplay
end
--Display table
table.insert(message, "\n")
table.insert(message, messageGreeting)
table.insert(message, "\n\n")
table.insert(message, string.format( "%-16s", "TYPE"))
table.insert(message, string.format( "%-12s", "BRG"))
table.insert(message, string.format( "%-12s", "RNG"))
table.insert(message, string.format( "%-21s", "ALT"))
table.insert(message, string.format( "%-15s", "SPD"))
table.insert(message, string.format( "%-3s", "HDG"))
table.insert(message, "\n")
for k = 1, maxThreats do
if threatTable[k] == nil then break end
table.insert(message, "\n")
table.insert(message, string.format( "%-16s", threatTable[k].unitType))
if threatTable[k].range == ewrs.notAvailable then
table.insert(message, string.format( "%-12s", " "))
table.insert(message, string.format( "%-12s", "POSITION"))
table.insert(message, string.format( "%-21s", " "))
table.insert(message, string.format( "%-15s", "UNKNOWN"))
table.insert(message, string.format( "%-3s", " "))
else
table.insert(message, string.format( "%03d", threatTable[k].bearing))
table.insert(message, string.format( "%8.1f %s", threatTable[k].range, rangeUnits))
table.insert(message, string.format( "%9d %s", threatTable[k].altitude, altUnits))
table.insert(message, string.format( "%9d %s", threatTable[k].speed, speedUnits))
table.insert(message, string.format( " %03d", threatTable[k].heading))
end
table.insert(message, "\n")
end
trigger.action.outTextForGroup(activePlayer.groupID, table.concat(message), ewrs.messageDisplayTime)
else
if (not ewrs.disableMessageWhenNoThreats) or (ewrs.onDemand) and greeting == nil then
trigger.action.outTextForGroup(activePlayer.groupID, "\nEWRS Picture Report for: " .. activePlayer.player .. "\n\nNo targets detected", ewrs.messageDisplayTime)
end
if greeting ~= nil then
trigger.action.outTextForGroup(activePlayer.groupID, "\nEWRS Friendly Picture for: " .. activePlayer.player .. "\n\nNo friendlies detected", ewrs.messageDisplayTime)
end
end
end)
if not status then
env.error(string.format("EWRS outText Error: %s", result))
end
end
function ewrs.displayMessageToAll()
local status, result = pcall(function()
timer.scheduleFunction(ewrs.displayMessageToAll, nil, timer.getTime() + ewrs.messageUpdateInterval)
ewrs.findRadarUnits()
ewrs.getDetectedTargets()
for i = 1, #ewrs.activePlayers do
if ewrs.groupSettings[tostring(ewrs.activePlayers[i].groupID)].messages then
if ewrs.activePlayers[i].side == 1 and #ewrs.redEwrUnits > 0 or ewrs.activePlayers[i].side == 2 and #ewrs.blueEwrUnits > 0 then
ewrs.outText(ewrs.activePlayers[i], ewrs.buildThreatTable(ewrs.activePlayers[i]))
end -- if ewrs.activePlayers[i].side == 1 and #ewrs.redEwrUnits > 0 or ewrs.activePlayers[i].side == 2 and #ewrs.blueEwrUnits > 0 then
end -- if ewrs.groupSettings[tostring(ewrs.activePlayers[i].groupID)].messages then
end -- for i = 1, #ewrs.activePlayers do
end)
if not status then
env.error(string.format("EWRS displayMessageToAll Error: %s", result))
end
end
function ewrs.onDemandMessage(args)
local status, result = pcall(function()
ewrs.findRadarUnits()
ewrs.getDetectedTargets()
for i = 1, #ewrs.activePlayers do
if ewrs.activePlayers[i].groupID == args[1] then
ewrs.outText(ewrs.activePlayers[i], ewrs.buildThreatTable(ewrs.activePlayers[i],args[2]),args[2])
end
end
end)
if not status then
env.error(string.format("EWRS onDemandMessage Error: %s", result))
end
end
function ewrs.buildFriendlyTable(friendlyNames,activePlayer)
local function sortRanges(v1,v2)
return v1.range < v2.range
end
local units = {}
for i =1, #friendlyNames do
local unit = Unit.getByName(friendlyNames[i])
if unit ~= nil and unit:isActive() then
table.insert(units,unit)
else
--env.error("Friendly Picture - Unit not found: "..friendlyNames[i]) -- Client Planes that are not active will fall into here.
end
end
local _self = Unit.getByName(activePlayer.unitname)
local selfpos = _self:getPosition()
local referenceX = selfpos.p.x
local referenceZ = selfpos.p.z
local friendlyTable = {}
for k,v in pairs(units) do
local velocity = v:getVelocity()
local pos = v:getPosition()
local bogeyType = v:getTypeName()
if pos.p.x ~= selfpos.p.x and pos.p.z ~= selfpos.p.z then --same position as self, means its you!
local bearing = ewrs.getBearing(referenceX,referenceZ,pos.p.x,pos.p.z)
local heading = ewrs.getHeading(velocity)
local range = ewrs.getDistance(referenceX,referenceZ,pos.p.x,pos.p.z) -- meters
local altitude = pos.p.y --meters
local speed = ewrs.getSpeed(velocity) --m/s
if ewrs.groupSettings[tostring(activePlayer.groupID)].measurements == "metric" then
range = range / 1000 --change to KM
speed = mist.utils.mpsToKmph(speed)
--altitude already in meters
else
range = mist.utils.metersToNM(range)
speed = mist.utils.mpsToKnots(speed)
altitude = mist.utils.metersToFeet(altitude)
end
local j = #friendlyTable + 1
friendlyTable[j] = {}
friendlyTable[j].unitType = bogeyType
friendlyTable[j].bearing = bearing
friendlyTable[j].range = range
friendlyTable[j].altitude = altitude
friendlyTable[j].speed = speed
friendlyTable[j].heading = heading
else
--env.info("Friendly Picture - Found Self")
end
end
table.sort(friendlyTable,sortRanges)
return friendlyTable
end
function ewrs.friendlyPicture(args)
local status, result = pcall(function()
for i = 1, #ewrs.activePlayers do
if ewrs.activePlayers[i].groupID == args[1] then
local sideString = nil
if ewrs.activePlayers[i].side == 1 then
sideString = "[red]"
else
sideString = "[blue]"
end
local filter = {sideString.."[helicopter]", sideString.."[plane]"}
local friendlies = mist.makeUnitTable(filter) --find a way to do this only once if there is more then 1 person in a group
local friendlyTable = ewrs.buildFriendlyTable(friendlies,ewrs.activePlayers[i])
local greeting = "EWRS Friendly Picture for: " .. ewrs.activePlayers[i].player
ewrs.outText(ewrs.activePlayers[i],friendlyTable,false,greeting)
end
end
end)
if not status then
env.error(string.format("EWRS friendlyPicture Error: %s", result))
end
end
function ewrs.buildActivePlayers()
local status, result = pcall(function()
local filter = { "[all][plane]","[all][helicopter]"}
local all_vecs = mist.makeUnitTable(filter)
ewrs.activePlayers = {}
for i = 1, #all_vecs do
local vec = Unit.getByName(all_vecs[i])
if vec ~= nil and Unit.isActive(vec) then
playerName = Unit.getPlayerName(vec)
local groupID = ewrs.getGroupId(vec)
if playerName ~= nil then
unitCategory = ewrs.acCategories[Unit.getTypeName(vec)]
if ewrs.disableFightersBRA and unitCategory == ewrs.FIGHTER then
--DONT DO ANYTHING
else
local group = Unit.getGroup(vec)
if ewrs.enableBlueTeam and Unit.getCoalition(vec) == 2 then
ewrs.addPlayer(playerName, groupID, vec)
elseif ewrs.enableRedTeam and Unit.getCoalition(vec) == 1 then
ewrs.addPlayer(playerName, groupID, vec)
end
end
end
end
end
end) -- pcall
if not status then
env.error(string.format("EWRS buildActivePlayers Error: %s", result))
end
end
--THANK YOU ciribob http://forums.eagle.ru/showpost.php?p=2499638&postcount=5
--And Stonehouse for pointing me there
function ewrs.getGroupId(_unit) --Temp fix for client groups not being accessable
local _unitDB = mist.DBs.unitsById[tonumber(_unit:getID())]
if _unitDB ~= nil and _unitDB.groupId then
return _unitDB.groupId
end
return nil
end
function ewrs.getGroupCategory(unit)
local unitDB = mist.DBs.unitsById[tonumber(unit:getID())]
if unitDB ~= nil and unitDB.category then
return unitDB.category
end
return nil
end
function ewrs.addPlayer(playerName, groupID, unit )
local status, result = pcall(function()
local i = #ewrs.activePlayers + 1
ewrs.activePlayers[i] = {}
ewrs.activePlayers[i].player = playerName
ewrs.activePlayers[i].groupID = groupID
ewrs.activePlayers[i].unitname = unit:getName()
ewrs.activePlayers[i].side = unit:getCoalition()
-- add default settings to settings table if it hasn't been done yet
if ewrs.groupSettings[tostring(groupID)] == nil then
ewrs.addGroupSettings(tostring(groupID))
end
end)
if not status then
env.error(string.format("EWRS addPlayer Error: %s", result))
end
end
-- filters units so ones detected by multiple radar sites still only get listed once
-- Filters out anything that isn't a plane or helicopter
function ewrs.filterUnits(units)
local newUnits = {}
for k,v in pairs(units) do
local valid = true
if v["object"]:getCategory() ~= Object.Category.UNIT then --rare but i've had it detect missiles
valid = false
end
if valid then --another check cause it seems AI radar can detected some ground units
local category = ewrs.getGroupCategory(v["object"])
if category ~= "plane" and category ~= "helicopter" then valid = false end
end
if valid then
for nk,nv in pairs (newUnits) do --recursive loop, can't see a way around this
if v["object"]:getName() == nv["object"]:getName() then
valid = false
--update already found unit incase the first detection(s) didn't know type or distance
if v["type"] then
nv["type"] = true
end
if v["distance"] then
nv["distance"] = true
end
end
end
end
if valid then
table.insert(newUnits, v)
end
end
return newUnits
end
function ewrs.getDetectedTargets()
if #ewrs.blueEwrUnits > 0 then
ewrs.currentlyDetectedRedUnits = ewrs.findDetectedTargets("red")
end
if #ewrs.redEwrUnits > 0 then
ewrs.currentlyDetectedBlueUnits = ewrs.findDetectedTargets("blue")
end
end
function ewrs.findDetectedTargets(side)
local units = {}
local ewrUnits = {}
if side == "red" then
ewrUnits = ewrs.blueEwrUnits
elseif side == "blue" then
ewrUnits = ewrs.redEwrUnits
end
for n = 1, #ewrUnits do
local ewrUnit = Unit.getByName(ewrUnits[n])
if ewrUnit ~= nil then
local ewrControl = ewrUnit:getGroup():getController()
local detectedTargets = ewrControl:getDetectedTargets(Controller.Detection.RADAR)
for k,v in pairs (detectedTargets) do
table.insert(units, v)
end
end
end
return ewrs.filterUnits(units)
end
function ewrs.findRadarUnits()
local filter = {}
if ewrs.enableBlueTeam and ewrs.enableRedTeam then
filter = { "[all][plane]", "[all][vehicle]", "[all][ship]"}
elseif ewrs.enableBlueTeam then
filter = { "[blue][plane]", "[blue][vehicle]", "[blue][ship]"}
elseif ewrs.enableRedTeam then
filter = { "[red][plane]", "[red][vehicle]", "[red][ship]"}
end
local all_vecs = mist.makeUnitTable(filter)
local redUnits = {}
local blueUnits = {}
for i = 1, #all_vecs do
local vec = Unit.getByName(all_vecs[i])
if vec ~= nil then
if Unit.isActive(vec) then
local vec_type = Unit.getTypeName(vec)
for n = 1, #ewrs.validSearchRadars do
if ewrs.validSearchRadars[n] == vec_type and Unit.getCoalition(vec) == 2 then
table.insert(blueUnits, Unit.getName(vec))
break
end
if ewrs.validSearchRadars[n] == vec_type and Unit.getCoalition(vec) == 1 then
table.insert(redUnits, Unit.getName(vec))
break
end
end --for n = 1, #ewrs.validSearchRadars do
end --if Unit.isActive(vec) then
end --if vec ~= nil then
end --for i = 1, #all_vecs do
ewrs.blueEwrUnits = blueUnits
ewrs.redEwrUnits = redUnits
end
function ewrs.addGroupSettings(groupID)
ewrs.groupSettings[groupID] = {}
ewrs.groupSettings[groupID].reference = ewrs.defaultReference
ewrs.groupSettings[groupID].measurements = ewrs.defaultMeasurements
ewrs.groupSettings[groupID].messages = true
end
function ewrs.setGroupReference(args)
local groupID = args[1]
ewrs.groupSettings[tostring(groupID)].reference = args[2]
trigger.action.outTextForGroup(groupID,"Reference changed to "..args[2],ewrs.messageDisplayTime)
end
function ewrs.setGroupMeasurements(args)
local groupID = args[1]
ewrs.groupSettings[tostring(groupID)].measurements = args[2]
trigger.action.outTextForGroup(groupID,"Measurement units changed to "..args[2],ewrs.messageDisplayTime)
end
function ewrs.setGroupMessages(args)
local groupID = args[1]
local onOff
if args[2] then onOff = "on" else onOff = "off" end
ewrs.groupSettings[tostring(groupID)].messages = args[2]
trigger.action.outTextForGroup(groupID,"Picture reports for group turned "..onOff,ewrs.messageDisplayTime)
end
function ewrs.buildF10Menu()
local status, result = pcall(function()
for i = 1, #ewrs.activePlayers do
local groupID = ewrs.activePlayers[i].groupID
local stringGroupID = tostring(groupID)
if ewrs.builtF10Menus[stringGroupID] == nil then
local rootPath = missionCommands.addSubMenuForGroup(groupID, "EWRS")
if ewrs.allowBogeyDope then
missionCommands.addCommandForGroup(groupID, "Request Bogey Dope",rootPath,ewrs.onDemandMessage,{groupID,true})
end
if ewrs.onDemand then
missionCommands.addCommandForGroup(groupID, "Request Picture",rootPath,ewrs.onDemandMessage,{groupID})
end
if ewrs.allowFriendlyPicture then
missionCommands.addCommandForGroup(groupID, "Request Friendly Picture",rootPath,ewrs.friendlyPicture,{groupID})
end
if not ewrs.restrictToOneReference then
local referenceSetPath = missionCommands.addSubMenuForGroup(groupID,"Set GROUP's reference point", rootPath)
missionCommands.addCommandForGroup(groupID, "Set to Bullseye",referenceSetPath,ewrs.setGroupReference,{groupID, "bulls"})
missionCommands.addCommandForGroup(groupID, "Set to Self",referenceSetPath,ewrs.setGroupReference,{groupID, "self"})
end
local measurementsSetPath = missionCommands.addSubMenuForGroup(groupID,"Set GROUP's measurement units",rootPath)
missionCommands.addCommandForGroup(groupID, "Set to Imperial (feet, knts)",measurementsSetPath,ewrs.setGroupMeasurements,{groupID, "imperial"})
missionCommands.addCommandForGroup(groupID, "Set to Metric (meters, km/h)",measurementsSetPath,ewrs.setGroupMeasurements,{groupID, "metric"})
if not ewrs.onDemand then
local messageOnOffPath = missionCommands.addSubMenuForGroup(groupID, "Turn Picture Report On/Off",rootPath)
missionCommands.addCommandForGroup(groupID, "Message ON", messageOnOffPath, ewrs.setGroupMessages, {groupID, true})
missionCommands.addCommandForGroup(groupID, "Message OFF", messageOnOffPath, ewrs.setGroupMessages, {groupID, false})
end
ewrs.builtF10Menus[stringGroupID] = true
end
end
end)
if not status then
env.error(string.format("EWRS buildF10Menu Error: %s", result))
end
end
--temp fix for ground units being detected by radar - FIXED
--[[ Leaving this here just in case I introduce threat based filtering, saves me writing it again
ewrs.validThreats = {
["A-10A"] = true,
["A-10C"] = true,
["A-50"] = true,
["AH-1W"] = true,
["AH-64A"] = true,
["AH-64D"] = true,
["An-26B"] = true,
["An-30M"] = true,
["B-1B"] = true,
["B-52H"] = true,
["Bf-109K-4"] = true,
["C-101CC"] = true,
["C-101EB"] = true,
["C-130"] = true,
["C-17A"] = true,
["CH-47D"] = true,
["CH-53E"] = true,
["E-2D"] = true,
["E-2C"] = true,
["E-3A"] = true,
["F-111F"] = true,
["F-117A"] = true,
["F-14A"] = true,
["F-15C"] = true,
["F-15E"] = true,
["F-16A"] = true,
["F-16A MLU"] = true,
["F-16C bl.50"] = true,
["F-16C bl.52d"] = true,
["F-4E"] = true,
["F-5E"] = true,
["F-5E-3"] = true,
["F-86F Sabre"] = true,
["F/A-18A"] = true,
["F/A-18C"] = true,
["FW-190D9"] = true,
["Hawk"] = true,
["IL-76MD"] = true,
["IL-78M"] = true,
["KC-135"] = true,
["Ka-27"] = true,
["Ka-50"] = true,
["Ka-52"] = true,
["L-39C"] = true,
["L-39ZA"] = true,
["M-2000C"] = true,
["MQ-9 Reaper"] = true,
["Mi-24V"] = true,
["Mi-26"] = true,
["Mi-28N"] = true,
["Mi-8MT"] = true,
["MiG-15bis"] = true,
["MiG-21Bis"] = true,
["MiG-23MLD"] = true,
["MiG-25PD"] = true,
["MiG-25RBT"] = true,
["MiG-27K"] = true,
["MiG-29A"] = true,
["MiG-29G"] = true,
["MiG-29K"] = true,
["MiG-29S"] = true,
["MiG-31"] = true,
["Mirage 2000-5"] = true,
["OH-58D"] = true,
["P-51D"] = true,
["RQ-1A Predator"] = true,
["S-3B"] = true,
["S-3B Tanker"] = true,
["SH-3W"] = true,
["SH-60B"] = true,
["Su-17M4"] = true,
["Su-24M"] = true,
["Su-24MR"] = true,
["Su-25"] = true,
["Su-25T"] = true,
["Su-25TM"] = true,
["Su-27"] = true,
["Su-30"] = true,
["Su-33"] = true,
["Su-34"] = true,
["TF-51D"] = true,
["Tornado GR4"] = true,
["Tornado IDS"] = true,
["Tu-142"] = true,
["Tu-160"] = true,
["Tu-22M3"] = true,
["Tu-95MS"] = true,
["UH-1H"] = true,
["UH-60A"] = true,
["Yak-40"] = true,
}
]]
--SCRIPT INIT
ewrs.currentlyDetectedRedUnits = {}
ewrs.currentlyDetectedBlueUnits = {}
ewrs.redEwrUnits = {}
ewrs.blueEwrUnits = {}
ewrs.activePlayers = {}
ewrs.groupSettings = {}
ewrs.builtF10Menus = {}
ewrs.notAvailable = 999999
ewrs.update()
if not ewrs.onDemand then
timer.scheduleFunction(ewrs.displayMessageToAll, nil, timer.getTime() + ewrs.messageUpdateInterval)
end
trigger.action.outText("EWRS by Steggles is now running",15)
env.info("EWRS Running")
--[[
TODO:
- Add check on friendly picture to not give one if no AWACS / EWR units are active. Doesn't use radar info anyway. Maybe just leave it to help out people with SA? Feedback Please!!
- Clean up functions and arguments from bogeyDope and friendly picture additions
- Threat based filtering if theres interest.
]]

View File

@ -0,0 +1,12 @@
{
"nameInUI": "EWRS",
"defaultValue": false,
"specificOptions": [],
"scriptsWorkOrders": [
{
"file": "ewrs.lua",
"mnemonic": "ewrs"
}
],
"configurationWorkOrders": []
}

View File

@ -2,5 +2,6 @@
"base",
"jtacautolase",
"skynetiads",
"ewrs",
"herculescargo"
]