env.setErrorMessageBoxEnabled(true) -- Enable messageboxes for Lua errors DCSEx = {} Library = {} TUM = {} TUM.VERSION_NUMBER = 1 TUM.VERSION_STRING = "0.1.250722" TUM.DEBUG_MODE = true -------------------------------------- --- Logging system -------------------------------------- TUM.logLevel = { TRACE = -2, DEBUG = -1, INFO = 0, WARNING = 1, ERROR = 2 } TUM.Logger = {} function TUM.Logger.splitText(text) local tbl = {} while text:len() > 4000 do local sub = text:sub(1, 4000) text = text:sub(4001) table.insert(tbl, sub) end table.insert(tbl, text) return tbl end function TUM.Logger.formatText(text, ...) if not text then return "" end if type(text) ~= 'string' then text = TUM.p(text) else local args = ... if args and args.n and args.n > 0 then local pArgs = {} for i=1,args.n do pArgs[i] = TUM.p(args[i]) end text = text:format(unpack(pArgs)) end end local fName = nil local cLine = nil if debug and debug.getinfo then local dInfo = debug.getinfo(3) fName = dInfo.name cLine = dInfo.currentline -- local fsrc = dinfo.short_src --local fLine = dInfo.linedefined end if fName and cLine then return fName .. '|' .. cLine .. ': ' .. text elseif cLine then return cLine .. ': ' .. text else return ' ' .. text end end function TUM.Logger.print(level, text) local texts = TUM.Logger.splitText(text) local levelChar = 'E' local logFunction = function(messageForLogfile, messageForUser) trigger.action.outText("ERROR: "..messageForUser, 3600) env.error(messageForLogfile) end if level == TUM.logLevel.WARNING then levelChar = 'W' logFunction = function(messageForLogfile, messageForUser) trigger.action.outText("WARNING: "..messageForUser, 10) env.warning(messageForLogfile) end elseif level == TUM.logLevel.INFO then levelChar = 'I' logFunction = function(messageForLogfile, messageForUser) if TUM.DEBUG_MODE then -- Info messages are only printed out if debug mode is enabled trigger.action.outText(messageForUser, 3) end env.info(messageForLogfile) end elseif level == TUM.logLevel.DEBUG then levelChar = 'D' logFunction = env.info elseif level == TUM.logLevel.TRACE then levelChar = 'T' logFunction = env.info end for i = 1, #texts do if i == 1 then local theText = 'TUM|' .. levelChar .. '|' .. texts[i] logFunction(theText, texts[i]) else local theText = texts[i] logFunction(theText, theText) end end end function TUM.Logger.error(text, ...) text = TUM.Logger.formatText(text, arg) local mText = text if debug and debug.traceback then mText = mText .. "\n" .. debug.traceback() end TUM.Logger.print(TUM.logLevel.ERROR, mText) end function TUM.Logger.warn(text, ...) text = TUM.Logger.formatText(text, arg) TUM.Logger.print(TUM.logLevel.WARNING, text) end function TUM.Logger.info(text, ...) text = TUM.Logger.formatText(text, arg) TUM.Logger.print(TUM.logLevel.INFO, text) end function TUM.Logger.debug(text, ...) if TUM.DEBUG_MODE then text = TUM.Logger.formatText(text, arg) TUM.Logger.print(TUM.logLevel.DEBUG, text) end end function TUM.Logger.trace(text, ...) if TUM.DEBUG_MODE then text = TUM.Logger.formatText(text, arg) TUM.Logger.print(TUM.logLevel.TRACE, text) end end ------------------------------------- -- Prints and logs a debug message -- @param message The message -- @param logLevel Is it a warning, error or info messages (as defined in TUM.logLevel). Info messages are not printed out unless debug mode is enabled. ------------------------------------- function TUM.log(message, logLevel) logLevel = logLevel or TUM.logLevel.INFO TUM.Logger.print(logLevel, message) end -------------------------------------- --- Administrative settings -------------------------------------- TUM.administrativeSettings = { -- This table defines the administrative settings for the script. -- These settings can modify the behavior of the script, and can be set by the mission maker via a specific trigger zone's parameters, or via script (defining the TUM.administrativeSettingsValues below) USE_SPECIFIC_RADIOMENU = 1, -- Use a specific radio menu for the mission commands, or use the main one? INITIALIZE_AUTOMATICALLY = 2, -- Automatically initialize the mission when the script is loaded. If false, you must call TUM.initialize() manually. IGNORE_ZONES_STARTINGWITH = 3, -- If set, ignore all zones starting with this string. This is useful to avoid conflicts with other scripts that use the same zone names. ONLY_ZONES_STARTINGWITH = 4, -- If set, only adds zones starting with this string. This is useful to avoid conflicts with other scripts that use the same zone names. } TUM.administrativeSettingsDefaultValues = { -- This table defines the default values for the administrative settings. -- The keys must match the keys in TUM.administrativeSettings [TUM.administrativeSettings.USE_SPECIFIC_RADIOMENU] = false, -- Use a specific radio menu for the mission commands, or use the main one? [TUM.administrativeSettings.INITIALIZE_AUTOMATICALLY] = --[[ VEAF SPECIFIC ]] false, -- Automatically initialize the mission when the script is loaded. If false, you must call TUM.initialize() manually. [TUM.administrativeSettings.IGNORE_ZONES_STARTINGWITH] = nil, -- If set, ignore all zones starting with this string. This is useful to avoid conflicts with other scripts that use the same zone names. [TUM.administrativeSettings.ONLY_ZONES_STARTINGWITH] = nil, -- If set, only adds zones starting with this string. This is useful to avoid conflicts with other scripts that use the same zone names. } TUM.administrativeSettingsValues = { -- This table defines the administrative settings values for the script. -- The keys must match the keys in TUM.administrativeSettings -- If set, these values will prevail over both the default values in TUM.administrativeSettings and the values set by the mission maker via a specific trigger zone's parameters. } --- Returns the value of the administrative setting with the given key function TUM.administrativeSettings.getValue(key) if TUM.administrativeSettingsValues[key] ~= nil then return TUM.administrativeSettingsValues[key] else return TUM.administrativeSettingsDefaultValues[key] end end --- Sets the value of the administrative setting with the given key function TUM.administrativeSettings.setValue(key, value) -- check if the key is in the administrative settings table local foundKey = false for _, v in pairs(TUM.administrativeSettings) do if v == key then foundKey = true break end end if not foundKey then TUM.log("Tried to set an unknown administrative setting: "..tostring(key), TUM.logLevel.ERROR) return nil end TUM.administrativeSettingsValues[key] = value end --- Takes all the values from (in order of priority): --- 1. The TUM.administrativeSettingsValues table (optionnaly set by script) --- 2. The trigger zone parameters (set by the mission maker) --- 3. The TUM.administrativeSettingsDefaultValues table (default values) function TUM.administrativeSettings.initializeSettings() local ADMIN_ZONE_NAME = "TUM_Administrative_Settings" -- The name of the administrative settings trigger zone local adminZone = DCSEx.zones.getByName(ADMIN_ZONE_NAME) for key, _ in pairs(TUM.administrativeSettings) do local value = nil if TUM.administrativeSettingsValues[TUM.administrativeSettings[key]] then -- Check if the value is set by script value = TUM.administrativeSettingsValues[TUM.administrativeSettings[key]] end if value == nil and adminZone then -- If the value is not set by script, check the trigger zone parameters local zoneValue = DCSEx.zones.getProperty(adminZone, key) if zoneValue ~= nil then value = zoneValue end end if value == nil then -- If the value is not set by script or trigger zone, use the default value value = TUM.administrativeSettingsDefaultValues[TUM.administrativeSettings[key]] end TUM.administrativeSettingsValues[TUM.administrativeSettings[key]] = value end end -------------------------------------- --- Radio menu for the mission commands -------------------------------------- TUM.rootMenu = nil function TUM.getOrCreateRootMenu(reset) -- Get or create the root menu for the mission commands; if reset is true, the menu will be cleared and recreated if reset then missionCommands.removeItem(TUM.rootMenu) -- Clear the menu TUM.rootMenu = nil TUM.getOrCreateRootMenu() -- Recreate the root menu end if not TUM.rootMenu then if TUM.administrativeSettings.getValue(TUM.administrativeSettings.USE_SPECIFIC_RADIOMENU) then local rootMenuTitle = "✈ TUM" TUM.rootMenu = missionCommands.addSubMenu(rootMenuTitle) end end return TUM.rootMenu end -------------------------------------- -- ==================================================================================== -- (DCS LUA ADD-ON) CONVERTER - UNITS CONVERSION FUNCTIONS -- -- DCSEx.converter.celsiusToFahrenheit(t) -- DCSEx.converter.degreesToRadians(degrees) -- DCSEx.converter.fahrenheitToCelsius(fahrenheit) -- DCSEx.converter.feetToMeters(feet) -- DCSEx.converter.kelvinToCelsius(t) -- DCSEx.converter.kelvinToFahrenheit(t) -- DCSEx.converter.kmphToMps(kmph) -- DCSEx.converter.knotsToMps(knots) -- DCSEx.converter.metersToFeet(meters) -- DCSEx.converter.metersToNM(meters) -- DCSEx.converter.mpsToKmph(mps) -- DCSEx.converter.mpsToKnots(mps) -- DCSEx.converter.nmToMeters(nm) -- DCSEx.converter.radiansToDegrees(radians) -- ==================================================================================== DCSEx.converter = {} ------------------------------------- -- Converts Celsius degrees to Fahrenheit -- @param t Temperature in Celsius degrees -- @return Temperature in Fahrenheit degrees ------------------------------------- function DCSEx.converter.celsiusToFahrenheit(t) return t * (9 / 5) + 32 end ------------------------------------- -- Converts angle in degrees to radians. -- @param degrees Angle in degrees -- @return Angle in radians ------------------------------------- function DCSEx.converter.degreesToRadians(degrees) return degrees * math.pi / 180 end ------------------------------------- -- Converts Fahrenheit degrees to Celsius -- @param fahrenheit Temperature in Fahrenheit degrees -- @return Temperature in Celsius degrees ------------------------------------- function DCSEx.converter.fahrenheitToCelsius(fahrenheit) return (fahrenheit - 32) * (5 / 9) end ------------------------------------- -- Converts feet to meters. -- @param feet Distance in feet -- @return Distance in meters ------------------------------------- function DCSEx.converter.feetToMeters(feet) return feet * 0.3048 end ------------------------------------- -- Converts Kelvin degrees to Celsius -- @param kelvin Temperature in Kelvin degrees -- @return Temperature in Celsius degrees ------------------------------------- function DCSEx.converter.kelvinToCelsius(t) return t - 273.15 end ------------------------------------- -- Converts Kelvin degrees to Fahrenheit -- @param kelvin Temperature in Kelvin degrees -- @return Temperature in Fahrenheit degrees ------------------------------------- function DCSEx.converter.kelvinToFahrenheit(t) return DCSEx.converter.celsiusToFahrenheit(DCSEx.converter.kelvinToCelsius(t)) end ------------------------------------- -- Converts kilometers per hour to meters per second. -- @param kmph speed in km/h -- @return speed in m/s ------------------------------------- function DCSEx.converter.kmphToMps(kmph) return kmph / 3.6 end ------------------------------------- -- Converts knots to meters per second. -- @param knots speed in knots -- @return speed in m/s ------------------------------------- function DCSEx.converter.knotsToMps(knots) return knots * 1852 / 3600 end ------------------------------------- -- Converts meters to feet. -- @param meters distance in meters -- @return distance in feet ------------------------------------- function DCSEx.converter.metersToFeet(meters) return meters / 0.3048 end ------------------------------------- -- Converts meters to nautical miles. -- @param meters distance in meters -- @return distance in nautical miles ------------------------------------- function DCSEx.converter.metersToNM(meters) return meters / 1852 end ------------------------------------- -- Converts meters per second to kilometers per hour. -- @param mps speed in m/s -- @return speed in km/h ------------------------------------- function DCSEx.converter.mpsToKmph(mps) return mps * 3.6 end ------------------------------------- -- Converts meters per second to knots. -- @param mps speed in m/s -- @return speed in knots ------------------------------------- function DCSEx.converter.mpsToKnots(mps) return mps * 3600 / 1852 end ------------------------------------- -- Converts nautical miles to meters. -- @param nm distance in nautical miles -- @return distance in meters ------------------------------------- function DCSEx.converter.nmToMeters(nm) return nm * 1852 end ------------------------------------- -- Converts angle in radians to degrees. -- @param degrees Angle in radians -- @return Angle in degrees ------------------------------------- function DCSEx.converter.radiansToDegrees(radians) return radians * 180 / math.pi end -- ==================================================================================== -- DCSTOOLS - FUNCTIONS LINKED TO DCS WORLD RULES AND TABLES -- ==================================================================================== -- DCSEx.dcs.getBRAA(point, refPoint, showAltitude, metricSystem, casualFormat) -- DCSEx.dcs.getCJTFForCoalition(coalitionID) -- DCSEx.dcs.getCoalitionAsString(coalitionID) -- DCSEx.dcs.getCoalitionColor(coalitionID, alpha) -- DCSEx.dcs.getGroupCenterPoint(group) -- DCSEx.dcs.getGroupIDAsNumber(group) -- DCSEx.dcs.getNearestObject(refPoint, objectTable) -- DCSEx.dcs.getNearestObjects(refPoint, objectTable, maxCount) -- DCSEx.dcs.getNearestPoints(refPoint, pointsTable, maxCount) -- DCSEx.dcs.getOppositeCoalition(coalitionID) -- DCSEx.dcs.getPlayerUnitsInGroup(group) -- DCSEx.dcs.getPlayerUnitsInGroupByID(groupID) -- DCSEx.dcs.getRadioModulationName(modulationID) -- DCSEx.dcs.getObjectIDAsNumber(obj) -- DCSEx.dcs.getUnitTypeFromFamily(unitFamily) -- DCSEx.dcs.getUnitFamilyForDecade(unitFamily, decade) -- TODO: remove? -- ==================================================================================== DCSEx.dcs = { } -- TODO: add description and update file header function DCSEx.dcs.doNothing() end ------------------------------------- -- Gets a BRAA (bearing, range, altitude, aspect) string about a point -- Format is "[bearing to unit] for [distance] at [altitude]" -- @param unit A unit -- @param refPoint Reference point for the bearing and distance -- @param showAltitude Should altitude be displayed? -- @param metricSystem Should metric system units be used? -- @param casualFormat Should the format be casual ("32nm northeast" instead of "45 for 32")? -- @return BRAA, as a string ------------------------------------- function DCSEx.dcs.getBRAA(point, refPoint, showAltitude, metricSystem, casualFormat) casualFormat = casualFormat or false metricSystem = metricSystem or false showAltitude = showAltitude or false if not point.z then point = DCSEx.math.vec2ToVec3(point, "land") end if not refPoint.z then refPoint = DCSEx.math.vec2ToVec3(refPoint, "land") end local braa = nil braa = tostring(DCSEx.math.getBearing(point, refPoint, casualFormat)) local distance = DCSEx.math.getDistance2D(point, refPoint) if metricSystem then distance = distance / 1000.0 else distance = DCSEx.converter.metersToNM(distance) end if casualFormat then if metricSystem then braa = math.ceil(distance).."km "..braa else braa = math.ceil(distance).."nm "..braa end else braa = braa .. " for " .. tostring(math.ceil(distance)) end if showAltitude then local altitude = point.y if metricSystem then altitude = math.floor(point.y / 100) * 100 else altitude = math.floor(DCSEx.converter.metersToFeet(point.y) / 1000) * 1000 end braa = braa .. " at " .. tostring(altitude) if casualFormat then if metricSystem then braa = braa.."m" else braa = braa.."ft" end end end return braa end ------------------------------------- -- Returns the CJTF country for a given coalition -- @param A coalition ID -- @return A country ID (country.id.CJTF_BLUE or country.id.CJTF_RED) ------------------------------------- function DCSEx.dcs.getCJTFForCoalition(coalitionID) if coalitionID == coalition.side.RED then return country.id.CJTF_RED end return country.id.CJTF_BLUE end ------------------------------------- -- Returns the name of a coalition, as a string ("blue", "red" or "neutral") -- @param A coalition ID -- @return A string ------------------------------------- function DCSEx.dcs.getCoalitionAsString(coalitionID) if coalitionID == coalition.side.NEUTRAL then return "neutral" end if coalitionID == coalition.side.RED then return "red" end if coalitionID == coalition.side.BLUE then return "blue" end return nil end ------------------------------------- -- Returns the RGBA color table for the given coalition, accoding to NATO symbology colors -- @param coalitionID A coalition side -- @param alpha (optional) Alpha. Default is 1 -- @return A RGBA color table ------------------------------------- function DCSEx.dcs.getCoalitionColor(coalitionID, alpha) alpha = alpha or 1.0 if coalitionID == coalition.side.RED then return {0.97, 0.52, 0.51, alpha} elseif coalitionID == coalition.side.BLUE then return {0.52, 0.87, 0.99, alpha} else return {0.5, 0.5, 0.5, alpha} end end -- TODO: description function DCSEx.dcs.getFirstUnitCallsign(group) if not group then return nil end local units = group:getUnits() if not units then return nil end local unit0 = units[1] if not unit0 then return nil end return unit0:getCallsign() end ------------------------------------- -- Returns a vec3 point at the center of all units of a group -- @param group A group object -- @return A vec3 ------------------------------------- function DCSEx.dcs.getGroupCenterPoint(group) if not group then return nil end local units = group:getUnits() if not units or #units == 0 then return nil end local centerPoint = { x = 0, y = 0, z = 0} for _,u in pairs(units) do local uPoint = u:getPoint() centerPoint.x = centerPoint.x + uPoint.x centerPoint.y = centerPoint.y + uPoint.y centerPoint.z = centerPoint.z + uPoint.z end centerPoint.x = centerPoint.x / #units centerPoint.y = centerPoint.y / #units centerPoint.z = centerPoint.z / #units return centerPoint end ------------------------------------- -- Returns the ID of a group as a number (here to fix a bug where sometimes ID is returned as a string) -- @param group A group table -- @return An ID (as an number) or nil if group is nil or has no ID ------------------------------------- function DCSEx.dcs.getGroupIDAsNumber(group) if not group then return nil end return tonumber(group:getID()) end ------------------------------------- -- Returns the object nearest (in a 2D plane) from a given point -- @param refPoint A reference point, as a vec2 or vec3 -- @param objectTable A table of DCS objects -- @return The object nearest from the point, or nil if no object was found ------------------------------------- function DCSEx.dcs.getNearestObject(refPoint, objectTable) local nearestObjects = DCSEx.dcs.getNearestObjects(refPoint, objectTable, 1) if #nearestObjects == 0 then return nil end return nearestObjects[1] end ------------------------------------- -- Returns the nearest objects (in a 2D plane) from a given point -- @param refPoint A reference point, as a vec2 or vec3 -- @param objectTable A table of DCS objects -- @param maxCount (optional) Maximum number of objects to return -- @return A table of objects, sorted by distance ------------------------------------- function DCSEx.dcs.getNearestObjects(refPoint, objectTable, maxCount) if not refPoint then return DCSEx.table.deepCopy(objectTable) end refPoint = DCSEx.math.vec3ToVec2(refPoint) local sortedObjects = {} local sortedKeys = {} for i,o in pairs(objectTable) do local distance = DCSEx.math.getDistance2D(refPoint, o:getPoint()) sortedObjects[distance] = i table.insert(sortedKeys, distance) end table.sort(sortedKeys) local sortedList = {} for _,v in ipairs(sortedKeys) do if maxCount and #sortedList >= maxCount then break end table.insert(sortedList, objectTable[sortedObjects[v]]) end return sortedList end ------------------------------------- -- Returns the nearest points (in a 2D plane) from a given point -- @param refPoint A reference point, as a vec2 or vec3 -- @param objectTable A table of points (vec2 or vec3) -- @param maxCount (optional) Maximum number of points to return -- @return A table of points, sorted by distance ------------------------------------- function DCSEx.dcs.getNearestPoints(refPoint, pointsTable, maxCount) if not refPoint then return DCSEx.table.deepCopy(pointsTable) end refPoint = DCSEx.math.vec3ToVec2(refPoint) local sortedPoints = {} local sortedKeys = {} for i,pt in pairs(pointsTable) do local distance = DCSEx.math.getDistance2D(refPoint, pt) sortedPoints[distance] = i table.insert(sortedKeys, distance) end table.sort(sortedKeys) local sortedList = {} for _,v in ipairs(sortedKeys) do if maxCount and #sortedList >= maxCount then break end table.insert(sortedList, pointsTable[sortedPoints[v]]) end return sortedList end ------------------------------------- -- Returns the coalition opposed to the provided coalition (coalition.side.NEUTRAL still returns NEUTRAL) -- @param group A coalition -- @return Another coalition ------------------------------------- function DCSEx.dcs.getOppositeCoalition(coalitionID) if coalitionID == coalition.side.RED then return coalition.side.BLUE end if coalitionID == coalition.side.BLUE then return coalition.side.RED end return coalition.side.NEUTRAL end ------------------------------------- -- Returns all player-controlled units in a group -- @param group A group object -- @return A table of unit objects ------------------------------------- function DCSEx.dcs.getPlayerUnitsInGroup(group) if not group then return nil end local units = group:getUnits() if not units then return { } end local players = {} for _,u in pairs(units) do if u:getPlayerName() then table.insert(players, u) end end return players end ------------------------------------- -- Returns all player-controlled units in the group with the given ID -- @param groupID A group ID -- @return A table of unit objects ------------------------------------- function DCSEx.dcs.getPlayerUnitsInGroupByID(groupID) return DCSEx.dcs.getPlayerUnitsInGroup(DCSEx.world.getGroupByID(groupID)) end ------------------------------------- -- Returns a radio modulation type as a string -- @param modulationID A modulation ID (from radio.modulation enum) -- @return A string ------------------------------------- function DCSEx.dcs.getRadioModulationName(modulationID) if modulationID == radio.modulation.FM then return "FM" end return "AM" end ------------------------------------- -- Returns a remplacement unit family for given family if it's not available in this decade (e.g. SAMs in the 1940s). Else returns the original family. -- @param unitFamily An unit family -- @param decade (optional) A decade, or the current decade from env.mission.date.Year -- @return An unit family ------------------------------------- function DCSEx.dcs.getUnitFamilyForDecade(unitFamily, decade) -- TODO -- decade = decade or envMission.getDecade() -- if decade < 1990 then -- if unitFamily == DCSEx.enums.unitFamily.UAVs then -- unitFamily = DCSEx.enums.unitFamily.AttackHelicopters -- end -- end -- if decade < 1970 then -- if unitFamily == DCSEx.enums.unitFamily.AWACS then -- unitFamily = DCSEx.enums.unitFamily.Transports -- elseif unitFamily == DCSEx.enums.unitFamily.SAMShort then -- unitFamily = DCSEx.enums.unitFamily.MobileAAA -- elseif unitFamily == DCSEx.enums.unitFamily.SAMShortIR then -- unitFamily = DCSEx.enums.unitFamily.MobileAAA -- end -- end -- if decade < 1960 then -- if unitFamily == DCSEx.enums.unitFamily.AttackHelicopters then -- unitFamily = DCSEx.enums.unitFamily.Fighters -- elseif unitFamily == DCSEx.enums.unitFamily.MANPADS then -- unitFamily = DCSEx.enums.unitFamily.Infantry -- elseif unitFamily == DCSEx.enums.unitFamily.SAMLong then -- unitFamily = DCSEx.enums.unitFamily.StaticAAA -- elseif unitFamily == DCSEx.enums.unitFamily.SAMMedium then -- unitFamily = DCSEx.enums.unitFamily.StaticAAA -- elseif unitFamily == DCSEx.enums.unitFamily.SSMissiles then -- unitFamily = DCSEx.enums.unitFamily.Artillery -- elseif unitFamily == DCSEx.enums.unitFamily.TransportHelicopters then -- unitFamily = DCSEx.enums.unitFamily.Transports -- end -- end -- if decade < 1950 then -- if unitFamily == DCSEx.enums.unitFamily.MobileAAA then -- unitFamily = DCSEx.enums.unitFamily.APC -- elseif unitFamily == DCSEx.enums.unitFamily.Tankers then -- unitFamily = DCSEx.enums.unitFamily.Transports -- end -- end return unitFamily end -- TODO: description function DCSEx.dcs.getUnitTypeFromFamily(unitFamily) return math.floor(unitFamily / 100) end ------------------------------------- -- Returns the ID of an object as a number (here to fix a bug where sometimes ID is returned as a string) -- @param obj An object (unit, static object...) -- @return An ID (as an number) or nil if unit is nil or has no ID ------------------------------------- function DCSEx.dcs.getObjectIDAsNumber(obj) if not obj then return nil end return tonumber(obj:getID()) end -- TODO: description & file header function DCSEx.dcs.loadMission(fileName) net.dostring_in("mission", string.format("a_load_mission(\"%s\")", fileName)) end -- TODO: description & file header -- function DCSEx.dcs.isMultiplayer() -- if #net.get_player_list() > 0 then return true end -- if dcs and dcs.isServer() == true then return true end -- return false -- end -- TODO: a_end_mission -- TODO: description & file header function DCSEx.dcs.outPicture(fileName, durationSeconds, clearView, startDelay, horizontalAlign, verticalAlign, size, sizeUnits) clearView = clearView or false startDelay = startDelay or 0 horizontalAlign = horizontalAlign or 1 verticalAlign = verticalAlign or 1 size = size or 100 sizeUnits = sizeUnits or 0 if clearView then clearView = "true" else clearView = "false" end net.dostring_in("mission", string.format("a_out_picture(getValueResourceByKey(\"%s\"), %d, %s, %d, \"%d\", \"%d\", %d, \"%d\")", fileName, durationSeconds, clearView, startDelay, horizontalAlign, verticalAlign, size, sizeUnits)) end DCSEx.enums = {} ------------------------------------- -- Line types for map markers. The enum is missing from DCS ------------------------------------- DCSEx.enums.lineType = { NO_LINE = 0, SOLID = 1, DASHED = 2, DOTTED = 3, DOT_DASH = 4, LONG_DASH = 5, TWO_DASH = 6, } ------------------------------------- -- Event to check to see if a task/objective is complete ------------------------------------- DCSEx.enums.spawnPointType = { LAND_LARGE = 1, LAND_MEDIUM = 2, LAND_SMALL = 3, SEA = 4, } ------------------------------------- -- Event to check to see if a task/objective is complete ------------------------------------- DCSEx.enums.taskEvent = { DESTROY = 1, DESTROY_SCENERY = 2, LAND = 3, } ------------------------------------- -- Families of mission tasks ------------------------------------- DCSEx.enums.taskFamily = { ANTISHIP = 1, -- CAP = 2, -- TODO -- CAS = 3, -- TODO GROUND_ATTACK = 2, -- 4 -- HELICOPTER = XXX, -- 5 -- HELO_HUNT = XXX, -- 6 INTERCEPTION = 3, -- 7 -- OCA = XXX, -- 8 SEAD = 4, --9 STRIKE = 5, -- 10 } ------------------------------------- -- Special events for tasks ------------------------------------- DCSEx.enums.taskFlag = { ALLOW_JTAC = 1, DESTROY_TRACK_RADARS_ONLY = 2, MOVING = 3, ON_ROADS = 4, SCENERY_TARGET = 5 } ------------------------------------- -- Enumerates the various time periods during which DCS World missions can take place ------------------------------------- DCSEx.enums.timePeriod = { WORLD_WAR_2 = 1, KOREA_WAR = 2, VIETNAM_WAR = 3, COLD_WAR = 4, MODERN = 5 } ------------------------------------- -- Type of unit families. Hundreds digit must match the value in the Unit.Category enum ------------------------------------- DCSEx.enums.unitFamily = { AIRDEFENSE_MANPADS = 251, AIRDEFENSE_AAA_MOBILE = 252, AIRDEFENSE_AAA_STATIC = 253, AIRDEFENSE_SAM_LONG = 254, AIRDEFENSE_SAM_MEDIUM = 255, AIRDEFENSE_SAM_SHORT = 256, AIRDEFENSE_SAM_SHORT_IR = 257, PLANE_ATTACK = 001, PLANE_AWACS = 002, PLANE_BOMBER = 003, PLANE_FIGHTER = 004, PLANE_INTERCEPTOR = 005, PLANE_TANKER = 006, PLANE_TRANSPORT = 007, PLANE_UAV = 008, GROUND_APC = 201, GROUND_ARTILLERY = 202, GROUND_INFANTRY = 203, GROUND_MBT = 204, GROUND_SS_MISSILE = 205, GROUND_UNARMED = 206, HELICOPTER_ATTACK = 101, HELICOPTER_TRANSPORT = 102, SHIP_CARGO = 301, SHIP_CARRIER = 302, SHIP_CRUISER = 303, SHIP_FRIGATE = 304, SHIP_LIGHT = 305, SHIP_MISSILE_BOAT = 306, SHIP_SUBMARINE = 307, STATIC_SCENERY = 401, STATIC_STRUCTURE = 402 } DCSEx.enums.victoryCondition = { DESTROY = 1, DESTROY_NO_AIR_DEFENSE = 2, DESTROY_SCENERY = 3, DESTROY_TRACK_RADARS_ONLY = 4, -- for SEAD tasks LAND_NEAR = 5, } -- ==================================================================================== -- (DCS LUA ADD-ON) ENVMISSION - FUNCTIONS RELATED TO THE ENV.MISSION TABLE -- -- DCSEx.envMission.getDecade(yearOffset) -- DCSEx.envMission.getDistanceToNearestPlayerSpawnPoint(point) -- DCSEx.envMission.getGroup(groupID) -- DCSEx.envMission.getGroups(sideID) -- DCSEx.envMission.getPlayerGroups(coalitionId) -- DCSEx.envMission.getPlayerGroupsCenterPoint(coalitionId) -- ==================================================================================== DCSEx.envMission = {} ------------------------------------- -- Returns the decade during which the mission takes place (1940 to 2010) -- @param yearOffset An offset to apply to the actual year -- @return The decade, as a number ------------------------------------- function DCSEx.envMission.getDecade(yearOffset) return DCSEx.math.clamp(math.floor((env.mission.date.Year + (yearOffset or 0)) / 10) * 10, 1940, 2010) end ------------------------------------- -- Returns the distance to the nearest player spawn point -- @param coalition Coalition the players belong to -- @param point A vec3 or vec2 -- @return The distance, in meters, to the nearest player spawn point, or nil if no player spawn points are present ------------------------------------- function DCSEx.envMission.getDistanceToNearestPlayerSpawnPoint(coalition, point) point = DCSEx.math.vec3ToVec2(point) local playerSlots = DCSEx.envMission.getPlayerGroups(coalition) if #playerSlots == 0 then return nil end local nearestPlayer = 999999999999999999999 for _,p in pairs(playerSlots) do local dist = DCSEx.math.getDistance2D(point, p) if dist < nearestPlayer then nearestPlayer = dist end end return nearestPlayer end ------------------------------------- -- Gets information about a group -- @param groupID Group ID -- @return Missiondata group table or nil if ID doesn't exist ------------------------------------- function DCSEx.envMission.getGroup(groupID) local allGroups = DCSEx.envMission.getGroups() for _, g in ipairs(allGroups) do if g.groupId == groupID then return g end end return nil end ------------------------------------- -- Gets all unit groups -- @param sideID Coalition ID (coalition.side.*), or nil to return unit groups from all coalitions -- @return Table of missiondata group tables ------------------------------------- function DCSEx.envMission.getGroups(sideID) -- Group data are located in coalition[COAL_ID_AS_STRING].country[N][UNIT_CATEGORY_AS_STRING].group[] -- (e.g. coalition["blue"].country[1]["plane"].group[1]) local validCoalitions = { [0] = "neutrals", [1] = "red", [2] = "blue"} -- by default, search all coalitions if sideID == coalition.side.BLUE then validCoalitions = { [2] = "blue"} elseif sideID == coalition.side.RED then validCoalitions = { [1] = "red" } elseif sideID == coalition.side.NEUTRAL then validCoalitions = { [0] = "neutrals" } end local groups = {} for coalID, coalName in pairs(validCoalitions) do -- In each coalition... if env.mission.coalition[coalName] then -- (if coalition exists) for _, countryData in pairs(env.mission.coalition[coalName].country) do -- search each country for _, uType in pairs({"helicopter", "plane", "ship", "static", "vehicle"}) do -- for each unit category if countryData[uType] then -- (if unit category exists) for _,g in pairs(countryData[uType].group) do -- for each group local groupInfo = DCSEx.table.deepCopy(g) groupInfo.coalition = coalID -- store coalition side for later reference table.insert(groups, groupInfo) end end end end end end return groups end ------------------------------------- -- Gets all player groups -- @param coalitionId Coalition ID (coalition.side.*), or nil to return unit groups from all coalitions -- @return Table of missiondata group tables ------------------------------------- function DCSEx.envMission.getPlayerGroups(coalitionId) local allGroups = DCSEx.envMission.getGroups(coalitionId) local playerGroups = {} for _, g in ipairs(allGroups) do local isPlayerGroup = false for _, u in pairs(g.units) do if u.skill == "Player" or u.skill == "Client" then isPlayerGroup = true break end end if isPlayerGroup then table.insert(playerGroups, DCSEx.table.deepCopy(g)) end end return playerGroups end ------------------------------------- -- Return the center 2D point of all player groups -- @param coalitionId Coalition ID (coalition.side.*), or nil to use unit groups from all coalitions -- @return A 2D point, or nil if no player groups ------------------------------------- function DCSEx.envMission.getPlayerGroupsCenterPoint(coalitionId) local pGroups = DCSEx.envMission.getPlayerGroups(coalitionId) if #pGroups == 0 then return nil end local center = { x = 0, y = 0 } for _,g in ipairs(pGroups) do center.x = center.x + g.x center.y = center.y + g.y end center.x = center.x / #pGroups center.y = center.y / #pGroups return center end -- TODO: description & file header function DCSEx.envMission.setBriefing(side, text, picture) text = text or "" text = text:gsub("\n", "\\n") picture = picture or "" net.dostring_in("mission", string.format("a_set_briefing(\"%s\", getValueResourceByKey(\"%s\"), \"%s\")", DCSEx.dcs.getCoalitionAsString(side):lower(), picture, text)) end -- ==================================================================================== -- DCSEx.IO - HANDLES READING/WRITING FILES -- ==================================================================================== -- DCSEx.io.canReadAndWrite() -- DCSEx.io.load(fileName) -- DCSEx.io.save(fileName, values) -- ==================================================================================== DCSEx.io = {} do ------------------------------------- -- Returns true if the IO table has been unsanitized (allowing IO operations) -- and false if it hasn't been -- -- @return A boolean ------------------------------------- function DCSEx.io.canReadAndWrite() return io ~= nil end ------------------------------------- -- Loads a table from a text file -- -- @param fileName Name of the file to read -- @param obfuscate Should the file contents be obfuscated? -- @return A table, or nil if something went wrong ------------------------------------- -- function DCSEx.io.load(fileName, obfuscate) -- obfuscate = obfuscate or false -- TODO: obfuscation -- -- IO table is sanitized, cannot read/write to disk -- if not DCSEx.io.canReadAndWrite() then return nil end -- local saveFile = io.open(fileName, "r") -- if not saveFile then return nil end -- local values = {} -- local rawText = saveFile:read("*all") -- for k, v in string.gmatch(rawText, "(%w+)=(%w+)") do -- local numval = tonumber(v) -- if numval then -- values[k] = tonumber(v) -- else -- values[k] = v -- -- trigger.action.outText("GET value \""..k.."\" AT \""..tostring(v).."\"", 1) -- end -- end -- saveFile:close() -- return values -- end function DCSEx.io.load(fileName) -- IO table is sanitized, cannot read/write to disk if not DCSEx.io.canReadAndWrite() then return nil end local saveFile = io.open(fileName, "r") if not saveFile then return nil end local str = saveFile:read("*all") saveFile:close() return str end ------------------------------------- -- Saves a table to a text file -- -- @param fileName Name of the file to write to -- @param values Key/value table containing the values to save -- @param obfuscate Should the file contents be obfuscated? -- @return True if everything went right, false otherwise ------------------------------------- -- function DCSEx.io.save(fileName, values, obfuscate) -- obfuscate = obfuscate or false -- TODO: obfuscation -- -- IO table is sanitized, cannot read/write to disk -- if not DCSEx.io.canReadAndWrite() then return false end -- -- No values or not a table -- if values == nil then return false end -- if type(values) ~= "table" then return false end -- local saveFile = io.open(fileName, "w") -- if not saveFile then return false end -- for k,v in pairs(values) do -- saveFile:write(k.."="..tostring(v).."\n") -- -- trigger.action.outText("SET value \""..k.."\" TO \""..tostring(v).."\"", 1) -- end -- saveFile:close() -- return true -- end function DCSEx.io.save(fileName, str) -- IO table is sanitized, cannot read/write to disk if not DCSEx.io.canReadAndWrite() then return false end local saveFile = io.open(fileName, "w") if not saveFile then return false end saveFile:write(str) saveFile:close() return true end end -- ==================================================================================== -- (DCS LUA ADD-ON) MATH - EXTENSION TO THE "MATH" TABLE -- -- (Constant) DCSEx.math.TWO_PI -- DCSEx.math.addVec(vecA, vecB) -- DCSEx.math.clamp(val, min, max) -- DCSEx.math.getBearing(point, refPoint, returnAsNESWstring) -- DCSEx.math.getDistance2D(vec2a, vec2b) -- DCSEx.math.getDistance3D(vec3a, vec3b) -- DCSEx.math.getRelativeHeading(point, refObject) -- DCSEx.math.getVec2FromAngle(angle) -- DCSEx.math.isPointInsideCircle(center, radius, vec2) -- DCSEx.math.isPointInsidePolygon(polygon, vec2) -- DCSEx.math.isSamePoint(pointA, pointB) -- DCSEx.math.lerp(val0, val1, t) -- DCSEx.math.multVec2(vec2, mult) -- DCSEx.math.normalizeVec2(vec2) -- DCSEx.math.randomBoolean() -- DCSEx.math.randomFloat(min, max) -- DCSEx.math.randomPointAtDistance(point, distance) -- DCSEx.math.randomPointInCircle(center, radius, minRadius, surfaceType) -- DCSEx.math.randomSign() -- DCSEx.math.toBoolean(val) -- DCSEx.math.vec2ToVec3(vec2, y) -- DCSEx.math.vec3ToVec2(vec3) -- ==================================================================================== DCSEx.math = {} ------------------------------------- -- Constants ------------------------------------- DCSEx.math.TWO_PI = math.pi * 2 ------------------------------------- -- Returns the sum of two vec2 or vec3 -- @param vecA A vector -- @param vecB Another vector -- @return The sum of both vectors ------------------------------------- function DCSEx.math.addVec(vecA, vecB) if vecA.z then return { x = vecA.x + vecB.x, y = vecA.y + vecB.y, z = vecA.z + vecB.z } end return { x = vecA.x + vecB.x, y = vecA.y + vecB.y } end ------------------------------------- -- Clamp a number value between min and max -- @param value The value to clamp -- @param min Minimum allowed value -- @param max Maximum allowed value -- @return Clamped value ------------------------------------- function DCSEx.math.clamp(val, min, max) return math.max(min, math.min(max, val)) end ------------------------------------- -- Gets the bearing between two vectors, in degrees -- @param point A vec2/vec3 -- @param refPoint Vec2/vec3 to use as a reference point -- @param returnAsNESWstring Should the value be returned as a N/S/E/W string instead of a numeric value -- @return Bearing, as a number, in degrees ------------------------------------- function DCSEx.math.getBearing(point, refPoint, returnAsNESWstring) returnAsNESWstring = returnAsNESWstring or false refPoint = refPoint or {x = 0, y = 0} if point.z then point = DCSEx.math.vec3ToVec2(point) end -- Point is a vec3, convert it if refPoint.z then refPoint = DCSEx.math.vec3ToVec2(refPoint) end -- Point is a vec3, convert it local bearing = math.atan2(point.y - refPoint.y, point.x - refPoint.x) if bearing < 0 then bearing = bearing + DCSEx.math.TWO_PI end bearing = math.floor(bearing * (180 / math.pi)) if returnAsNESWstring then bearing = math.floor((bearing / 45.0) + .5) local namesArray = { "north", "northeast", "east", "southeast", "south", "southwest", "west", "northwest" } return namesArray[(bearing % 8) + 1] end return bearing end ------------------------------------- -- Returns the pythagorean distance between two 2D points or the length of a single vector -- @param vec2a A 2D point -- @param vec2b (optional) Another 2D point -- @return Distance between the points ------------------------------------- function DCSEx.math.getDistance2D(vec2a, vec2b) vec2b = vec2b or { x = 0, y = 0 } if vec2a.z then vec2a = DCSEx.math.vec3ToVec2(vec2a) end if vec2b.z then vec2b = DCSEx.math.vec3ToVec2(vec2b) end return math.sqrt((vec2a.x - vec2b.x) ^ 2 + (vec2a.y - vec2b.y) ^ 2) end ------------------------------------- -- Returns the pythagorean distance between two 3D points or the length of a single vector -- @param vec3a A 3D point -- @param vec3b (optional) Another 3D point -- @return Distance between the points ------------------------------------- function DCSEx.math.getDistance3D(vec3a, vec3b) vec3b = vec3b or { x = 0, y = 0, z = 0 } return math.sqrt((vec3a.x - vec3b.x) ^ 2 + (vec3a.y - vec3b.y) ^ 2 + (vec3a.z - vec3b.z) ^ 2) end ------------------------------------- -- Returns the relative heading difference between refObject and a given point -- @param point The point for which to check the relative heading -- @param refObject The reference object against which relative heading should be measured -- @param format (optional) Return format. Possible formats are "clock" (1 o'clock...) or "cardinal" (NNW...) -- @return A number in degrees, or a string if a special format was provided ------------------------------------- function DCSEx.math.getRelativeHeading(point, refObject, format) if not point then return nil end if not refObject then return nil end local unitpos = refObject:getPosition() local bearing = DCSEx.math.getBearing(point, unitpos:getPoint()) local unitBearing = math.atan2(unitpos.x.z, unitpos.x.x) if unitBearing < 0 then unitBearing = unitBearing + DCSEx.math.TWO_PI end unitBearing = math.floor(unitBearing * (180 / math.pi)) local relBearing = bearing - unitBearing if relBearing < 0 then relBearing = relBearing + 360 end if format == "oclock" then local oClock = math.floor(relBearing / 30) if oClock <= 0 then oClock = 12 end return tostring(oClock).." o'clock" elseif format == "cardinal" then return "TODO" -- TODO: cardinal end return math.floor(relBearing) end ------------------------------------- -- Returns an normalized vec2 from an angle/bearing in radians -- @param unit Angle/bearing in radians -- @return A normalized vec2 ------------------------------------- function DCSEx.math.getVec2FromAngle(angle) return {x = math.cos(angle), y = math.sin(angle)} end ------------------------------------- -- Is a point inside a circle? -- @param center The center of the circle, as a vec2 -- @param radius The radius of the circle -- @param vec2 A vec2 -- @return True if vec2 is inside the circle, false otherwise ------------------------------------- function DCSEx.math.isPointInsideCircle(center, radius, vec2) return (vec2.x - center.x) ^ 2 + (vec2.y - center.y) ^ 2 < radius ^ 2 end ------------------------------------- -- Is a point inside a polygon? -- @param vec2[] A polygon, as a table of vec2 -- @param vec2 A vec2 -- @return True if vec2 is inside the polygon, false otherwise ------------------------------------- function DCSEx.math.isPointInsidePolygon(polygon, vec2) if not polygon or not vec2 then return false end local oddNodes = false local j = #polygon for i = 1, #polygon do if (polygon[i].y < vec2.y and polygon[j].y >= vec2.y or polygon[j].y < vec2.y and polygon[i].y >= vec2.y) then if (polygon[i].x + (vec2.y - polygon[i].y) / (polygon[j].y - polygon[i].y) * (polygon[j].x - polygon[i].x) < vec2.x) then oddNodes = not oddNodes end end j = i end return oddNodes end ------------------------------------- -- Compares two 2D or 3D points -- @param pointA a Point2 or Point3 -- @param pointB another Point2 or Point3 -- @return True if points are the same, false otherwise ------------------------------------- function DCSEx.math.isSamePoint(pointA, pointB) if pointA.x ~= pointB.x then return false end if pointA.y ~= pointB.y then return false end if pointA.z or pointB.z then if pointA.z ~= pointB.z then return false end end return true end ------------------------------------- -- Linearly interpolates between two numbers -- @param val0 Value vers l=0 -- @param val1 Value vers l=1 -- @param t Interpolation between 0 and 1 -- @return A number value ------------------------------------- function DCSEx.math.lerp(val0, val1, t) return val0 + t * (val1 - val0); end ------------------------------------- -- Multiplies both the x and y components of a vec2 by a floating-point value -- @param vec2 A vec2 -- @param mult A floating-point value -- @return A vec2 ------------------------------------- function DCSEx.math.multVec2(vec2, mult) return {x = vec2.x * mult, y = vec2.y * mult} end ------------------------------------- -- Returns an normalized vec2 -- @param unit A vec2 -- @return A normalized vec2 ------------------------------------- function DCSEx.math.normalizeVec2(vec2) local length = DCSEx.math.getDistance2D(vec2) return {x = vec2.x / length, y = vec2.y / length} end ------------------------------------- -- Returns a random boolean -- @return A boolean ------------------------------------- function DCSEx.math.randomBoolean() return DCSEx.math.random(1, 2) == 1 end ------------------------------------- -- Returns a random floating-point number between min and max -- @param min Minimum floating-point value -- @param max Maximum floating-point value -- @return A number ------------------------------------- function DCSEx.math.randomFloat(min, max) if min >= max then return min end return min + math.random() * (max - min) end ------------------------------------- -- Returns a random vec2 at a given distance of another vec2 -- @param point Reference point -- @param distance Distance from the reference point -- @return A vec2 ------------------------------------- function DCSEx.math.randomPointAtDistance(point, distance) local angle = math.random() * math.pi * 2.0 local x = point.x + math.cos(angle) * distance local y = point.y + math.sin(angle) * distance return { x = x, y = y } end ------------------------------------- -- Returns a random vec2 in circle of a given center and radius -- @param center Center of the circle as a vec2 -- @param radius Radius of the circle -- @param minRadius (optional) Minimum inner radius circle in which points should not be spawned -- @param surfaceType (optional) If not nil, point must be of given surface type -- @return A vec2 or nil if no point was found ------------------------------------- function DCSEx.math.randomPointInCircle(center, radius, minRadius, surfaceType) local minRadius = minRadius or 0 local dist = minRadius + math.random() * (radius - minRadius) local angle = math.random() * math.pi * 2.0 local point = nil for i=1,36 do local x = center.x + math.cos(angle) * dist local y = center.y + math.sin(angle) * dist point = { x = x, y = y } if not surfaceType then return point end if land.getSurfaceType(point) == surfaceType then return point end angle = angle + 0.174533 -- Increment angle by 10° (in radians) end return nil end ------------------------------------- -- Returns a random sign as a number, -1 or 1 -- @return -1 50% of the time, 1 50% of the time ------------------------------------- function DCSEx.math.randomSign() if math.random() < .5 then return -1 end return 1 end ------------------------------------- -- Converts a value to a boolean -- @param val Value to convert -- @return A boolean, or nil if val was nil ------------------------------------- function DCSEx.math.toBoolean(val) if val == nil then return nil end if not val then return false end if val == 0 then return false end if val:lower() == "false" or val:lower() == "no" or val:lower() == "off" then return false end return true end ------------------------------------- -- Converts a vec2 to a vec3 -- @param vec2 A vec2 -- @param y (Optional) A value for the vec3's y component or "land" to use land height -- @return A vec3 where v3.x=v2.x, v3.y=y and v3.z=v2.y ------------------------------------- function DCSEx.math.vec2ToVec3(vec2, y) -- Value was already a vec3 if vec2.z then return {x = vec2.x, y = vec2.y, z = vec2.z} end y = y or 0 if y == "land" then y = land.getHeight(vec2) end return {x = vec2.x, y = y, z = vec2.y} end ------------------------------------- -- Converts a vec3 to a vec2 -- @param vec3 A vec3 -- @return A vec2 where v2.x=v3.x and v2.y=v3.z ------------------------------------- function DCSEx.math.vec3ToVec2(vec3) -- Value was already a vec2 if not vec3.z then return {x = vec3.x, y = vec3.y} end return {x = vec3.x, y = vec3.z} end -- ==================================================================================== -- (DCS LUA ADD-ON) STRING - EXTENSION TO THE "STRING" TABLE -- -- DCSEx.string.firstToUpper(str) -- DCSEx.string.getReadingTime(message) -- DCSEx.string.split(str, separator) -- DCSEx.string.startsWith(haystack, needle) -- DCSEx.string.trim(str) -- ==================================================================================== DCSEx.string = {} ------------------------------------- -- Uppercases the fist letter of a string -- @param str A string -- @return A string, with the first letter cast to upper case ------------------------------------- function DCSEx.string.firstToUpper(str) return (str:gsub("^%l", string.upper)) end ------------------------------------- -- Estimates the time (in seconds) required to read a string -- @param message A text message -- @return A duration in seconds ------------------------------------- function DCSEx.string.getReadingTime(message) message = message or "" message = tostring(message) return DCSEx.math.clamp(#message / 8.7, 3.0, 15.0) -- 10.7 letters per second, minimum length 3 seconds, max length 15 seconds end -- TODO: description, update file header function DCSEx.string.join(table, separator) local joinedString = "" for i=1,#table do joinedString = joinedString..tostring(table[i]) if i < #table then joinedString = joinedString..separator end end return joinedString end -- TODO: description, file header function DCSEx.string.getTimeString(timeInSeconds, useColon) timeInSeconds = timeInSeconds or timer.getAbsTime() useColon = useColon or false timeInSeconds = math.max(0, timeInSeconds) % 86400 local hours = math.floor(timeInSeconds / 3600) local minutes = math.floor(timeInSeconds / 60 - hours * 60) local hoursStr = tostring(hours) if #hoursStr == 1 then hoursStr = "0"..hoursStr end local minutesStr = tostring(minutes) if #minutesStr == 1 then minutesStr = "0"..minutesStr end local separator = "" if useColon then separator = ":" end return hoursStr..separator..minutesStr end -- TODO: description, file header function DCSEx.string.toStringNumber(number, firstToUpper) firstToUpper = firstToUpper or false local NUMBERS = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty" } if number + 1 <= #NUMBERS then local str = NUMBERS[number + 1] if firstToUpper then str = DCSEx.string.firstToUpper(str) end return str end return DCSEx.string.toStringThousandsSeparator(number) end -- TODO: description, file header -- Code from https://stackoverflow.com/questions/10989788/format-integer-in-lua function DCSEx.string.toStringThousandsSeparator(number) local i, j, minus, int, fraction = tostring(number):find('([-]?)(%d+)([.]?%d*)') int = int:reverse():gsub("(%d%d%d)", "%1,") return minus .. int:reverse():gsub("^,", "") .. fraction end ------------------------------------- -- Splits a string -- @param str The string to split -- @param separator The string to split -- @return A table of split strings ------------------------------------- function DCSEx.string.split(str, separator) separator = separator or "%s" local t = {} for s in DCSEx.string.gmatch(str, "([^"..separator.."]+)") do table.insert(t, s) end return t end ------------------------------------- -- Does a string starts with the given substring? -- @param haystack The string -- @param needle The substring to look for -- @return True if it starts with the substring, false otherwise ------------------------------------- function DCSEx.string.startsWith(haystack, needle) return haystack:sub(1, #needle) == needle end ------------------------------------- -- Trims a string -- @param str A string -- @return A string ------------------------------------- function DCSEx.string.trim(str) return (str:gsub("^%s*(.-)%s*$", "%1")) end -- ==================================================================================== -- (DCS LUA ADD-ON) TABLE - EXTENSION TO THE "TABLE" TABLE -- -- DCSEx.table.contains(t, val) -- DCSEx.table.containsKey(t, k) -- DCSEx.table.containsAll(t, values) -- DCSEx.table.containsAny(t, values) -- DCSEx.table.countNonNils(t) -- DCSEx.table.deepCopy(orig) -- DCSEx.table.dump(t) -- DCSEx.table.getKeys(t) -- DCSEx.table.getKeyFromValue(t, val) -- DCSEx.table.getRandom(t) -- DCSEx.table.getRandomIndex(t) -- DCSEx.table.shuffle(t) -- ==================================================================================== DCSEx.table = {} ------------------------------------- -- Returns true if table t contains value val -- @param t A table -- @param val A value -- @return True if the table contains the value, false otherwise ------------------------------------- function DCSEx.table.contains(t, val) if not t then return false end for _,v in pairs(t) do if v == val then return true end end return false end ------------------------------------- -- Returns true if table t contains key k -- @param t A table -- @param k A key -- @return True if the table contains the key, false otherwise ------------------------------------- function DCSEx.table.containsKey(t, k) if not t then return false end if t[k] then return true end return false end ------------------------------------- -- Returns true if table t contains all values in table values -- @param t A table -- @param values A table of values -- @return True if the table contains all values, false otherwise ------------------------------------- function DCSEx.table.containsAll(t, values) if not t then return false end for _,v in pairs(values) do if not DCSEx.table.contains(t, v) then return false end end return true end ------------------------------------- -- Returns true if table t contains at least one value in table values -- @param t A table -- @param values A table of values -- @return True if the table contains at least one value, false otherwise ------------------------------------- function DCSEx.table.containsAny(t, values) if not t then return false end for _,v in pairs(values) do if DCSEx.table.contains(t, v) then return true end end return false end function DCSEx.table.containsAllKeys(t, keys) if not t then return false end for _,k in pairs(keys) do if not DCSEx.table.containsKey(t, k) then return false end end return true end function DCSEx.table.containsAnyKeys(t, keys) if not t then return false end for _,k in pairs(keys) do if DCSEx.table.containsKey(t, k) then return true end end return false end ------------------------------------- -- Returns the number of non-nils elements in a table -- @param t A table -- @return A number ------------------------------------- function DCSEx.table.countNonNils(t) local count = 0 for _,v in pairs(t) do if v ~= nil then count = count + 1 end end return count end ------------------------------------- -- Returns a deep copy of the table, doesn't work with recursive tables (code from http://lua-users.org/wiki/CopyTable) -- @param orig A table -- @return A deep copied clone of the table ------------------------------------- function DCSEx.table.deepCopy(orig) -- Not a table if type(orig) ~= "table" then return orig end local copy = {} for orig_key, orig_value in next, orig, nil do copy[DCSEx.table.deepCopy(orig_key)] = DCSEx.table.deepCopy(orig_value) end setmetatable(copy, DCSEx.table.deepCopy(getmetatable(orig))) return copy end ------------------------------------- -- Dumps the content of a table as a string -- @param orig A table -- @return A string representaton of the table ------------------------------------- function DCSEx.table.dump(t) if type(t) == 'table' then local s = '{ ' for k,v in pairs(t) do if type(k) ~= 'number' then k = '"'..k..'"' end s = s .. '['..k..'] = ' .. DCSEx.table.dump(v) .. ',' end return s .. '} ' else return tostring(t) end end ------------------------------------- -- Returns the key associated to a value in a table, or nil if not found -- @param t A table -- @param val A value -- @return The key associated to this value in the table, or nil ------------------------------------- function DCSEx.table.getKeyFromValue(t, val) for k, v in pairs(t) do if v == val then return k end end return nil end ------------------------------------- -- Returns all the keys in an associative table -- @param t A table -- @return An array of keys ------------------------------------- function DCSEx.table.getKeys(t) local keys = {} local n = 1 for k,_ in pairs(t) do keys[n] = k n = n + 1 end table.sort(keys) return keys end ------------------------------------- -- Returns a random value from a numerically-indexed table -- @param t A table -- @return A random element from the table ------------------------------------- function DCSEx.table.getRandom(t) return t[math.random(#t)] end ------------------------------------- -- Returns a random index from a numerically-indexed table -- @param t A table -- @return A random index from the table ------------------------------------- function DCSEx.table.getRandomIndex(t) return math.random(#t) end ------------------------------------- -- Randomly shuffles a numerically-indexed table -- @param t A table -- @return A table with shuffled values ------------------------------------- function DCSEx.table.shuffle(t) local len, random = #t, math.random for i = len, 2, -1 do local j = random(1, i) t[i], t[j] = t[j], t[i] end return t end DCSEx.unitCallsignMaker = {} do local CALLSIGN_TYPE = { DEFAULT = 1, A10 = 2, AH64 = 3, AWACS = 4, B1B = 5, B52 = 6, F15E = 7, F16 = 8, F18 = 9, JTAC = 10, TANKER = 11, TRANSPORT = 12, } local CALLSIGNS = { [CALLSIGN_TYPE.DEFAULT] = { [1] = "Enfield", [2] = "Springfield", [3] = "Uzi", [4] = "Colt", [5] = "Dodge", [6] = "Ford", [7] = "Chevy", [8] = "Pontiac", }, [CALLSIGN_TYPE.A10] = { [9] = "Hawg", [10] = "Boar", [11] = "Pig", [12] = "Tusk", }, [CALLSIGN_TYPE.AH64] = { [9] = "Army Air", [10] = "Apache", [11] = "Crow", [12] = "Sioux", [13] = "Gatling", [14] = "Gunslinger", [15] = "Hammerhead", [16] = "Bootleg", [17] = "Palehorse", [18] = "Carnivor", [19] = "Saber", }, [CALLSIGN_TYPE.AWACS] = { [1] = "Overlord", [2] = "Magic", [3] = "Wizard", [4] = "Focus", [5] = "Darkstar", }, [CALLSIGN_TYPE.B1B] = { [9] = "Bone", [10] = "Dark", [11] = "Vader", }, [CALLSIGN_TYPE.B52] = { [9] = "Buff", [10] = "Dump", [11] = "Kenworth", }, [CALLSIGN_TYPE.F15E] = { [9] = "Dude", [10] = "Thud", [11] = "Gunny", [12] = "Trek", [13] = "Sniper", [14] = "Sled", [15] = "Best", [16] = "Jazz", [17] = "Rage", [18] = "Tahoe", }, [CALLSIGN_TYPE.F16] = { [9] = "Viper", [10] = "Venom", [11] = "Lobo", [12] = "Cowboy", [13] = "Python", [14] = "Rattler", [15] = "Panther", [16] = "Wolf", [17] = "Weasel", [18] = "Wild", [19] = "Ninja", [20] = "Jedi", }, [CALLSIGN_TYPE.F18] = { [9] = "Hornet", [10] = "Squid", [11] = "Ragin", [12] = "Roman", [13] = "Sting", [14] = "Jury", [15] = "Joker", [16] = "Ram", [17] = "Hawk", [18] = "Devil", [19] = "Check", [20] = "Snake", }, [CALLSIGN_TYPE.JTAC] = { [1] = "Axeman", [2] = "Darknight", [3] = "Warrior", [4] = "Pointer", [5] = "Eyeball", [6] = "Moonbeam", [7] = "Whiplash", [8] = "Finger", [9] = "Pinpoint", [10] = "Ferret", [11] = "Shaba", [12] = "Playboy", [13] = "Hammer", [14] = "Jaguar", [15] = "Deathstar", [16] = "Anvil", [17] = "Firefly", [18] = "Mantis", [19] = "Badger" }, [CALLSIGN_TYPE.TANKER] = { [1] = "Texaco", [2] = "Arco", [3] = "Shell", }, [CALLSIGN_TYPE.TRANSPORT] = { [9] = "Heavy", [10] = "Trash", [11] = "Cargo", [12] = "Ascot", }, } local currentCallsigns = {} for _,i in pairs(CALLSIGN_TYPE) do currentCallsigns[i] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} end local function getCallsignTypeByUnitType(unitType) if not unitType then return CALLSIGN_TYPE.DEFAULT end -- TODO: complete if unitType == "AH-64A" or unitType == "AH-64D" or unitType == "AH-64D_BLK_II" then return CALLSIGN_TYPE.A10 end if unitType == "A-10A" or unitType == "A-10C" or unitType == "A-10C_2" then return CALLSIGN_TYPE.A10 end if unitType == "F-15E" or unitType == "F-15ESE" then return CALLSIGN_TYPE.F15E end if unitType == "F-16A" or unitType == "F-16A MLU" or unitType == "F-16C bl.50" or unitType == "F-16C bl.52d" or unitType == "F-16C_50" then return CALLSIGN_TYPE.F16 end if unitType == "FA-18C" or unitType == "FA-18C_hornet" then return CALLSIGN_TYPE.F18 end -- if unitType == "A-50" or unitType == "E-2C" or unitType == "E-3A" then return CALLSIGN_TYPE.AWACS end local unitDesc = Unit.getDescByName(unitType) if not unitDesc then return CALLSIGN_TYPE.DEFAULT end if unitDesc.attributes["AWACS"] then return CALLSIGN_TYPE.AWACS end if unitDesc.attributes["Tankers"] then return CALLSIGN_TYPE.TANKER end return CALLSIGN_TYPE.DEFAULT end local function incrementCallsign(callsignName, callsignNumber) if not callsignName then return end callsignNumber = math.max(1, callsignNumber or 1) for k,_ in pairs(CALLSIGNS) do for i,_ in pairs(CALLSIGNS[k]) do if CALLSIGNS[k][i]:lower() == callsignName:lower() then currentCallsigns[k][i] = math.max(currentCallsigns[k][i], callsignNumber + 1) if (currentCallsigns[k][i] > 9) then currentCallsigns[k][i] = 1 end -- More than 9? Loop back to 1. -- TUM.log("Callsign "..CALLSIGNS[k][i].." set to "..tostring(callsignNumber)) return end end end end function DCSEx.unitCallsignMaker.getCallsign(unitType) local csType = getCallsignTypeByUnitType(unitType) local csNameIndex = DCSEx.table.getRandom(DCSEx.table.getKeys(CALLSIGNS[csType])) if not currentCallsigns[csType][csNameIndex] then currentCallsigns[csType][csNameIndex] = 1 end local csNumber = currentCallsigns[csType][csNameIndex] currentCallsigns[csType][csNameIndex] = currentCallsigns[csType][csNameIndex] + 1 if currentCallsigns[csType][csNameIndex] > 9 then currentCallsigns[csType][csNameIndex] = 1 end local callsignTable = { [1] = csNameIndex, [2] = csNumber, -- [3] = 1, ["name"] = CALLSIGNS[csType][csNameIndex]..tostring(csNumber), } return callsignTable end function DCSEx.unitCallsignMaker.getNextGroupCallSign(callsign) if not callsign then return nil end local callsignName = callsign:sub(1, #callsign - 2):lower() local callsignGroupNumber = tonumber(callsign:sub(#callsign - 2, #callsign - 1)) local callsignUnitNumber = tonumber(callsign:sub(#callsign - 1, #callsign)) for csType,_ in pairs(CALLSIGNS) do for csNameIndex,_ in pairs(CALLSIGNS[csType]) do if CALLSIGNS[csType][csNameIndex]:lower() == callsignName then return { [1] = csNameIndex, [2] = callsignGroupNumber, [3] = callsignUnitNumber, ["name"] = CALLSIGNS[csType][csNameIndex]..tostring(callsignGroupNumber), } end end end return nil end do local missionGroups = DCSEx.envMission.getGroups() for _,g in ipairs(missionGroups) do if g.units and g.units[1] then local unit = g.units[1] if unit.callsign and type(unit.callsign) == "table" and unit.callsign.name then local callsignName = unit.callsign.name:sub(1, #unit.callsign.name - 2) incrementCallsign(callsignName, unit.callsign[2]) end end end end end -- ==================================================================================== -- DCSEX.UNITGROUMAKER - CREATES AND ADDS GROUPS TO THE GAME WORLD -- -- (local) createGroupTable(groupID, groupCategory, options) -- (local) getDefaultUnitSpread(groupCategory) -- (local) getNextGroupID() -- (local) getNextUnitID() -- (local) setAircraftTaskAwacs(groupTable) -- (local) setAircraftTaskOrbit(groupTable, options) -- (local) setCommand(groupTable, actionID, actionValue) -- (local) setOption(groupTable, optionID, optionValue) -- DCSEx.unitGroupMaker.create(coalitionID, groupCategory, vec2, unitTypes, options) -- DCSEx.unitGroupMaker.initialize() -- ==================================================================================== DCSEx.unitGroupMaker = {} do local nextGroupID = 1 -- ID of the next generated group local nextUnitID = 1 -- ID of the next generated unit local dataLinkID = 201 -- Next datalink ID local function createGroupTable(groupID, groupCategory, options) local groupTable = { groupId = groupID, hidden = options.hidden, name = options.name, route = {points = {}}, start_time = 0, taskSelected = true, uncontrollable = true, visible = false, units = {}, } if groupCategory == Group.Category.GROUND then groupTable.task = "Ground Nothing" groupTable.tasks = {} elseif groupCategory == Group.Category.AIRPLANE or groupCategory == Group.Category.HELICOPTER then groupTable.uncontrolled = options.uncontrolled or false end return groupTable end local function getDefaultUnitSpread(groupCategory) if groupCategory == Group.Category.AIRPLANE or groupCategory == Group.Category.HELICOPTER then return 150 -- TODO: improve elseif groupCategory == Group.Category.SHIP then return math.random(250, 400) else return math.random(20, 30) end end -- Returns the next available group ID and increment the number local function getNextGroupID() nextGroupID = nextGroupID + 1 return nextGroupID - 1 end -- Returns the next available unit ID and increment the number local function getNextUnitID() nextUnitID = nextUnitID + 1 return nextUnitID - 1 end local function setAircraftTaskAwacs(groupTable) groupTable.frequency = 251000000 groupTable.task = "AWACS" table.insert(groupTable.route.points[1].task.params.tasks, { ["enabled"] = true, ["auto"] = true, ["id"] = "AWACS", ["number"] = #groupTable.route.points[1].task.params.tasks + 1, ["params"] = { }, }) return groupTable end local function setAircraftTaskCAP(groupTable) groupTable.task = "CAP" table.insert(groupTable.route.points[1].task.params.tasks, { ["enabled"] = true, ["auto"] = true, ["id"] = "EngageTargets", ["number"] = #groupTable.route.points[1].task.params.tasks + 1, ["params"] = { maxDist = DCSEx.converter.nmToMeters(60), maxDistEnabled = false, -- targetTypes = { "Planes", "Helicopters" }, targetTypes = { "Fighters", "Interceptors", "Multirole fighters" }, priority = 0 }, }) return groupTable end local function setAircraftTaskFollow(groupTable, followedGroupID, xyDistance) xyDistance = xyDistance or 800 groupTable.task = "Escort" table.insert(groupTable.route.points[1].task.params.tasks, { ["enabled"] = true, ["auto"] = true, ["id"] = "Follow", ["number"] = #groupTable.route.points[1].task.params.tasks + 1, ["params"] = { groupId = followedGroupID, pos = { x = -xyDistance, y = 0, z = -xyDistance }, lastWptIndexFlag = false, lastWptIndex = -1 }, }) return groupTable end local function setAircraftTaskOrbit(groupTable, options) -- TODO: oval orbit table.insert(groupTable.route.points[#groupTable.route.points].task.params.tasks, { ["enabled"] = true, ["auto"] = false, ["id"] = "Orbit", ["number"] = #groupTable.route.points[#groupTable.route.points].task.params.tasks + 1, ["params"] = { ["altitude"] = options.altitude, ["pattern"] = "Circle", ["speed"] = options.speed, }, }) return groupTable end local function setCommand(groupTable, actionID, actionValue) table.insert( groupTable.route.points[1].task.params.tasks, { ["auto"] = false, ["enabled"] = true, ["id"] = "WrappedAction", ["number"] = #groupTable.route.points[1].task.params.tasks + 1, ["params"] = { ["action"] = { ["id"] = actionID, ["params"] = { ["value"] = actionValue, }, }, }, }) end local function setOption(groupTable, optionID, optionValue) table.insert( groupTable.route.points[1].task.params.tasks, { ["auto"] = false, ["enabled"] = true, ["id"] = "WrappedAction", ["number"] = #groupTable.route.points[1].task.params.tasks + 1, ["params"] = { ["action"] = { ["id"] = "Option", ["params"] = { ["name"] = optionID, ["value"] = optionValue, }, }, }, }) end function DCSEx.unitGroupMaker.createStatic(side, point2, typeName, shapeName, heading, dead) heading = heading or DCSEx.converter.degreesToRadians(math.random(0, 359)) dead = dead or false local unitID = getNextUnitID() local staticObj = { ["heading"] = 0, ["groupId"] = getNextGroupID(), ["shape_name"] = shapeName, ["type"] = typeName, ["unitId"] = unitID, ["rate"] = 100, ["name"] = "Structure #"..tostring(unitID), ["category"] = "Fortifications", ["y"] = point2.y, ["x"] = point2.x, ["dead"] = dead, } coalition.addStaticObject(DCSEx.dcs.getCJTFForCoalition(side), staticObj) return unitID end function DCSEx.unitGroupMaker.create(coalitionID, groupCategory, vec2, unitTypes, options) if not unitTypes or #unitTypes == 0 then return nil end -- No unit types provided if type(unitTypes) == "string" then unitTypes = { unitTypes } end -- Single unit type provided, make it a table of size 1 local aircraftDB = nil -- Aircraft entry in the DB for airplane/helicopter units local destVec2 = nil -- Destination point (for moving units) local groupID = getNextGroupID() -- Get a new unique ID for the group local isAirUnit = false local hidden = options.hidden or false if not TUM.DEBUG_MODE and coalitionID ~= TUM.settings.getPlayerCoalition() then hidden = true end -- Setup options options = options or {} --options.heading = nil options.altitudeType = options.altitudeType or "BARO" options.hidden = hidden options.isMoving = false options.livery = options.livery or "default" options.name = DCSEx.unitNamesMaker.getName(groupID, unitTypes) options.pointAction = "Turning Point" options.skill = options.skill or "Average" options.speed = 5.5555556 options.spreadDistance = options.spreadDistance or getDefaultUnitSpread(groupCategory) options.spreadOffset = options.spreadOffset or 0 -- Movement point (for units with a second WP) if options.moveTo then options.isMoving = true destVec2 = DCSEx.table.deepCopy(options.moveTo) elseif options.moveBy then options.isMoving = true local angle = DCSEx.converter.degreesToRadians(math.random(0, 359)) destVec2 = { x = vec2.x + math.cos(angle) * options.moveBy, y = vec2.y + math.sin(angle) * options.moveBy } end -- Category specific options if groupCategory == Group.Category.GROUND then options.pointAction = "Off Road" local desc = Unit.getDescByName(unitTypes[1]) if desc and desc.attributes and desc.attributes.Infantry then options.speed = 1.66667 end -- Check position and formation for moving ground units if options.isMoving then if options.onRoad then options.pointAction = "On Road" vec2 = DCSEx.world.getClosestPointOnRoadsVec2(vec2) destVec2 = DCSEx.world.getClosestPointOnRoadsVec2(destVec2) else options.pointAction = options.formation or DCSEx.table.getRandom({"Rank", "Cone", "Vee", "Diamond", "EchelonL", "EchelonR"}) end end options.livery = "default" -- TODO: getSeasonalLivery() elseif groupCategory == Group.Category.AIRPLANE or groupCategory == Group.Category.HELICOPTER then isAirUnit = true -- Plane/helicopter groups always use a single unit type for i=1,#unitTypes do unitTypes[i] = unitTypes[1] end -- Get unit info from aircraft database aircraftDB = Library.aircraft[unitTypes[1]] if not aircraftDB then return nil end -- Unit wasn't found in the database, abort group creation -- Pick a random livery if available -- if aircraftDB.liveries and aircraftDB.liveries[coalitionID] then -- options.livery = table.getRandom(aircraftDB.liveries[coalitionID]) -- end options.altitude = options.altitude or aircraftDB.altitude or DCSEx.converter.feetToMeters(15000) options.altitudeType = "BARO" options.speed = DCSEx.math.randomFloat(0.9, 1.1) * (aircraftDB.speed or 250) end -- First unit of the group is a template, use a group template instead of enumerating the types in unitTypes local groupTemplate = nil if Library.groupTemplates[unitTypes[1]] then groupTemplate = DCSEx.table.deepCopy(Library.groupTemplates[unitTypes[1]]) unitTypes = {} for i=1,#groupTemplate do table.insert(unitTypes, groupTemplate[i].name) end end -- Create group table local groupTable = createGroupTable(groupID, groupCategory, options) groupTable.x = vec2.x groupTable.y = vec2.y -- Initial waypoint table.insert( groupTable.route.points, { action = options.pointAction, alt = options.altitude, alt_type = options.altitudeType, ETA = 0.0, ETA_locked = false, formation_template = "", name = "WP1", speed = options.speed, speed_locked = true, task = {id = "ComboTask", params = {tasks = {}}}, type = "Turning Point", x = vec2.x, y = vec2.y } ) if options.takeOff and (groupCategory == Group.Category.AIRPLANE or groupCategory == Group.Category.HELICOPTER) then groupTable.route.points[1].alt = 750 groupTable.route.points[1].alt_type = "RADIO" end if destVec2 then -- There's a destination, add a second waypoint local destPoint = { action = options.pointAction, alt_type = options.altitudeType, alt = options.altitude, ETA = 0.0, ETA_locked = false, formation_template = "", name = "WP2", speed = options.speed, task = { id = "ComboTask", params = { tasks = { } } }, type = "Turning Point", x = destVec2.x, y = destVec2.y, speed_locked = true } -- Ground/ship groups loop between their waypoints if groupCategory == Group.Category.GROUND or groupCategory == Group.Category.SHIP then if not options.noLoop then table.insert( destPoint.task.params.tasks, { enabled = true, auto = false, id = "GoToWaypoint", number = 1, params = { fromWaypointIndex = 2, nWaypointIndx = 1 } }) end end table.insert(groupTable.route.points, destPoint) end -- Add various options/commands if options.disableWeapons then setOption(groupTable, AI.Option.Ground.id.ROE, AI.Option.Ground.val.ROE.WEAPON_HOLD) end -- Values are from the AI.Option.Ground tables, but they're the same for all (ROE=0, WEAPON_HOLD=4) if options.immortal then setCommand(groupTable, "SetImmortal", true) end if options.invisible then setCommand(groupTable, "SetInvisible", true) end if options.silenced then setOption(groupTable, AI.Option.Air.id.SILENCE, true) end if options.unlimitedFuel then setCommand(groupTable, "SetUnlimitedFuel", true) end local groupCallsign = nil if isAirUnit then -- setOption(groupTable, AI.Option.Air.id.FORCED_ATTACK, true) -- setOption(groupTable, AI.Option.Air.id.RTB_ON_BINGO, false) if options.prohibitJettison then setOption(groupTable, AI.Option.Air.id.PROHIBIT_JETT, true) end if options.taskAwacs then setAircraftTaskAwacs(groupTable) end if options.taskCAP then setAircraftTaskCAP(groupTable) end if options.taskFollow then setAircraftTaskFollow(groupTable, options.taskFollow) else setAircraftTaskOrbit(groupTable, options) end if options.callsign then groupCallsign = options.callsign else groupCallsign = DCSEx.unitCallsignMaker.getCallsign(unitTypes[1]) end groupTable.name = groupCallsign.name end -- Group name already exists while Group.getByName(groupTable.name) do groupTable.name = groupTable.name.."-" end local unitsID = {} ----------------------- -- Create units ----------------------- for i=1,#unitTypes do local unitID = getNextUnitID() table.insert(unitsID, unitID) local unitHeading, unitOffset if groupTemplate then -- Use offset and heading from the group unitHeading = groupTemplate[i].heading unitOffset = { x = groupTemplate[i].dx, y = groupTemplate[i].dy } else -- Create offset and heading unitHeading = options.heading or DCSEx.math.randomFloat(0, DCSEx.math.TWO_PI) unitOffset = DCSEx.math.multVec2( DCSEx.math.getVec2FromAngle(unitHeading), options.spreadDistance * (options.spreadOffset + i - 1) ) end local unitType = unitTypes[i] local unitTable = { coldAtStart = false, heading = unitHeading, livery = options.livery, name = options.name.." #"..tostring(i), playerCanDrive = false, skill = options.skill, transportable = {randomTransportable = false}, type = unitType, unitId = unitID, x = vec2.x + unitOffset.x, y = vec2.y + unitOffset.y } if options.onRoad then local posOnRoads = DCSEx.world.getClosestPointOnRoadsVec2(unitTable) unitTable.x = posOnRoads.x unitTable.y = posOnRoads.y end if isAirUnit and aircraftDB then unitTable.hardpoint_racks = true unitTable.psi = 1.7703702498393 local callsignUnitIndex = i + (options.callsignOffset or 0) unitTable.callsign = DCSEx.table.deepCopy(groupCallsign) unitTable.callsign.name = unitTable.callsign.name..tostring(callsignUnitIndex) unitTable.callsign[3] = callsignUnitIndex unitTable.callsign[4] = unitTable.callsign.name unitTable.name = unitTable.callsign.name -- Special properties for unit unitTable.AddPropAircraft = {} if aircraftDB.properties then unitTable.AddPropAircraft = DCSEx.table.deepCopy(aircraftDB.properties) end -- Setup datalink local datalinkString = tostring(dataLinkID) if #datalinkString == 3 then datalinkString = "00"..datalinkString elseif #datalinkString == 4 then datalinkString = "0"..datalinkString end unitTable.AddPropAircraft["STN_L16"] = datalinkString dataLinkID = dataLinkID + 1 -- Common payload (fuel, gun ammo, etc) if aircraftDB.payload then unitTable.payload = DCSEx.table.deepCopy(aircraftDB.payload) end if aircraftDB.pylons then local payload = "attack" -- Default payload is "attack", because it's usually a good mix of A-G and A-A munitions if options.payload then -- A payload was specified payload = options.payload else -- No payload was specified, deduce payload from tasking if options.taskAntiship then payload = "antiship" elseif options.taskCAP then payload = "cap" elseif options.taskSEAD then payload = "sead" elseif options.taskStrike then payload = "strike" end end unitTable.payload.pylons = DCSEx.table.deepCopy(aircraftDB.pylons[payload]) end end -- Unit name already exists while Unit.getByName(unitTable.name) do unitTable.name = unitTable.name.."-" end table.insert(groupTable.units, unitTable) end coalition.addGroup(DCSEx.dcs.getCJTFForCoalition(coalitionID), groupCategory, groupTable) return { callsign = groupCallsign, groupID = groupID, unitsID = unitsID, unitTypeNames = DCSEx.table.deepCopy(unitTypes) -- Not always the same as the unitTypes input parameter, because of group templates } end ------------------------------------------------------ -- INITIALIZE THE GROUP MAKER -- Look for maximum groupID and unitID already in use to make sure we don't use an existing ID when spawning units ------------------------------------------------------ local groupData = DCSEx.envMission.getGroups() for _,g in ipairs(groupData) do if g.groupId >= nextGroupID then nextGroupID = g.groupId + 1 end for __,u in ipairs(g.units) do if u.unitId >= nextUnitID then nextUnitID = u.unitId + 1 end end end end DCSEx.unitNamesMaker = {} do local function getSectionNameSuffixAir() return DCSEx.table.getRandom({"squadron", "wing"}) end local function getSectionNameSuffixGround() return DCSEx.table.getRandom({"bataillon", "brigade", "corps", "division", "regiment"}) end local function getSectionNameSuffixNaval() return DCSEx.table.getRandom({"fleet", "force"}) end local function getDefaultSectionName() return "unit "..getSectionNameSuffixGround() end local function getNameByDesc(unitDesc) if not unitDesc then return getDefaultSectionName() end if unitDesc.attributes["UAVs"] then return DCSEx.table.getRandom({"unmanned"}).." "..getSectionNameSuffixAir() end if unitDesc.attributes["Bombers"] then return DCSEx.table.getRandom({"bomber"}).." "..getSectionNameSuffixAir() end if unitDesc.attributes["Fighters"] or unitDesc.attributes["Interceptors"] or unitDesc.attributes["Battle airplanes"] then return DCSEx.table.getRandom({"fighter", "fighting"}).." "..getSectionNameSuffixAir() end if unitDesc.attributes["Planes"] then return DCSEx.table.getRandom({"air", "cargo", "transport"}).." "..getSectionNameSuffixAir() end if unitDesc.attributes["Attack helicopters"] then return DCSEx.table.getRandom({"assault", "rotary"}).." "..getSectionNameSuffixAir() end if unitDesc.attributes["Helicopters"] then return DCSEx.table.getRandom({"tactical"}).." "..getSectionNameSuffixAir() end if unitDesc.attributes["Aircraft Carriers"] then return DCSEx.table.getRandom({"carrier"}).." "..getSectionNameSuffixNaval() end if unitDesc.attributes["Unarmed ships"] then return DCSEx.table.getRandom({"cargo", "logistical"}).." "..getSectionNameSuffixNaval() end if unitDesc.attributes["Ships"] then return DCSEx.table.getRandom({"expeditionary", "assault"}).." "..getSectionNameSuffixNaval() end if unitDesc.attributes["MANPADS AUX"] or unitDesc.attributes["MANPADS"] or unitDesc.attributes["Armed Air Defence"] or unitDesc.attributes["SAM elements"] or unitDesc.attributes["SAM related"] or unitDesc.attributes["SAM"] then return DCSEx.table.getRandom({"air defense"}).." "..getSectionNameSuffixGround() end if unitDesc.attributes["Tanks"] or unitDesc.attributes["HeavyArmoredUnits"] or unitDesc.attributes["LightArmoredUnits"] then return DCSEx.table.getRandom({"armor", "heavy"}).." "..getSectionNameSuffixGround() end if unitDesc.attributes["LightArmoredUnits"] then return DCSEx.table.getRandom({"armored", "mechanized"}).." "..getSectionNameSuffixGround() end if unitDesc.attributes["Ground vehicles"] then return DCSEx.table.getRandom({"engineer","logistical","support","tactical"}).." "..getSectionNameSuffixGround() end if unitDesc.attributes["Infantry"] then return DCSEx.table.getRandom({"infantry"}).." "..getSectionNameSuffixGround() end return getDefaultSectionName() end function DCSEx.unitNamesMaker.getName(groupID, unitTypes) local nameNumber = tostring(groupID) if (nameNumber:sub(-1) == "1") then nameNumber = nameNumber.."st" elseif (nameNumber:sub(-1) == "2") then nameNumber = nameNumber.."nd" elseif (nameNumber:sub(-1) == "3") then nameNumber = nameNumber.."rd" else nameNumber = nameNumber.."th" end local nameSection = getDefaultSectionName() if unitTypes and #unitTypes > 0 then local desc = Unit.getDescByName(unitTypes[1]) if desc then nameSection = getNameByDesc(desc) end end return nameNumber.." "..nameSection end end -- ==================================================================================== -- WORLDTOOLS - FUNCTIONS RELATED TO THE GAME WORLD -- ==================================================================================== -- DCSEx.world.collidesWithScenery(vec2, radius) -- DCSEx.world.findSpawnPoint(vec2, minRadius, maxRadius, surfaceType, radiusWithoutScenery) -- DCSEx.world.getAllPlayers() -- DCSEx.world.getAllSceneryBuildings(minHealth) -- DCSEx.world.getAllUnits(unitCategory) -- DCSEx.world.getClosestPointOnRoadsVec2(vec2) -- DCSEx.world.getCoordinatesAsString(point) -- DCSEx.world.getCurrentMarkerID() -- DCSEx.world.getGroupByID(groupID) -- DCSEx.world.getNextMarkerID() -- DCSEx.world.getSceneriesInZone(center, radius, minHealth) -- DCSEx.world.getStaticObjectByID(staticID) -- DCSEx.world.getTerrainHeightDiff(coord, searchRadius) -- DCSEx.world.getUnitByID(unitID) -- DCSEx.world.isGroupAlive(g, unitsMustBeInAir) -- DCSEx.world.setUnitLifePercent(unitID, life) -- ==================================================================================== DCSEx.world = { } do -- TODO: get max marker already in use from envMission local nextMarkerId = 1 -- Next map marker ID function DCSEx.world.collidesWithScenery(vec2, radius) local foundOne = false radius = radius or 8 local volS = { id = world.VolumeType.SPHERE, params = { point = DCSEx.math.vec2ToVec3(vec2, "land"), radius = radius } } local ifFound = function(foundItem, val) foundOne = true return true end world.searchObjects(Object.Category.SCENERY, volS, ifFound) return foundOne end -- function DCSEx.world.findSpawnPoint(vec2, minRadius, maxRadius, surfaceType, radiusWithoutScenery, territorySide, expandSearch) -- expandSearch = expandSearch or true -- for _=0,16 do -- for _=0,16 do -- local spawnPoint = nil -- spawnPoint = DCSEx.math.randomPointInCircle( -- vec2, -- DCSEx.converter.nmToMeters(maxRadius), -- DCSEx.converter.nmToMeters(minRadius), -- surfaceType) -- if spawnPoint and radiusWithoutScenery then -- if DCSEx.world.collidesWithScenery(spawnPoint, radiusWithoutScenery) then -- spawnPoint = nil -- end -- end -- if spawnPoint and territorySide then -- if scramble.territories.getOwner(spawnPoint) ~= territorySide then -- spawnPoint = nil -- end -- end -- if spawnPoint then return spawnPoint end -- end -- if not expandSearch then return nil end -- minRadius = minRadius * 0.9 -- maxRadius = maxRadius * 1.2 -- end -- return nil -- end ------------------------------------- -- Returns a table of all player-controlled units currently in the game -- @return A table of unit objects ------------------------------------- function DCSEx.world.getAllPlayers() local players = {} for coalitionID=0,2 do local coalPlayers = coalition.getPlayers(coalitionID) for _,p in pairs(coalPlayers) do table.insert(players, p) end end return players end ------------------------------------- -- Returns a table of all map scenery buildings. -- This function is rather CPU-consuming, better run it once on mission start and store the result in table. -- @param minHealth Minimum health a building must have to be included in the table -- @return A table of scenery objects ------------------------------------- function DCSEx.world.getAllSceneryBuildings(minHealth) minHealth = minHealth or 0 local sceneries = {} local scenerySearchvolume = { id = world.VolumeType.SPHERE, params = { point = { x = env.mission.map.centerX, y = 0, z = env.mission.map.centerY }, radius = 10000000 } } local function ifSceneryFound(foundScenery, val) local desc = foundScenery:getDesc() if desc and desc.attributes and desc.attributes.Buildings then if desc.life >= minHealth then table.insert(sceneries, foundScenery) end end return true end world.searchObjects(Object.Category.SCENERY, scenerySearchvolume, ifSceneryFound) return sceneries end ------------------------------------- -- Returns all units belonging to a given category -- @param coalitionID Coalition ID (coalition.side.XXX) or nil to search all coalitions -- @param unitCategory An unit category (Group.Category.XXX) -- @return A table of unit tables ------------------------------------- function DCSEx.world.getAllUnits(coalitionID, unitCategory) local units = {} local searchedCoalitions = { 0, 1, 2 } if coalitionID then searchedCoalitions = { coalitionID } end for _,c in pairs(searchedCoalitions) do -- Enumerate coalitions for _, g in pairs(coalition.getGroups(c, unitCategory)) do for __, u in pairs(g:getUnits()) do table.insert(units, u) end end end return units end ------------------------------------- -- Returns the closest point to roads as a vec2 -- @param vec2 Coordinates to look for -- @return A vec2 with the closest point on roads ------------------------------------- function DCSEx.world.getClosestPointOnRoadsVec2(vec2) local roadX, roadY = land.getClosestPointOnRoads("roads", vec2.x, vec2.y) return {x = roadX, y = roadY} end ------------------------------------- -- Returns the LL/MGRS coordinates of a point, as a string -- Based on code by Bushmanni - https://forums.eagle.ru/showthread.php?t=99480 -- @param point The point, as a vec2 or vec3 -- @param hideElevation (optional) Show elevation NOT be displayed? Default: false -- @return A string ------------------------------------- function DCSEx.world.getCoordinatesAsString(point, hideElevation) hideElevation = hideElevation or false if not point.z then point = DCSEx.math.vec2ToVec3(point, "land") end local cooString = "" local LLposN, LLposE, alt = coord.LOtoLL(point) local LLposfixN, LLposdegN = math.modf(LLposN) LLposdegN = LLposdegN * 60 local LLposdegN2, LLposdegN3 = math.modf(LLposdegN) local LLposdegN3Decimal = LLposdegN3 * 1000 LLposdegN3 = LLposdegN3 * 60 local LLposfixE, LLposdegE = math.modf(LLposE) LLposdegE = LLposdegE * 60 local LLposdegE2, LLposdegE3 = math.modf(LLposdegE) local LLposdegE3Decimal = LLposdegE3 * 1000 LLposdegE3 = LLposdegE3 * 60 local LLns = "N" if LLposfixN < 0 then LLns = "S" end local LLew = "E" if LLposfixE < 0 then LLew = "W" end local LLposNstring = LLns .. " " .. string.format("%.2i°%.2i'%.2i''", LLposfixN, LLposdegN2, LLposdegN3) local LLposEstring = LLew .. " " .. string.format("%.3i°%.2i'%.2i''", LLposfixE, LLposdegE2, LLposdegE3) cooString = "L/L: " .. LLposNstring .. " " .. LLposEstring local LLposNstring = LLns .. " " .. string.format("%.2i°%.2i.%.3i", LLposfixN, LLposdegN2, LLposdegN3Decimal) local LLposEstring = LLew .. " " .. string.format("%.3i°%.2i.%.3i", LLposfixE, LLposdegE2, LLposdegE3Decimal) cooString = cooString .. "\nL/L: " .. LLposNstring .. " " .. LLposEstring local mgrs = coord.LLtoMGRS(LLposN, LLposE) local mgrsString = mgrs.MGRSDigraph .. " " .. mgrs.UTMZone .. " " .. tostring(mgrs.Easting) .. " " .. tostring(mgrs.Northing) cooString = cooString .. "\nMGRS: " .. mgrsString if not hideElevation then cooString = cooString .. "\nELEVATION: " .. math.floor(alt * 3.281) .. "ft / " .. math.floor(alt) .. " meters" end return cooString end ------------------------------------- -- Returns the last map marker ID generated by DCSEx.world.getNextMarkerID(), if any -- @return A numeric ID, or nil ------------------------------------- function DCSEx.world.getCurrentMarkerID() if nextMarkerId == 1 then return nil end return nextMarkerId - 1 end ------------------------------------- -- Searches and return a group by its ID -- @param groupID ID of the group -- @return A group table, or nil if no group with this ID was found ------------------------------------- function DCSEx.world.getGroupByID(groupID) for coalitionID = 1, 2 do for _, grp in pairs(coalition.getGroups(coalitionID)) do if DCSEx.dcs.getGroupIDAsNumber(grp) == groupID then return grp end end end return nil end -- TODO: description function DCSEx.world.getMarkerByText(text, coalition) if not text then return nil end text = text:lower() local markers = world.getMarkPanels() for _,m in ipairs(markers) do local markerText = m.text or "" markerText = markerText:lower() if markerText == text then if coalition == nil or m.coalition == coalition then return m end end end return nil end ------------------------------------- -- Returns a new, unique, map marker ID -- @return A numeric ID ------------------------------------- function DCSEx.world.getNextMarkerID() nextMarkerId = nextMarkerId + 1 return nextMarkerId - 1 end -- TODO: description, file header function DCSEx.world.getPlayersInAir(side) local players = {} if side then players = coalition.getPlayers(side) else players = DCSEx.world.getAllPlayers() end local playersInAir = {} for _,p in ipairs(players) do if p:inAir() then table.insert(playersInAir, p) end end return playersInAir end -- TODO: description, file header function DCSEx.world.getSpawnPoint(zone, surfaceType, safeRadius) safeRadius = safeRadius or 100 -- Only two surface types are really useful to us: land and water if surfaceType == land.SurfaceType.SHALLOW_WATER then surfaceType = land.SurfaceType.WATER elseif surfaceType == land.SurfaceType.ROAD or surfaceType == land.SurfaceType.RUNWAY then surfaceType = land.SurfaceType.LAND end local loopsLeft = 512 while loopsLeft > 0 do local basePoint = DCSEx.zones.getRandomPointInside(zone) if not surfaceType then -- Nil surfaceType means: any point is fine return basePoint end if surfaceType == land.SurfaceType.WATER then if basePoint and land.getSurfaceType(basePoint) == land.SurfaceType.WATER then return basePoint end else if safeRadius <= 0 then return basePoint end basePoint = DCSEx.math.vec2ToVec3(basePoint, "land") local spawnPoints = Disposition.getSimpleZones(basePoint, math.max(1852, safeRadius * 5), safeRadius, 1) if #spawnPoints > 0 and land.getSurfaceType(spawnPoints[1]) == land.SurfaceType.LAND then return spawnPoints[1] end end loopsLeft = loopsLeft - 1 end return nil end -- TODO: description function DCSEx.world.getSceneriesInZone(center, radius, minHealth) minHealth = minHealth or 0 local sceneries = {} local scenerySearchvolume = { id = world.VolumeType.SPHERE, params = { point = DCSEx.math.vec2ToVec3(center, "land"), radius = radius } } local function ifSceneryFound(foundScenery, val) local desc = foundScenery:getDesc() if desc and desc.attributes and desc.attributes.Buildings then if desc.life >= minHealth then table.insert(sceneries, foundScenery) end end return true end world.searchObjects(Object.Category.SCENERY, scenerySearchvolume, ifSceneryFound) return sceneries end ------------------------------------- -- Searches and return a static object by its ID -- @param staticID ID of the static object -- @return An unit, or nil if no static object with this ID was found ------------------------------------- function DCSEx.world.getStaticObjectByID(staticID) for coalitionID = 1, 2 do for _, s in pairs(coalition.getStaticObjects(coalitionID)) do if DCSEx.dcs.getObjectIDAsNumber(s) == staticID then return s end end end return nil end -- TODO: description, update file header function DCSEx.world.getTerrainHeightDiff(coord, searchRadius) local samples = {} searchRadius = searchRadius or 5 samples[#samples + 1] = land.getHeight(coord) for i = 0, 360, 30 do samples[#samples + 1] = land.getHeight({x = (coord.x + (math.sin(math.rad(i))*searchRadius)), y = (coord.y + (math.cos(math.rad(i))*searchRadius))}) if searchRadius >= 20 then -- if search radius is sorta large, take a sample halfway between center and outer edge samples[#samples + 1] = land.getHeight({x = (coord.x + (math.sin(math.rad(i))*(searchRadius/2))), y = (coord.y + (math.cos(math.rad(i))*(searchRadius/2)))}) end end local tMax, tMin = 0, 1000000 for _, height in pairs(samples) do if height > tMax then tMax = height end if height < tMin then tMin = height end end return tMax - tMin end -- TODO: description, update file header function DCSEx.world.getGroupCenter(group) return DCSEx.world.getUnitsCenter(group:getUnits()) end -- TODO: description, update file header function DCSEx.world.getUnitsCenter(units) if not units or #units == 0 then return { x = 0, y = 0 } end local center = { x = 0, y = 0 } for _,u in pairs(units) do local uPt2 = DCSEx.math.vec3ToVec2(u:getPoint()) center.x = center.x + uPt2.x center.y = center.y + uPt2.y end center.x = center.x / #units center.y = center.y / #units return center end ------------------------------------- -- Searches and return an unit by its ID -- @param unitID ID of the unit -- @return An unit, or nil if no unit with this ID was found ------------------------------------- function DCSEx.world.getUnitByID(unitID) for coalitionID = 1, 2 do for _, g in pairs(coalition.getGroups(coalitionID)) do local units = g:getUnits() for _, u in pairs(units) do if DCSEx.dcs.getObjectIDAsNumber(u) == unitID then return u end end end end return nil end ------------------------------------- -- Searches and return a coalition static object by its ID -- @param unitID ID of the static object -- @return An static object, or nil if no unit with this ID was found ------------------------------------- function DCSEx.world.getStaticObjectByID(staticID) for coalitionID = 1,2 do for _,s in pairs(coalition.getStaticObjects(coalitionID)) do if DCSEx.dcs.getObjectIDAsNumber(s) == staticID then return s end end end return nil end -- TODO: description function DCSEx.world.isGroupAlive(g, unitsMustBeInAir) if not g then return false end if not g:isExist() then return false end if g:getSize() == 0 then return false end unitsMustBeInAir = unitsMustBeInAir or false local atLeastOneActiveUnit = false local units = g:getUnits() if not units or #units == 0 then return false end for _,u in pairs(units) do if u:isExist() and u:getLife() > 0 then if u:inAir() or not unitsMustBeInAir then atLeastOneActiveUnit = true end end end return atLeastOneActiveUnit end -- TODO: description & file header function DCSEx.world.setUnitLifePercent(unitID, life) net.dostring_in("mission", string.format("a_unit_set_life_percentage(%d, %f)", unitID, life)) end -- TODO: description & file header function DCSEx.world.explodeUnit(unitID, amount) net.dostring_in("mission", string.format("a_explosion_unit(%d, %f)", unitID, amount)) end function DCSEx.world.destroyGroupByID(groupID) if not groupID then return end local g = DCSEx.world.getGroupByID(groupID) if g then g:destroy() end end -- function DCSEx.world.destroySceneryInZone(zone, destructionPercent) -- destructionPercent = destructionPercent or 0 -- net.dostring_in("mission", string.format("a_scenery_destruction_zone(%d, %f)", zone.zoneId, destructionPercent)) -- end -- function DCSEx.world.highlightUnit(unitID, enabled) -- if enabled then -- enabled = "true" -- else -- enabled = "false" -- end -- net.dostring_in("mission", string.format("a_unit_highlight(%d, %s)", unitID, enabled)) -- end -- function DCSEx.world.shellingZone(zone, tnt, shellsCount) -- net.dostring_in("mission", string.format("a_shelling_zone(%d, %f, %d)", zone.zoneId, tnt, shellsCount)) -- end end -- ==================================================================================== -- ZONETOOLS - FUNCTIONS RELATED TO MAP TRIGGER ZONES -- ==================================================================================== -- DCSEx.zones.drawOnMap(zoneTable, lineColor, fillColor, lineType, drawName, readonly) -- DCSEx.zones.getAll() -- DCSEx.zones.getByName(name) -- DCSEx.zones.getCenter(zoneTable) -- DCSEx.zones.getProperty(zoneTable, propertyName) -- DCSEx.zones.getPropertyBoolean(zoneTable, propertyName, defaultValue) -- DCSEx.zones.getPropertyFloat(zoneTable, propertyName, defaultValue, min, max) -- DCSEx.zones.getPropertyInt(zoneTable, propertyName, defaultValue, min, max) -- DCSEx.zones.getPropertyParse(zoneTable, propertyName, stringTable, valueTable, defaultValue) -- DCSEx.zones.getPropertyTable(zoneTable, propertyName) -- DCSEx.zones.getRadius(zoneTable, useMaxForQuads) -- DCSEx.zones.getSurfaceArea(zoneTable) -- DCSEx.zones.isPointInside(zoneTable, point) -- ==================================================================================== DCSEx.zones = { } -- TODO: function description function DCSEx.zones.drawOnMap(zoneTable, lineColor, fillColor, lineType, drawName, readOnly) drawName = drawName or false readOnly = readOnly or true if not zoneTable then return end local markerID = DCSEx.world.getNextMarkerID() -- Draw shapes on the F10 map if zoneTable.type == 2 then -- Zone is a quad trigger.action.quadToAll( -1, markerID, DCSEx.math.vec2ToVec3(zoneTable.verticies[1]), DCSEx.math.vec2ToVec3(zoneTable.verticies[2]), DCSEx.math.vec2ToVec3(zoneTable.verticies[3]), DCSEx.math.vec2ToVec3(zoneTable.verticies[4]), lineColor, fillColor, lineType, readOnly ) else -- Zone is a circle trigger.action.circleToAll( -1, markerID, DCSEx.math.vec2ToVec3(zoneTable), zoneTable.radius, lineColor, fillColor, lineType, readOnly ) end if drawName then local markerIDText = DCSEx.world.getNextMarkerID() trigger.action.textToAll(-1, markerIDText, DCSEx.math.vec2ToVec3(zoneTable), { 1, 1, 1, 1 }, { 0, 0, 0, .5 }, 18, readOnly, zoneTable.name) return { markerID, markerIDText } end return markerID end ------------------------------------- -- Returns all trigger zones -- @return Table of zones ------------------------------------- function DCSEx.zones.getAll() if not env.mission.triggers then return {} end if not env.mission.triggers.zones then return {} end return DCSEx.table.deepCopy(env.mission.triggers.zones) end ------------------------------------- -- Finds and return a trigger zone by a certain name -- @param name Case-insensitive name of the zone -- @return Zone table or nil if no zone with this name was found ------------------------------------- function DCSEx.zones.getByName(name) if not name then return nil end if not env.mission.triggers then return nil end if not env.mission.triggers.zones then return nil end name = name:lower() for _, z in pairs(env.mission.triggers.zones) do if z.name:lower() == name then return DCSEx.table.deepCopy(z) end end return nil end ------------------------------------- -- Returns the center of a zone -- @param zoneTable The zone table, returned by TMMissionData.getZones() or TMMissionData.getZoneByName(name) -- @return A vec2 ------------------------------------- function DCSEx.zones.getCenter(zoneTable) if not zoneTable then return nil end local x = zoneTable.x or 0 local y = zoneTable.y or 0 if zoneTable.type == 2 then -- Zone is a quad x = (zoneTable.verticies[1].x + zoneTable.verticies[2].x + zoneTable.verticies[3].x + zoneTable.verticies[4].x) / 4 y = (zoneTable.verticies[1].y + zoneTable.verticies[2].y + zoneTable.verticies[3].y + zoneTable.verticies[4].y) / 4 end return { x = x, y = y } end ------------------------------------- -- Returns the value of the property of a trigger zone, as a string -- @param zoneTable The zone table, returned by DCSEx.zones.getAll() or DCSEx.zones.getByName(name) -- @param propertyName Case-insensitive name of the property -- @return The value of the property or nil if it doesn't exist ------------------------------------- function DCSEx.zones.getProperty(zoneTable, propertyName, defaultValue) if not propertyName then return defaultValue end if not zoneTable then return defaultValue end if not zoneTable.properties then return defaultValue end propertyName = propertyName:lower() for _, p in pairs(zoneTable.properties) do if p.key:lower() == propertyName then return (p.value or defaultValue):lower() end end return defaultValue end ------------------------------------- -- Returns the value of the property of a trigger zone, parsed against a case-insensitive table of strings -- @param zoneTable The zone table, returned by DCSEx.zones.getAll() or DCSEx.zones.getByName(name) -- @param propertyName Case-insensitive name of the property -- @param defaultValue Default value to return if no match was found -- @return A boolean ------------------------------------- function DCSEx.zones.getPropertyBoolean(zoneTable, propertyName, defaultValue) return DCSEx.zones.getPropertyParse( zoneTable, propertyName, {"true", "yes", "1", "on", "enabled", "false", "no", "0", "off", "disabled"}, {true, true, true, true, true, false, false, false, false, false}, defaultValue) end ------------------------------------- -- Returns the value of the property of a trigger zone, as a float -- @param zoneTable The zone table, returned by DCSEx.zones.getAll() or DCSEx.zones.getByName(name) -- @param propertyName Case-insensitive name of the property -- @param defaultValue Default value to return if no match was found -- @param min Minimum value -- @param max Maximum value -- @return A float ------------------------------------- function DCSEx.zones.getPropertyFloat(zoneTable, propertyName, defaultValue, min, max) local value = tonumber(DCSEx.zones.getProperty(zoneTable, propertyName)) if not value then return defaultValue end if min then value = math.max(min, value) end if max then value = math.min(max, value) end return value end ------------------------------------- -- Returns the value of the property of a trigger zone, as an integer -- @param zoneTable The zone table, returned by DCSEx.zones.getAll() or DCSEx.zones.getByName(name) -- @param propertyName Case-insensitive name of the property -- @param defaultValue Default value to return if no match was found -- @param min Minimum value -- @param max Maximum value -- @return An integer ------------------------------------- function DCSEx.zones.getPropertyInt(zoneTable, propertyName, defaultValue, min, max) local value = DCSEx.zones.getPropertyFloat(zoneTable, propertyName, defaultValue, min, max) if not value then return nil end return math.floor(value) end ------------------------------------- -- Gets the value of a property of a trigger zone and parse it according to two correspondance tables -- @param zoneTable The zone table, returned by DCSEx.zones.getAll() or DCSEx.zones.getByName(name) -- @param propertyName Case-insensitive name of the property -- @param stringTable A table of strings -- @param valueTable A values, matching the strings table's indices -- @param defaultValue Default value to return if no match was found -- @return A value ------------------------------------- function DCSEx.zones.getPropertyParse(zoneTable, propertyName, stringTable, valueTable, defaultValue) local value = DCSEx.zones.getProperty(zoneTable, propertyName) or "" value = value:lower() for i,_ in ipairs(stringTable) do if value == stringTable[i]:lower() then return valueTable[i] end end return defaultValue end ------------------------------------- -- Returns the value of the property of a trigger zone, as a table of comma-separated lowercase strings -- @param zoneTable The zone table, returned by DCSEx.zones.getAll() or DCSEx.zones.getByName(name) -- @param propertyName Case-insensitive name of the property -- @return An table ------------------------------------- function DCSEx.zones.getPropertyTable(zoneTable, propertyName) local value = DCSEx.zones.getProperty(zoneTable, propertyName) if not value then return {} end return string.split(value:lower(), ",") end ------------------------------------- -- Returns the radius of a zone, in meter -- @param zoneTable The zone table, returned by DCSEx.zones.getAll() or DCSEx.zones.getByName(name) -- @param useMaxForQuads If true, return largest distance between the center and a vertex. If false (default value), returns the mean distance. Only used if the zone is a quad. -- @return An table ------------------------------------- function DCSEx.zones.getRadius(zoneTable, useMaxForQuads) if not zoneTable then return 0 end useMaxForQuads = useMaxForQuads or false local radius = 0 if zoneTable.type == 2 then -- Zone is a quad for _,v in ipairs(zoneTable.verticies) do if useMaxForQuads then radius = math.max(radius, DCSEx.math.getDistance2D(zoneTable, v)) else radius = radius + DCSEx.math.getDistance2D(zoneTable, v) end end if #zoneTable.verticies > 0 and not useMaxForQuads then radius = radius / #zoneTable.verticies end else radius = zoneTable.radius end return radius end -- TODO: description + file header function DCSEx.zones.getRandomPointInside(zoneTable, surfaceType) local radius = DCSEx.zones.getRadius(zoneTable) for _=1,64 do local point = DCSEx.math.randomPointInCircle(zoneTable, radius, surfaceType) if zoneTable.type == 2 then if not DCSEx.zones.isPointInside(zoneTable, point) then point = nil end end if point then return point end end return nil end ------------------------------------- -- Returns the surface area of a zone -- @param zoneTable The zone table, returned by TMMissionData.getZones() or TMMissionData.getZoneByName(name) -- @return A number, in squared meters ------------------------------------- function DCSEx.zones.getSurfaceArea(zoneTable) if not zoneTable then return 0 end if zoneTable.type == 2 then -- Zone is a quad if not zoneTable.verticies then return 0 end local area = zoneTable.verticies[1].x * zoneTable.verticies[2].y + zoneTable.verticies[2].x * zoneTable.verticies[3].y + zoneTable.verticies[3].x * zoneTable.verticies[4].y + zoneTable.verticies[4].x * zoneTable.verticies[1].y - zoneTable.verticies[2].x * zoneTable.verticies[1].y - zoneTable.verticies[3].x * zoneTable.verticies[2].y - zoneTable.verticies[4].x * zoneTable.verticies[3].y - zoneTable.verticies[1].x * zoneTable.verticies[4].y return math.abs(area) / 2 else -- Zone is a circle if not zoneTable.radius then return 0 end return (zoneTable.radius ^ 2) * math.pi end end ------------------------------------- -- Returns true if a point is inside a zone -- @param zoneTable The zone table, returned by TMMissionData.getZones() or TMMissionData.getZoneByName(name) -- @param point A point, as a vec3 or vec2 -- @return True if the point is inside the zone, false otherwise ------------------------------------- function DCSEx.zones.isPointInside(zoneTable, point) if not point then return false end if point.z then point = DCSEx.math.vec3ToVec2(point) end -- Point was a vec3, convert to vec2 if zoneTable.type == 2 then -- Zone is a quad return DCSEx.math.isPointInsidePolygon(zoneTable.verticies, point) else -- Zone is a circle return DCSEx.math.isPointInsideCircle({x = zoneTable.x, y = zoneTable.y}, zoneTable.radius, point) end end Library.addOns = { } Library.aircraft = { ["A-10A"] = { ["altitude"] = 4000, ["speed"] = 125, ["payload"] = { ["chaff"] = 240, ["flare"] = 120, ["fuel"] = 5029, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [2] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [3] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [4] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [5] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [7] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [8] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [9] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [10] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["antiship"] = { [11] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [10] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [9] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [8] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [7] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [5] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["cap"] = { [1] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [2] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [3] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [4] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [5] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [7] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [8] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [9] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [10] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [2] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [3] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [4] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [5] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [7] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [8] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [9] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [10] = { ["CLSID"] = "{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["strike"] = { [11] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [10] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [9] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [8] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [7] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [5] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } } } }, ["A-10C"] = { ["altitude"] = 4000, ["speed"] = 125, ["payload"] = { ["chaff"] = 240, ["flare"] = 120, ["fuel"] = 5029, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "ALQ_184" }, [2] = { ["CLSID"] = "{319293F2-392C-4617-8315-7C88C22AF7C4}" }, [3] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}" }, [4] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [5] = { ["CLSID"] = "{GBU-38}" }, [7] = { ["CLSID"] = "{GBU-38}" }, [8] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [9] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [5] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "ALQ_184" }, [9] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [8] = { ["CLSID"] = "BRU-42_3*GBU-12" }, [4] = { ["CLSID"] = "BRU-42_3*GBU-12" }, [3] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [1] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["cap"] = { [1] = { ["CLSID"] = "ALQ_184" }, [2] = { ["CLSID"] = "{319293F2-392C-4617-8315-7C88C22AF7C4}" }, [3] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}" }, [4] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [5] = { ["CLSID"] = "{GBU-38}" }, [7] = { ["CLSID"] = "{GBU-38}" }, [8] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [9] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["sead"] = { [1] = { ["CLSID"] = "ALQ_184" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" }, [7] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [8] = { ["CLSID"] = "{CBU_105}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [3] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}" }, [4] = { ["CLSID"] = "{CBU_105}" }, [5] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [9] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}" } }, ["strike"] = { [1] = { ["CLSID"] = "ALQ_184" }, [3] = { ["CLSID"] = "LAU_117_AGM_65G" }, [4] = { ["CLSID"] = "{GBU-38}" }, [5] = { ["CLSID"] = "{GBU-31}" }, [7] = { ["CLSID"] = "{GBU-31}" }, [8] = { ["CLSID"] = "{GBU-38}" }, [9] = { ["CLSID"] = "LAU_117_AGM_65G" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } } } }, ["A-10C_2"] = { ["altitude"] = 4000, ["speed"] = 125, ["payload"] = { ["chaff"] = 240, ["flare"] = 240, ["fuel"] = 5029, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [3] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}" }, [4] = { ["CLSID"] = "{GBU_54_V_1B}" }, [5] = { ["CLSID"] = "{GBU_54_V_1B}" }, [7] = { ["CLSID"] = "{GBU_54_V_1B}" }, [8] = { ["CLSID"] = "{GBU_54_V_1B}" }, [9] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" }, [1] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [2] = { ["CLSID"] = "{LAU-131 - 7 AGR-20A}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [5] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "ALQ_184" }, [9] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [8] = { ["CLSID"] = "BRU-42_3*GBU-12" }, [4] = { ["CLSID"] = "BRU-42_3*GBU-12" }, [3] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [1] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } }, ["cap"] = { [3] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}" }, [4] = { ["CLSID"] = "{GBU_54_V_1B}" }, [5] = { ["CLSID"] = "{GBU_54_V_1B}" }, [7] = { ["CLSID"] = "{GBU_54_V_1B}" }, [8] = { ["CLSID"] = "{GBU_54_V_1B}" }, [9] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" }, [1] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [2] = { ["CLSID"] = "{LAU-131 - 7 AGR-20A}" } }, ["sead"] = { [1] = { ["CLSID"] = "ALQ_184" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" }, [7] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [8] = { ["CLSID"] = "{CBU_105}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [3] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98452}" }, [4] = { ["CLSID"] = "{CBU_105}" }, [5] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [9] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}" } }, ["strike"] = { [1] = { ["CLSID"] = "ALQ_184" }, [3] = { ["CLSID"] = "{GBU-38}" }, [4] = { ["CLSID"] = "{GBU-38}" }, [5] = { ["CLSID"] = "{GBU-31}" }, [7] = { ["CLSID"] = "{GBU-31}" }, [8] = { ["CLSID"] = "{GBU-38}" }, [9] = { ["CLSID"] = "{GBU-38}" }, [10] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [11] = { ["CLSID"] = "{DB434044-F5D0-4F1F-9BA9-B73027E18DD3}" } } } }, ["A-20G"] = { ["altitude"] = 4000, ["speed"] = 125, ["payload"] = { ["fuel"] = 1500, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["cap"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["sead"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["strike"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } } } }, ["A-50"] = { ["altitude"] = 11000, ["speed"] = 220, ["payload"] = { ["chaff"] = 192, ["flare"] = 192, ["fuel"] = 70000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["cap"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["sead"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } }, ["strike"] = { [1] = { ["CLSID"] = "{4xAN-M64_on_InvCountedAttachmentPoints}" } } } }, ["AH-1W"] = { ["altitude"] = 366, ["speed"] = 278, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 1250, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["cap"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["sead"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["strike"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } } } }, ["AH-64A"] = { ["altitude"] = 1402, ["speed"] = 296, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 1157, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["cap"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["sead"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["strike"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } } } }, ["AH-64D"] = { ["altitude"] = 1402, ["speed"] = 296, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 1157, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["cap"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["sead"] = { [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [3] = { ["CLSID"] = "{FD90A1DC-9147-49FA-BF56-CB83EF0BD32B}" }, [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } }, ["strike"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [2] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" } } } }, ["AH-64D_BLK_II"] = { ["altitude"] = 1402, ["speed"] = 296, ["payload"] = { ["chaff"] = 30, ["flare"] = 60, ["fuel"] = 1140, ["gun"] = 100 }, ["properties"] = { ["PltNVG"] = true, ["CpgNVG"] = true, ["FlareBurstCount"] = 0, ["FlareBurstInterval"] = 0, ["FlareSalvoCount"] = 0, ["FlareSalvoInterval"] = 0, ["FlareProgramDelay"] = 0, ["OverrideIFF"] = 0, ["TrackAirTargets"] = true, ["NetCrewControlPriority"] = 0, ["AIDisabled"] = false, ["HumanOrchestra"] = false }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 225, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["cap"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["sead"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["strike"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } } } }, ["AJS37"] = { ["altitude"] = 8400, ["speed"] = 152, ["payload"] = { ["chaff"] = 1080, ["flare"] = 72, ["fuel"] = 4476, ["gun"] = 100 }, ["properties"] = { ["Rb04GroupTarget"] = 3, ["Rb04VinkelHopp"] = 0, ["WeapSafeHeight"] = 1, ["MissionGeneratorSetting"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [5] = { ["CLSID"] = "{RB75}" }, [3] = { ["CLSID"] = "{RB75}" }, [2] = { ["CLSID"] = "{RB75}" }, [6] = { ["CLSID"] = "{RB75}" }, [1] = { ["CLSID"] = "{Robot24J}" }, [7] = { ["CLSID"] = "{Robot24J}" }, [4] = { ["CLSID"] = "{VIGGEN_X-TANK}" } }, ["antiship"] = { [6] = { ["CLSID"] = "{Rb15_HB}" }, [2] = { ["CLSID"] = "{Rb15_HB}" }, [3] = { ["CLSID"] = "{Robot74}" }, [5] = { ["CLSID"] = "{Robot74}" }, [4] = { ["CLSID"] = "{VIGGEN_X-TANK}" } }, ["cap"] = { [5] = { ["CLSID"] = "{Robot74}" }, [3] = { ["CLSID"] = "{Robot74}" }, [6] = { ["CLSID"] = "{Robot74}" }, [2] = { ["CLSID"] = "{Robot74}" }, [4] = { ["CLSID"] = "{VIGGEN_X-TANK}" }, [7] = { ["CLSID"] = "{Robot24J}" }, [1] = { ["CLSID"] = "{Robot24J}" } }, ["sead"] = { [5] = { ["CLSID"] = "{RB75T}" }, [3] = { ["CLSID"] = "{RB75T}" }, [2] = { ["CLSID"] = "{KB}" }, [6] = { ["CLSID"] = "{U22}" }, [4] = { ["CLSID"] = "{VIGGEN_X-TANK}" } }, ["strike"] = { [5] = { ["CLSID"] = "{Robot05}" }, [3] = { ["CLSID"] = "{Robot05}" }, [4] = { ["CLSID"] = "{VIGGEN_X-TANK}" }, [2] = { ["CLSID"] = "{Robot74}" }, [6] = { ["CLSID"] = "{Robot74}" } } } }, ["AV8BNA"] = { ["altitude"] = 5486, ["speed"] = 225, ["payload"] = { ["chaff"] = 60, ["flare"] = 120, ["fuel"] = 3519.423, ["gun"] = 100 }, ["properties"] = { ["LoadWater"] = true, ["MountNVG"] = false, ["ClockTime"] = 1, ["RocketBurst"] = 1, ["EWDispenserTFL"] = 1, ["EWDispenserTFR"] = 1, ["EWDispenserTBL"] = 2, ["EWDispenserTBR"] = 2, ["EWDispenserBL"] = 2, ["EWDispenserBR"] = 2, ["LaserCode100"] = 6, ["LaserCode10"] = 8, ["LaserCode1"] = 8, ["GBULaserCode100"] = 6, ["GBULaserCode10"] = 8, ["GBULaserCode1"] = 8, ["AAR_Zone1"] = 0, ["AAR_Zone2"] = 0, ["AAR_Zone3"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 243, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["antiship"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "LAU_117_AGM_65F" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "LAU_117_AGM_65F" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["sead"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [6] = { ["CLSID"] = "LAU_117_AGM_65F" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "LAU_117_AGM_65F" }, [2] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [7] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_RIGHT}" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_LEFT}" } } } }, ["An-26B"] = { ["altitude"] = 3000, ["speed"] = 120.8, ["payload"] = { ["chaff"] = 384, ["flare"] = 384, ["fuel"] = 5500, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["antiship"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "LAU_117_AGM_65F" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "LAU_117_AGM_65F" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["sead"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [6] = { ["CLSID"] = "LAU_117_AGM_65F" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "LAU_117_AGM_65F" }, [2] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [7] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_RIGHT}" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_LEFT}" } } } }, ["An-30M"] = { ["altitude"] = 3000, ["speed"] = 120.8, ["payload"] = { ["chaff"] = 192, ["flare"] = 192, ["fuel"] = 5500, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["antiship"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "LAU_117_AGM_65F" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "LAU_117_AGM_65F" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["sead"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [6] = { ["CLSID"] = "LAU_117_AGM_65F" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "LAU_117_AGM_65F" }, [2] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [7] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_RIGHT}" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_LEFT}" } } } }, ["B-17G"] = { ["altitude"] = 4000, ["speed"] = 125, ["payload"] = { ["fuel"] = 7600, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["antiship"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "LAU_117_AGM_65F" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "LAU_117_AGM_65F" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [6] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_RIGHT}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [3] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [2] = { ["CLSID"] = "{BRU-42_2*Mk-82SNAKEYE_LEFT}" }, [1] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["sead"] = { [8] = { ["CLSID"] = "{AGM_122_SIDEARM}" }, [7] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [6] = { ["CLSID"] = "LAU_117_AGM_65F" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "LAU_117_AGM_65F" }, [2] = { ["CLSID"] = "{LAU_7_AGM_122_SIDEARM}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [7] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_RIGHT}" }, [6] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [5] = { ["CLSID"] = "{ALQ_164_RF_Jammer}" }, [4] = { ["CLSID"] = "{GAU_12_Equalizer}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{BRU-42A_2*GBU-12_SIDE_LEFT}" } } } }, ["B-1B"] = { ["altitude"] = 6096, ["speed"] = 217, ["payload"] = { ["chaff"] = 480, ["flare"] = 48, ["fuel"] = 88450, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [3] = { ["CLSID"] = "GBU-38*16" }, [2] = { ["CLSID"] = "GBU-38*16" }, [1] = { ["CLSID"] = "GBU-38*16" } }, ["antiship"] = { [3] = { ["CLSID"] = "GBU-31V3B*8" }, [2] = { ["CLSID"] = "GBU-31V3B*8" }, [1] = { ["CLSID"] = "GBU-31V3B*8" } }, ["cap"] = { [3] = { ["CLSID"] = "GBU-38*16" }, [2] = { ["CLSID"] = "GBU-38*16" }, [1] = { ["CLSID"] = "GBU-38*16" } }, ["sead"] = { [3] = { ["CLSID"] = "GBU-38*16" }, [2] = { ["CLSID"] = "GBU-38*16" }, [1] = { ["CLSID"] = "GBU-38*16" } }, ["strike"] = { [3] = { ["CLSID"] = "GBU-31V3B*8" }, [2] = { ["CLSID"] = "GBU-31V3B*8" }, [1] = { ["CLSID"] = "GBU-31V3B*8" } } } }, ["B-52H"] = { ["altitude"] = 6705, ["speed"] = 227, ["payload"] = { ["chaff"] = 1125, ["flare"] = 192, ["fuel"] = 141135, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{585D626E-7F42-4073-AB70-41E728C333E2}" }, [2] = { ["CLSID"] = "{6C47D097-83FF-4FB2-9496-EAB36DDF0B05}" }, [3] = { ["CLSID"] = "{585D626E-7F42-4073-AB70-41E728C333E2}" } }, ["antiship"] = { [2] = { ["CLSID"] = "{46ACDCF8-5451-4E26-BDDB-E78D5830E93C}" } }, ["cap"] = { [1] = { ["CLSID"] = "{585D626E-7F42-4073-AB70-41E728C333E2}" }, [2] = { ["CLSID"] = "{6C47D097-83FF-4FB2-9496-EAB36DDF0B05}" }, [3] = { ["CLSID"] = "{585D626E-7F42-4073-AB70-41E728C333E2}" } }, ["sead"] = { [1] = { ["CLSID"] = "{585D626E-7F42-4073-AB70-41E728C333E2}" }, [2] = { ["CLSID"] = "{6C47D097-83FF-4FB2-9496-EAB36DDF0B05}" }, [3] = { ["CLSID"] = "{585D626E-7F42-4073-AB70-41E728C333E2}" } }, ["strike"] = { [1] = { ["CLSID"] = "{45447F82-01B5-4029-A572-9AAD28AF0275}" }, [2] = { ["CLSID"] = "{8DCAF3A3-7FCF-41B8-BB88-58DEDA878EDE}" }, [3] = { ["CLSID"] = "{45447F82-01B5-4029-A572-9AAD28AF0275}" } } } }, ["Bf-109K-4"] = { ["altitude"] = 5200, ["speed"] = 125, ["payload"] = { ["fuel"] = 296, ["gun"] = 100 }, ["properties"] = { ["MW50TankContents"] = 1, ["Flare_Gun"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 40, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "SC_501_SC250" } }, ["antiship"] = { [1] = { ["CLSID"] = "SC_501_SC500" } }, ["cap"] = { [1] = { ["CLSID"] = "BF109K_4_FUEL_TANK" } }, ["sead"] = { [1] = { ["CLSID"] = "SC_501_SC250" } }, ["strike"] = { [1] = { ["CLSID"] = "SC_501_SC500" } } } }, ["C-101CC"] = { ["altitude"] = 4400, ["speed"] = 125, ["payload"] = { ["fuel"] = 1796, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1, ["MountIFRHood"] = false, ["CameraRecorder"] = false, ["SightSunFilter"] = false, ["NS430allow"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 225, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{C-101-DEFA553}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{A021F29D-18AB-4d3e-985C-FC9C60E35E9E}" }, [6] = { ["CLSID"] = "{A021F29D-18AB-4d3e-985C-FC9C60E35E9E}" }, [7] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [4] = { ["CLSID"] = "{C-101-DEFA553}" }, [6] = { ["CLSID"] = "{1461CD18-429A-42A9-A21F-4C621ECD4573}" }, [2] = { ["CLSID"] = "{1461CD18-429A-42A9-A21F-4C621ECD4573}" } }, ["cap"] = { [7] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [4] = { ["CLSID"] = "{C-101-DEFA553}" } }, ["sead"] = { [4] = { ["CLSID"] = "{C-101-DEFA553}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{A021F29D-18AB-4d3e-985C-FC9C60E35E9E}" }, [6] = { ["CLSID"] = "{A021F29D-18AB-4d3e-985C-FC9C60E35E9E}" }, [7] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "BR_250" }, [6] = { ["CLSID"] = "BR_250" }, [4] = { ["CLSID"] = "{C-101-DEFA553}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } } } }, ["C-101EB"] = { ["altitude"] = 5000, ["speed"] = 125, ["payload"] = { ["fuel"] = 1796, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1, ["MountIFRHood"] = false, ["NS430allow"] = 1, ["SmokeOnGround"] = false }, ["options"] = {}, ["radio"] = { ["frequency"] = 225, ["modulation"] = 0 }, ["pylons"] = {} }, ["C-130"] = { ["altitude"] = 3726, ["speed"] = 174, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 20830, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = {} }, ["C-17A"] = { ["altitude"] = 5486, ["speed"] = 147.2, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 132405, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = {} }, ["C-47"] = { ["altitude"] = 2926, ["speed"] = 125, ["payload"] = { ["fuel"] = 1470, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = {} }, ["CH-47D"] = { ["altitude"] = 670, ["speed"] = 260, ["payload"] = { ["chaff"] = 120, ["flare"] = 120, ["fuel"] = 3600, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["cap"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["sead"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["strike"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } } } }, ["CH-47Fbl1"] = { ["altitude"] = 670, ["speed"] = 260, ["payload"] = { ["chaff"] = 120, ["flare"] = 120, ["fuel"] = 3054.592, ["gun"] = 100 }, ["properties"] = { ["NetCrewControlPriority"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["cap"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["sead"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["strike"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } } } }, ["CH-53E"] = { ["altitude"] = 1158, ["speed"] = 278, ["payload"] = { ["chaff"] = 60, ["flare"] = 60, ["fuel"] = 2880, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["cap"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["sead"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["strike"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } } } }, ["Christen Eagle II"] = { ["altitude"] = 2400, ["speed"] = 67, ["payload"] = { ["fuel"] = 71, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1, ["NS430allow"] = true }, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = {} }, ["E-2C"] = { ["altitude"] = 9000, ["speed"] = 133.3, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 5624, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = {} }, ["E-3A"] = { ["altitude"] = 11000, ["speed"] = 220, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 65000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = {} }, ["F-117A"] = { ["altitude"] = 5480, ["speed"] = 270, ["payload"] = { ["fuel"] = 8255, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{EF0A9419-01D6-473B-99A3-BEBDB923B14D}" }, [2] = { ["CLSID"] = "{EF0A9419-01D6-473B-99A3-BEBDB923B14D}" } }, ["cap"] = { [1] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" } }, ["sead"] = { [1] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" } }, ["strike"] = { [1] = { ["CLSID"] = "{EF0A9419-01D6-473B-99A3-BEBDB923B14D}" }, [2] = { ["CLSID"] = "{EF0A9419-01D6-473B-99A3-BEBDB923B14D}" } } } }, ["F-14A"] = { ["altitude"] = 6460, ["speed"] = 220, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 7348, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [4] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [5] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [8] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [9] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [11] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [12] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [4] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [5] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [8] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [9] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [11] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [12] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [4] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [5] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [8] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [9] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [11] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [12] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [4] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [5] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [8] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [9] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [11] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [12] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [4] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [5] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [8] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [9] = { ["CLSID"] = "{7575BA0B-7294-4844-857B-031A144B2595}" }, [11] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [12] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } } } }, ["F-14A-135-GR"] = { ["altitude"] = 6827, ["speed"] = 223, ["payload"] = { ["chaff"] = 140, ["flare"] = 60, ["fuel"] = 7348, ["gun"] = 100 }, ["properties"] = { ["M61BURST"] = 2, ["ALE39Loadout"] = 0, ["UseLAU138"] = true, ["INSAlignmentStored"] = false, ["TacanChannel"] = 0, ["TacanBand"] = 0, ["IlsChannel"] = 1, ["KY28Key"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{MAK79_MK82 4}" }, [7] = { ["CLSID"] = "{MAK79_MK82 4}" }, [5] = { ["CLSID"] = "{MAK79_MK82 3L}" }, [6] = { ["CLSID"] = "{MAK79_MK82 3R}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [9] = { ["CLSID"] = "{F14-LANTIRN-TP}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [7] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [4] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [1] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" } }, ["cap"] = { [10] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [9] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [7] = { ["CLSID"] = "{AIM_54A_Mk60}" }, [4] = { ["CLSID"] = "{AIM_54A_Mk60}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [1] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [5] = { ["CLSID"] = "{BELLY AIM-7M}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [4] = { ["CLSID"] = "{BRU3242_ADM141}" }, [5] = { ["CLSID"] = "{BRU3242_ADM141}" }, [6] = { ["CLSID"] = "{BRU3242_ADM141}" }, [7] = { ["CLSID"] = "{BRU3242_ADM141}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [9] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [10] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [9] = { ["CLSID"] = "{F14-LANTIRN-TP}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [7] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [4] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [1] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" } } } }, ["F-14B"] = { ["altitude"] = 6827, ["speed"] = 223, ["payload"] = { ["chaff"] = 140, ["flare"] = 60, ["fuel"] = 7348, ["gun"] = 100 }, ["properties"] = { ["M61BURST"] = 0, ["ALE39Loadout"] = 0, ["UseLAU138"] = true, ["INSAlignmentStored"] = false, ["TacanChannel"] = 0, ["TacanBand"] = 0, ["IlsChannel"] = 1, ["KY28Key"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{MAK79_MK82 4}" }, [7] = { ["CLSID"] = "{MAK79_MK82 4}" }, [5] = { ["CLSID"] = "{MAK79_MK82 3L}" }, [6] = { ["CLSID"] = "{MAK79_MK82 3R}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [9] = { ["CLSID"] = "{F14-LANTIRN-TP}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [7] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [4] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [1] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" } }, ["cap"] = { [10] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [9] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [7] = { ["CLSID"] = "{AIM_54A_Mk60}" }, [4] = { ["CLSID"] = "{AIM_54A_Mk60}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [1] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [5] = { ["CLSID"] = "{BELLY AIM-7M}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [4] = { ["CLSID"] = "{BRU3242_ADM141}" }, [5] = { ["CLSID"] = "{BRU3242_ADM141}" }, [6] = { ["CLSID"] = "{BRU3242_ADM141}" }, [7] = { ["CLSID"] = "{BRU3242_ADM141}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [9] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [10] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" }, [9] = { ["CLSID"] = "{F14-LANTIRN-TP}" }, [8] = { ["CLSID"] = "{F14-300gal}" }, [7] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [4] = { ["CLSID"] = "{BRU-32 GBU-12}" }, [3] = { ["CLSID"] = "{F14-300gal}" }, [2] = { ["CLSID"] = "{SHOULDER AIM-7M}" }, [1] = { ["CLSID"] = "{LAU-138 wtip - AIM-9M}" } } } }, ["F-15C"] = { ["altitude"] = 7320, ["speed"] = 220, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 6103, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [6] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [7] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [8] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [11] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [6] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [7] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [8] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [11] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["cap"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [6] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [7] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [8] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [11] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["sead"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [6] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [7] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [8] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [11] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["strike"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [6] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [7] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [8] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [11] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } } } }, ["F-15E"] = { ["altitude"] = 7320, ["speed"] = 220, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 10246, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{GBU-38}" }, [6] = { ["CLSID"] = "{GBU-38}" }, [7] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [9] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [11] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [13] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [14] = { ["CLSID"] = "{GBU-38}" }, [16] = { ["CLSID"] = "{GBU-38}" }, [18] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [19] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [17] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["antiship"] = { [19] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [18] = { ["CLSID"] = "{GBU-31V3B}" }, [17] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [12] = { ["CLSID"] = "{GBU-31V3B}" }, [10] = { ["CLSID"] = "{GBU-31V3B}" }, [8] = { ["CLSID"] = "{GBU-31V3B}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{GBU-31V3B}" }, [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["cap"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [11] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [17] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [13] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [7] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [19] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [9] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [18] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" } }, ["sead"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{GBU-38}" }, [6] = { ["CLSID"] = "{GBU-38}" }, [7] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [9] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [10] = { ["CLSID"] = "{E1F29B21-F291-4589-9FD8-3272EEC69506}" }, [11] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [13] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [14] = { ["CLSID"] = "{GBU-38}" }, [16] = { ["CLSID"] = "{GBU-38}" }, [18] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" }, [19] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [17] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [19] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [18] = { ["CLSID"] = "{GBU-31V3B}" }, [17] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [12] = { ["CLSID"] = "{GBU-31V3B}" }, [10] = { ["CLSID"] = "{GBU-31V3B}" }, [8] = { ["CLSID"] = "{GBU-31V3B}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{GBU-31V3B}" }, [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } } } }, ["F-15ESE"] = { ["altitude"] = 7320, ["speed"] = 254, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 10245.529841877513, ["gun"] = 100 }, ["properties"] = { ["MountNVG"] = false, ["needsGCAlign"] = false, ["InitAirborneTime"] = 0, ["InitAlertStatus"] = false, ["Sta2LaserCode"] = 688, ["LCFTLaserCode"] = 688, ["Sta5LaserCode"] = 688, ["RCFTLaserCode"] = 688, ["Sta8LaserCode"] = 688, ["SoloFlight"] = false, ["NetCrewControlPriority"] = 0, ["HumanOrchestra"] = false }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 243, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{CFT_L_MK82LD_x_6}" }, [7] = { ["CLSID"] = "{F-15E_AAQ-14_LANTIRN}" }, [8] = { ["CLSID"] = "" }, [9] = { ["CLSID"] = "{F-15E_AAQ-13_LANTIRN}" }, [12] = { ["CLSID"] = "{CFT_R_CBU_97_x_3}" }, [13] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [14] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [15] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{CFT_L_GBU_12_x_4}" }, [7] = { ["CLSID"] = "{F-15E_AAQ-14_LANTIRN}" }, [8] = { ["CLSID"] = "" }, [9] = { ["CLSID"] = "{F-15E_AAQ-13_LANTIRN}" }, [12] = { ["CLSID"] = "{CFT_R_GBU_10_x_2}" }, [13] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [15] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [14] = { ["CLSID"] = "{F15E_EXTTANK}" }, [2] = { ["CLSID"] = "{F15E_EXTTANK}" } }, ["cap"] = { [15] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [14] = { ["CLSID"] = "{F15E_EXTTANK}" }, [13] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [11] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [10] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [6] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [5] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{F15E_EXTTANK}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{CFT_L_MK82LD_x_6}" }, [7] = { ["CLSID"] = "{F-15E_AAQ-14_LANTIRN}" }, [8] = { ["CLSID"] = "" }, [9] = { ["CLSID"] = "{F-15E_AAQ-13_LANTIRN}" }, [12] = { ["CLSID"] = "{CFT_R_CBU_97_x_3}" }, [13] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [14] = { ["CLSID"] = "{AB8B8299-F1CC-4359-89B5-2172E0CF4A5A}" }, [15] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{CFT_L_GBU_12_x_4}" }, [7] = { ["CLSID"] = "{F-15E_AAQ-14_LANTIRN}" }, [8] = { ["CLSID"] = "" }, [9] = { ["CLSID"] = "{F-15E_AAQ-13_LANTIRN}" }, [12] = { ["CLSID"] = "{CFT_R_GBU_10_x_2}" }, [13] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [15] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [14] = { ["CLSID"] = "{F15E_EXTTANK}" }, [2] = { ["CLSID"] = "{F15E_EXTTANK}" } } } }, ["F-16A"] = { ["altitude"] = 6096, ["speed"] = 220, ["payload"] = { ["chaff"] = 60, ["flare"] = 30, ["fuel"] = 3104, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "ALQ_184" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [3] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } }, ["cap"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } }, ["sead"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [3] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } }, ["strike"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [5] = { ["CLSID"] = "{CAAC1CFD-6745-416B-AFA4-CB57414856D0}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } } } }, ["F-16A MLU"] = { ["altitude"] = 6096, ["speed"] = 220, ["payload"] = { ["chaff"] = 60, ["flare"] = 30, ["fuel"] = 3104, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [3] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" }, [4] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" }, [8] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } }, ["cap"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } }, ["sead"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [3] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [4] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [8] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{CAAC1CFD-6745-416B-AFA4-CB57414856D0}" } }, ["strike"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [5] = { ["CLSID"] = "{CAAC1CFD-6745-416B-AFA4-CB57414856D0}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } } } }, ["F-16C bl.50"] = { ["altitude"] = 6096, ["speed"] = 220, ["payload"] = { ["chaff"] = 90, ["flare"] = 45, ["fuel"] = 3104, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [7] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [4] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [3] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [6] = { ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "LAU_117_AGM_65G" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [3] = { ["CLSID"] = "LAU_117_AGM_65G" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["cap"] = { [10] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [3] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [6] = { ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}" } }, ["sead"] = { [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [7] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [4] = { ["CLSID"] = "{5335D97A-35A5-4643-9D9B-026C75961E52}" }, [3] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [6] = { ["CLSID"] = "{8A0BE8AE-58D4-4572-9263-3144C0D06364}" } }, ["strike"] = { [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "{GBU-31V3B}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [3] = { ["CLSID"] = "{GBU-31V3B}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } } } }, ["F-16C bl.52d"] = { ["altitude"] = 6096, ["speed"] = 220, ["payload"] = { ["chaff"] = 90, ["flare"] = 45, ["fuel"] = 3104, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "LAU_117_AGM_65G" }, [7] = { ["CLSID"] = "LAU_117_AGM_65G" }, [6] = { ["CLSID"] = "ALQ_184" }, [4] = { ["CLSID"] = "LAU_117_AGM_65G" }, [3] = { ["CLSID"] = "LAU_117_AGM_65G" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["cap"] = { [10] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [8] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [6] = { ["CLSID"] = "ALQ_184" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [3] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" } }, ["sead"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [3] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [4] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [8] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" } }, ["strike"] = { [1] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{GBU-31V3B}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [5] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" }, [6] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [7] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [8] = { ["CLSID"] = "{GBU-31V3B}" }, [10] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" } } } }, ["F-16C_50"] = { ["altitude"] = 6096, ["speed"] = 220, ["payload"] = { ["chaff"] = 60, ["flare"] = 60, ["fuel"] = 3249, ["gun"] = 100 }, ["properties"] = { ["LAU3ROF"] = 0, ["HelmetMountedDevice"] = 1 }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [3] = { ["CLSID"] = "{TER_9A_2R*GBU-12}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [5] = { ["CLSID"] = "ALQ_184_Long" }, [6] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [7] = { ["CLSID"] = "{E6A6262A-CA08-4B3D-B030-E1A993B98453}" }, [8] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [9] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [11] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [3] = { ["CLSID"] = "LAU_117_AGM_65H" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [5] = { ["CLSID"] = "ALQ_184_Long" }, [6] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [7] = { ["CLSID"] = "LAU_117_AGM_65H" }, [8] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [9] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [11] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" } }, ["cap"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [3] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [5] = { ["CLSID"] = "ALQ_184_Long" }, [6] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [7] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [8] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [9] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [11] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" } }, ["sead"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [3] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [4] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [5] = { ["CLSID"] = "ALQ_184_Long" }, [6] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [7] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [8] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [9] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [10] = { ["CLSID"] = "{AN_ASQ_213}" }, [11] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" } }, ["strike"] = { [1] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [3] = { ["CLSID"] = "{GBU-31V3B}" }, [4] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [5] = { ["CLSID"] = "ALQ_184_Long" }, [6] = { ["CLSID"] = "{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}" }, [7] = { ["CLSID"] = "{GBU-31V3B}" }, [8] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [9] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [11] = { ["CLSID"] = "{A111396E-D3E8-4b9c-8AC9-2432489304D5}" } } } }, ["F-4E"] = { ["altitude"] = 7162, ["speed"] = 256, ["payload"] = { ["chaff"] = 60, ["flare"] = 30, ["fuel"] = 4864, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{1C97B4A0-AA3B-43A8-8EE7-D11071457185}" }, [2] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [3] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [4] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [8] = { ["CLSID"] = "{60CC734F-0AFA-4E2E-82B8-93B941AB11CF}" }, [9] = { ["CLSID"] = "{1C97B4A0-AA3B-43A8-8EE7-D11071457185}" } }, ["antiship"] = { [9] = { ["CLSID"] = "{7B4B122D-C12C-4DB4-834E-4D8BB4D863A8}" }, [8] = { ["CLSID"] = "{D7670BC7-881B-4094-906C-73879CF7EB27}" }, [7] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [5] = { ["CLSID"] = "{8B9E3FD0-F034-4A07-B6CE-C269884CC71B}" }, [4] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [3] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [2] = { ["CLSID"] = "{D7670BC7-881B-4094-906C-73879CF7EB28}" }, [1] = { ["CLSID"] = "{7B4B122D-C12C-4DB4-834E-4D8BB4D863A8}" } }, ["cap"] = { [1] = { ["CLSID"] = "{7B4B122D-C12C-4DB4-834E-4D8BB4D863A8}" }, [2] = { ["CLSID"] = "{9DDF5297-94B9-42FC-A45E-6E316121CD85}" }, [3] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [4] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [8] = { ["CLSID"] = "{9DDF5297-94B9-42FC-A45E-6E316121CD85}" }, [9] = { ["CLSID"] = "{7B4B122D-C12C-4DB4-834E-4D8BB4D863A8}" } }, ["sead"] = { [1] = { ["CLSID"] = "{3E6B632D-65EB-44D2-9501-1C2D04515405}" }, [2] = { ["CLSID"] = "{3E6B632D-65EB-44D2-9501-1C2D04515405}" }, [3] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [4] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [8] = { ["CLSID"] = "{3E6B632D-65EB-44D2-9501-1C2D04515405}" }, [9] = { ["CLSID"] = "{3E6B632D-65EB-44D2-9501-1C2D04515405}" } }, ["strike"] = { [1] = { ["CLSID"] = "{7B4B122D-C12C-4DB4-834E-4D8BB4D863A8}" }, [2] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [3] = { ["CLSID"] = "{6D21ECEA-F85B-4E8D-9D51-31DC9B8AA4EF}" }, [4] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [8] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [9] = { ["CLSID"] = "{7B4B122D-C12C-4DB4-834E-4D8BB4D863A8}" } } } }, ["F-4E-45MC"] = { ["altitude"] = 7200, ["speed"] = 257, ["payload"] = { ["chaff"] = 120, ["flare"] = 30, ["fuel"] = 5510.5, ["gun"] = 100 }, ["properties"] = { ["Quality"] = 100, ["Wear"] = 0, ["UseReferenceAircraft"] = false, ["INSAlignmentStored"] = true, ["IsModifiedJesterAllowed"] = true, ["IsNvgAllowed"] = true, ["TacanChannel"] = 0, ["TacanBand"] = 0, ["VORILSFrequencyMHZ"] = 108, ["VORILSFrequencyDecimalMHZ"] = 0, ["KY28Key"] = 1, ["ChaffDoubleDispense"] = false, ["IffMode2Digit1"] = 0, ["IffMode2Digit2"] = 0, ["IffMode2Digit3"] = 0, ["IffMode2Digit4"] = 0, ["LaserCodeDigit1"] = 1, ["LaserCodeDigit2"] = 6, ["LaserCodeDigit3"] = 8, ["LaserCodeDigit4"] = 8 }, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [13] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [9] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [8] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [7] = { ["CLSID"] = "{F4_SARGENT_TANK_600_GAL}" }, [6] = { ["CLSID"] = "{HB_PAVE_SPIKE_FAST_ON_ADAPTER_IN_AERO7}" }, [5] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [1] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [11] = { ["CLSID"] = "{HB_F4EAGM-65D_LAU88_2x_Right}" }, [3] = { ["CLSID"] = "{HB_F4EAGM-65D_LAU88_2x_Left}" }, [14] = { ["CLSID"] = "{HB_ALE_40_30_60}" }, [4] = { ["CLSID"] = "" }, [2] = { ["CLSID"] = "" }, [12] = { ["CLSID"] = "" }, [10] = { ["CLSID"] = "" } }, ["antiship"] = { [13] = { ["CLSID"] = "{34759BBC-AF1E-4AEE-A581-498FF7A6EBCE}" }, [9] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [8] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [7] = { ["CLSID"] = "{F4_SARGENT_TANK_600_GAL}" }, [6] = { ["CLSID"] = "{HB_PAVE_SPIKE_FAST_ON_ADAPTER_IN_AERO7}" }, [5] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [1] = { ["CLSID"] = "{34759BBC-AF1E-4AEE-A581-498FF7A6EBCE}" }, [11] = { ["CLSID"] = "{C40A1E3A-DD05-40D9-85A4-217729E37FAE}" }, [14] = { ["CLSID"] = "{HB_ALE_40_30_60}" }, [12] = { ["CLSID"] = "" }, [10] = { ["CLSID"] = "" }, [4] = { ["CLSID"] = "" }, [2] = { ["CLSID"] = "" }, [3] = { ["CLSID"] = "{C40A1E3A-DD05-40D9-85A4-217729E37FAE}" } }, ["cap"] = { [12] = { ["CLSID"] = "{AIM-9M}" }, [10] = { ["CLSID"] = "{AIM-9M}" }, [8] = { ["CLSID"] = "{HB_F4E_AIM-7M}" }, [9] = { ["CLSID"] = "{HB_F4E_AIM-7M}" }, [6] = { ["CLSID"] = "{HB_F4E_AIM-7M}" }, [5] = { ["CLSID"] = "{HB_F4E_AIM-7M}" }, [4] = { ["CLSID"] = "{AIM-9M}" }, [2] = { ["CLSID"] = "{AIM-9M}" }, [13] = { ["CLSID"] = "{F4_SARGENT_TANK_370_GAL_R}" }, [1] = { ["CLSID"] = "{F4_SARGENT_TANK_370_GAL}" }, [14] = { ["CLSID"] = "{HB_ALE_40_30_60}" } }, ["sead"] = { [14] = { ["CLSID"] = "{HB_ALE_40_30_60}" }, [13] = { ["CLSID"] = "{LAU_34_AGM_45A}" }, [11] = { ["CLSID"] = "{LAU_34_AGM_45A}" }, [9] = { ["CLSID"] = "{HB_F4E_AIM-7F}" }, [8] = { ["CLSID"] = "{HB_F4E_AIM-7F}" }, [7] = { ["CLSID"] = "{F4_SARGENT_TANK_600_GAL}" }, [6] = { ["CLSID"] = "{HB_ALQ-131_ON_ADAPTER_IN_AERO7}" }, [5] = { ["CLSID"] = "{HB_F4E_AIM-7F}" }, [3] = { ["CLSID"] = "{LAU_34_AGM_45A}" }, [1] = { ["CLSID"] = "{LAU_34_AGM_45A}" }, [12] = { ["CLSID"] = "" }, [10] = { ["CLSID"] = "" }, [4] = { ["CLSID"] = "" }, [2] = { ["CLSID"] = "" } }, ["strike"] = { [13] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [9] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [8] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [7] = { ["CLSID"] = "{F4_SARGENT_TANK_600_GAL}" }, [6] = { ["CLSID"] = "{HB_PAVE_SPIKE_FAST_ON_ADAPTER_IN_AERO7}" }, [5] = { ["CLSID"] = "{HB_F4E_AIM-7E-2}" }, [1] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [14] = { ["CLSID"] = "{HB_ALE_40_30_60}" }, [11] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [3] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [12] = { ["CLSID"] = "" }, [10] = { ["CLSID"] = "" }, [4] = { ["CLSID"] = "" }, [2] = { ["CLSID"] = "" } } } }, ["F-5E"] = { ["altitude"] = 6461, ["speed"] = 174, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 1996, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [4] = { ["CLSID"] = "{MER-5E_Mk82SNAKEYEx5}" }, [5] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [4] = { ["CLSID"] = "{MER-5E_Mk82SNAKEYEx5}" }, [5] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } }, ["cap"] = { [7] = { ["CLSID"] = "{AIM-9P5}" }, [5] = { ["CLSID"] = "{PTB-150GAL}" }, [4] = { ["CLSID"] = "{PTB-150GAL}" }, [3] = { ["CLSID"] = "{PTB-150GAL}" }, [1] = { ["CLSID"] = "{AIM-9P5}" } }, ["sead"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [4] = { ["CLSID"] = "{MER-5E_Mk82SNAKEYEx5}" }, [5] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } }, ["strike"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [4] = { ["CLSID"] = "{MER-5E_Mk82SNAKEYEx5}" }, [5] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } } } }, ["F-5E-3"] = { ["altitude"] = 6461, ["speed"] = 174, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 2046, ["gun"] = 100 }, ["properties"] = { ["LAU3ROF"] = 0, ["LAU68ROF"] = 0, ["ChaffBurst"] = 0, ["ChaffSalvo"] = 0, ["ChaffBurstInt"] = 0, ["ChaffSalvoInt"] = 0, ["FlareBurst"] = 0, ["FlareBurstInt"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [4] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [5] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9P5}" }, [1] = { ["CLSID"] = "{AIM-9P5}" }, [6] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{PTB-150GAL}" } }, ["cap"] = { [7] = { ["CLSID"] = "{AIM-9P5}" }, [5] = { ["CLSID"] = "{PTB-150GAL}" }, [4] = { ["CLSID"] = "{PTB-150GAL}" }, [3] = { ["CLSID"] = "{PTB-150GAL}" }, [1] = { ["CLSID"] = "{AIM-9P5}" } }, ["sead"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [4] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [5] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9P5}" }, [1] = { ["CLSID"] = "{AIM-9P5}" }, [6] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{PTB-150GAL}" } } } }, ["F-5E-3_FC"] = { ["altitude"] = 6461, ["speed"] = 174, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 2046, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [4] = { ["CLSID"] = "{MER-5E_Mk82SNAKEYEx5}" }, [5] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9P5}" }, [1] = { ["CLSID"] = "{AIM-9P5}" }, [6] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{PTB-150GAL}" } }, ["cap"] = { [7] = { ["CLSID"] = "{AIM-9P5}" }, [5] = { ["CLSID"] = "{PTB-150GAL}" }, [4] = { ["CLSID"] = "{PTB-150GAL}" }, [3] = { ["CLSID"] = "{PTB-150GAL}" }, [1] = { ["CLSID"] = "{AIM-9P5}" } }, ["sead"] = { [1] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" }, [2] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [4] = { ["CLSID"] = "{MER-5E_Mk82SNAKEYEx5}" }, [5] = { ["CLSID"] = "{0395076D-2F77-4420-9D33-087A4398130B}" }, [6] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{9BFD8C90-F7AE-4e90-833B-BFD0CED0E536}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9P5}" }, [1] = { ["CLSID"] = "{AIM-9P5}" }, [6] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{PTB-150GAL}" } } } }, ["F-86F Sabre"] = { ["altitude"] = 6040, ["speed"] = 237, ["payload"] = { ["fuel"] = 1282, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 225, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [10] = { ["CLSID"] = "{HVARx2}" }, [9] = { ["CLSID"] = "{HVARx2}" }, [8] = { ["CLSID"] = "{HVARx2}" }, [7] = { ["CLSID"] = "{HVARx2}" }, [4] = { ["CLSID"] = "{HVARx2}" }, [3] = { ["CLSID"] = "{HVARx2}" }, [2] = { ["CLSID"] = "{HVARx2}" }, [1] = { ["CLSID"] = "{HVARx2}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" }, [4] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" } }, ["cap"] = { [6] = { ["CLSID"] = "{GAR-8}" }, [5] = { ["CLSID"] = "{GAR-8}" } }, ["sead"] = { [10] = { ["CLSID"] = "{HVARx2}" }, [9] = { ["CLSID"] = "{HVARx2}" }, [8] = { ["CLSID"] = "{HVARx2}" }, [7] = { ["CLSID"] = "{HVARx2}" }, [4] = { ["CLSID"] = "{HVARx2}" }, [3] = { ["CLSID"] = "{HVARx2}" }, [2] = { ["CLSID"] = "{HVARx2}" }, [1] = { ["CLSID"] = "{HVARx2}" } }, ["strike"] = { [7] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" }, [4] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" } } } }, ["F-86F_FC"] = { ["altitude"] = 6040, ["speed"] = 237, ["payload"] = { ["fuel"] = 1282, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 225, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{F86ANM64}" }, [4] = { ["CLSID"] = "{F86ANM64}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" }, [4] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" } }, ["cap"] = { [4] = { ["CLSID"] = "{PTB_120_F86F35}" }, [7] = { ["CLSID"] = "{PTB_120_F86F35}" } }, ["sead"] = { [7] = { ["CLSID"] = "{F86ANM64}" }, [4] = { ["CLSID"] = "{F86ANM64}" } }, ["strike"] = { [7] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" }, [4] = { ["CLSID"] = "{00F5DAC4-0466-4122-998F-B1A298E34113}" } } } }, ["F/A-18A"] = { ["altitude"] = 6096, ["speed"] = 180, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 4930, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{D5D51E24-348C-4702-96AF-97A714E72697}" }, [3] = { ["CLSID"] = "{D5D51E24-348C-4702-96AF-97A714E72697}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{D5D51E24-348C-4702-96AF-97A714E72697}" }, [8] = { ["CLSID"] = "{D5D51E24-348C-4702-96AF-97A714E72697}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [3] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [8] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [3] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [4] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [5] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [8] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [3] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [8] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [3] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [8] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } } } }, ["F/A-18C"] = { ["altitude"] = 6096, ["speed"] = 180, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 4900, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [3] = { ["CLSID"] = "{D5D51E24-348C-4702-96AF-97A714E72697}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{1C2B16EB-8EB0-43de-8788-8EBB2D70B8BC}" }, [7] = { ["CLSID"] = "{D5D51E24-348C-4702-96AF-97A714E72697}" }, [8] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [3] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [8] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [3] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [4] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [5] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [7] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [8] = { ["CLSID"] = "{C8E06185-7CD6-4C90-959F-044679E90751}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [3] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8200-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [8] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["strike"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [3] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [4] = { ["CLSID"] = "{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}" }, [5] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [6] = { ["CLSID"] = "{8D399DDA-FF81-4F14-904D-099B34FE7918}" }, [7] = { ["CLSID"] = "{EFEC8201-B922-11d7-9897-000476191836}" }, [8] = { ["CLSID"] = "{51F9AAE5-964F-4D21-83FB-502E3BFE5F8A}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } } } }, ["F4U-1D"] = { ["altitude"] = 4721, ["speed"] = 102, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 662, ["gun"] = 100 }, ["properties"] = { ["F4U_CustomGunsFiringPattern"] = false, ["F4U_GunsConvergence_Inner"] = 2, ["F4U_GunsConvergence_Mid"] = 2, ["F4U_GunsConvergence_Outer"] = 2 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{Tiny_Tim_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{Tiny_Tim_Corsair}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [2] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [11] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [10] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" } }, ["cap"] = { [7] = { ["CLSID"] = "{Tiny_Tim_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{Tiny_Tim_Corsair}" } }, ["sead"] = { [7] = { ["CLSID"] = "{Tiny_Tim_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{Tiny_Tim_Corsair}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AN-M64}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{AN-M64}" } } } }, ["F4U-1D_CW"] = { ["altitude"] = 4721, ["speed"] = 102, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 662, ["gun"] = 100 }, ["properties"] = { ["F4U_CustomGunsFiringPattern"] = false, ["F4U_GunsConvergence_Inner"] = 2, ["F4U_GunsConvergence_Mid"] = 2, ["F4U_GunsConvergence_Outer"] = 2, ["F4U_CW_number"] = true, ["F4U_CW_number_1"] = 4, ["F4U_CW_number_2"] = 6, ["F4U_CW_number_3"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{Tiny_Tim_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{Tiny_Tim_Corsair}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [2] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [11] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [10] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" } }, ["cap"] = { [7] = { ["CLSID"] = "{Tiny_Tim_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{Tiny_Tim_Corsair}" } }, ["sead"] = { [7] = { ["CLSID"] = "{Tiny_Tim_Corsair}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{Tiny_Tim_Corsair}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AN-M64}" }, [8] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [3] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [4] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [9] = { ["CLSID"] = "{HVAR_USN_Mk28_Mod4_Corsair}" }, [5] = { ["CLSID"] = "{AN-M64}" } } } }, ["FA-18C_hornet"] = { ["altitude"] = 7280, ["speed"] = 180, ["payload"] = { ["chaff"] = 60, ["flare"] = 60, ["fuel"] = 4900, ["gun"] = 100 }, ["properties"] = { ["OuterBoard"] = 0, ["InnerBoard"] = 0, ["HelmetMountedDevice"] = 1 }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [9] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [1] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [2] = { ["CLSID"] = "{BRU55_2*GBU-38}" }, [3] = { ["CLSID"] = "{BRU33_2X_GBU-12}" }, [4] = { ["CLSID"] = "{AN_ASQ_228}" }, [5] = { ["CLSID"] = "{FPU_8A_FUEL_TANK}" }, [6] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [7] = { ["CLSID"] = "{BRU33_2X_GBU-12}" }, [8] = { ["CLSID"] = "{BRU55_2*GBU-38}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{AGM_84D}" }, [3] = { ["CLSID"] = "{AGM_84D}" }, [4] = { ["CLSID"] = "{AN_ASQ_228}" }, [5] = { ["CLSID"] = "{FPU_8A_FUEL_TANK}" }, [6] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [7] = { ["CLSID"] = "{AGM_84D}" }, [8] = { ["CLSID"] = "{AGM_84D}" }, [9] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" } }, ["cap"] = { [9] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [1] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [4] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [6] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [2] = { ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C" }, [8] = { ["CLSID"] = "LAU-115_2*LAU-127_AIM-120C" }, [3] = { ["CLSID"] = "" }, [5] = { ["CLSID"] = "" }, [7] = { ["CLSID"] = "" } }, ["sead"] = { [9] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [1] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [2] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [3] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [4] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [5] = { ["CLSID"] = "{FPU_8A_FUEL_TANK}" }, [6] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [7] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [8] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" } }, ["strike"] = { [1] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [9] = { ["CLSID"] = "{5CE2FF2A-645A-4197-B48D-8720AC69394F}" }, [2] = { ["CLSID"] = "{AGM_84H}" }, [3] = { ["CLSID"] = "{FPU_8A_FUEL_TANK}" }, [4] = { ["CLSID"] = "{AN_ASQ_228}" }, [5] = { ["CLSID"] = "{AWW-13}" }, [6] = { ["CLSID"] = "{40EF17B7-F508-45de-8566-6FFECC0C1AB8}" }, [7] = { ["CLSID"] = "{FPU_8A_FUEL_TANK}" }, [8] = { ["CLSID"] = "{AGM_84H}" } } } }, ["FW-190A8"] = { ["altitude"] = 4400, ["speed"] = 125, ["payload"] = { ["fuel"] = 409, ["gun"] = 100 }, ["properties"] = { ["FW_MW50TankContents"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 38.4, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "ER_4_SC50" } }, ["antiship"] = { [1] = { ["CLSID"] = "ER_4_SC50" } }, ["cap"] = { [1] = { ["CLSID"] = "ER_4_SC50" } }, ["sead"] = { [1] = { ["CLSID"] = "ER_4_SC50" } }, ["strike"] = { [1] = { ["CLSID"] = "ER_4_SC50" } } } }, ["FW-190D9"] = { ["altitude"] = 5200, ["speed"] = 125, ["payload"] = { ["fuel"] = 388, ["gun"] = 100 }, ["properties"] = { ["FW_MW50TankContents"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 38.4, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "SC_501_SC500" } }, ["antiship"] = { [1] = { ["CLSID"] = "SC_501_SC500" } }, ["cap"] = { [3] = { ["CLSID"] = "{WGr21}" }, [2] = { ["CLSID"] = "{WGr21}" } }, ["sead"] = { [1] = { ["CLSID"] = "SC_501_SC500" } }, ["strike"] = { [1] = { ["CLSID"] = "SC_501_SC500" } } } }, ["Falcon_Gyrocopter"] = { ["altitude"] = 1200, ["speed"] = 38.888888888888886, ["payload"] = { ["fuel"] = 54, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 243, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "SC_501_SC500" } }, ["antiship"] = { [1] = { ["CLSID"] = "SC_501_SC500" } }, ["cap"] = { [3] = { ["CLSID"] = "{WGr21}" }, [2] = { ["CLSID"] = "{WGr21}" } }, ["sead"] = { [1] = { ["CLSID"] = "SC_501_SC500" } }, ["strike"] = { [1] = { ["CLSID"] = "SC_501_SC500" } } } }, ["H-6J"] = { ["altitude"] = 5240, ["speed"] = 213.33, ["payload"] = { ["chaff"] = 120, ["flare"] = 120, ["fuel"] = 25000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [8] = { ["CLSID"] = "DIS_H6_250_2_N24" } }, ["antiship"] = { [3] = { ["CLSID"] = "DIS_DF4B_YJ12" }, [4] = { ["CLSID"] = "DIS_DF4B_YJ12" }, [5] = { ["CLSID"] = "DIS_DF4B_YJ12" }, [2] = { ["CLSID"] = "DIS_DF4B_YJ12" } }, ["cap"] = { [8] = { ["CLSID"] = "DIS_H6_250_2_N24" } }, ["sead"] = { [8] = { ["CLSID"] = "DIS_H6_250_2_N24" } }, ["strike"] = { [2] = { ["CLSID"] = "DIS_GDJ_KD63" }, [7] = { ["CLSID"] = "DIS_AKG_DLPOD" }, [3] = { ["CLSID"] = "DIS_GDJ_KD63" }, [4] = { ["CLSID"] = "DIS_GDJ_KD63" }, [5] = { ["CLSID"] = "DIS_GDJ_KD63" } } } }, ["Hawk"] = { ["altitude"] = 5852, ["speed"] = 231, ["payload"] = { ["fuel"] = 1272, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [8] = { ["CLSID"] = "DIS_H6_250_2_N24" } }, ["antiship"] = { [3] = { ["CLSID"] = "DIS_DF4B_YJ12" }, [4] = { ["CLSID"] = "DIS_DF4B_YJ12" }, [5] = { ["CLSID"] = "DIS_DF4B_YJ12" }, [2] = { ["CLSID"] = "DIS_DF4B_YJ12" } }, ["cap"] = { [8] = { ["CLSID"] = "DIS_H6_250_2_N24" } }, ["sead"] = { [8] = { ["CLSID"] = "DIS_H6_250_2_N24" } }, ["strike"] = { [2] = { ["CLSID"] = "DIS_GDJ_KD63" }, [7] = { ["CLSID"] = "DIS_AKG_DLPOD" }, [3] = { ["CLSID"] = "DIS_GDJ_KD63" }, [4] = { ["CLSID"] = "DIS_GDJ_KD63" }, [5] = { ["CLSID"] = "DIS_GDJ_KD63" } } } }, ["I-16"] = { ["altitude"] = 3880, ["speed"] = 97, ["payload"] = { ["fuel"] = 191, ["gun"] = 100 }, ["properties"] = { ["landingTorch"] = false }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["antiship"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["cap"] = { [4] = { ["CLSID"] = "I16_DROP_FUEL_TANK" }, [5] = { ["CLSID"] = "I16_DROP_FUEL_TANK" } }, ["sead"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["strike"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } } } }, ["IL-76MD"] = { ["altitude"] = 4800, ["speed"] = 208, ["payload"] = { ["chaff"] = 96, ["flare"] = 96, ["fuel"] = 87584, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["antiship"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["cap"] = { [4] = { ["CLSID"] = "I16_DROP_FUEL_TANK" }, [5] = { ["CLSID"] = "I16_DROP_FUEL_TANK" } }, ["sead"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["strike"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } } } }, ["IL-78M"] = { ["altitude"] = 4800, ["speed"] = 208, ["payload"] = { ["chaff"] = 96, ["flare"] = 96, ["fuel"] = 112000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["antiship"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["cap"] = { [4] = { ["CLSID"] = "I16_DROP_FUEL_TANK" }, [5] = { ["CLSID"] = "I16_DROP_FUEL_TANK" } }, ["sead"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } }, ["strike"] = { [1] = { ["CLSID"] = "I16_RS_82" }, [2] = { ["CLSID"] = "I16_RS_82" }, [3] = { ["CLSID"] = "I16_RS_82" }, [6] = { ["CLSID"] = "I16_RS_82" }, [7] = { ["CLSID"] = "I16_RS_82" }, [8] = { ["CLSID"] = "I16_RS_82" }, [4] = { ["CLSID"] = "I16_FAB_100SV" }, [5] = { ["CLSID"] = "I16_FAB_100SV" } } } }, ["J-11A"] = { ["altitude"] = 7400, ["speed"] = 170, ["payload"] = { ["chaff"] = 96, ["flare"] = 96, ["fuel"] = 9400, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{B8M1_20_S8KOM_DUAL_L}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{B8M1_20_S8KOM_DUAL_R}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{RKL609_R}" }, [1] = { ["CLSID"] = "{RKL609_L}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{RKL609_R}" }, [1] = { ["CLSID"] = "{RKL609_L}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [8] = { ["CLSID"] = "{S25_DUAL_R}" }, [3] = { ["CLSID"] = "{S25_DUAL_L}" }, [7] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } }, ["cap"] = { [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{B79C379A-9E87-4E50-A1EE-7F7E29C2E87A}" }, [4] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [5] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [6] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [7] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [8] = { ["CLSID"] = "{B79C379A-9E87-4E50-A1EE-7F7E29C2E87A}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{RKL609_L}" }, [10] = { ["CLSID"] = "{RKL609_R}" } }, ["sead"] = { [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{B8M1_20_S8KOM_DUAL_L}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{B8M1_20_S8KOM_DUAL_R}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{RKL609_R}" }, [1] = { ["CLSID"] = "{RKL609_L}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } }, ["strike"] = { [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{FAB_500_DUAL_L}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [7] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [8] = { ["CLSID"] = "{FAB_500_DUAL_R}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{RKL609_R}" }, [1] = { ["CLSID"] = "{RKL609_L}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } } } }, ["JF-17"] = { ["altitude"] = 6768, ["speed"] = 220, ["payload"] = { ["chaff"] = 36, ["flare"] = 32, ["fuel"] = 2325, ["gun"] = 100 }, ["properties"] = { ["LaserCode100"] = 6, ["LaserCode10"] = 8, ["LaserCode1"] = 8, ["AARProbe"] = false }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 243, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_WMD7" }, [3] = { ["CLSID"] = "DIS_TANK1100" }, [5] = { ["CLSID"] = "DIS_TANK1100" }, [6] = { ["CLSID"] = "DIS_GBU_12" }, [2] = { ["CLSID"] = "DIS_GBU_12" } }, ["antiship"] = { [5] = { ["CLSID"] = "DIS_C-802AK" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [3] = { ["CLSID"] = "DIS_C-802AK" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [6] = { ["CLSID"] = "DIS_C-701IR" }, [2] = { ["CLSID"] = "DIS_C-701IR" } }, ["cap"] = { [1] = { ["CLSID"] = "DIS_PL-5EII" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [6] = { ["CLSID"] = "DIS_SD-10_DUAL_R" }, [2] = { ["CLSID"] = "DIS_SD-10_DUAL_L" } }, ["sead"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_SPJ_POD" }, [5] = { ["CLSID"] = "DIS_LS_6_500" }, [3] = { ["CLSID"] = "DIS_LS_6_500" }, [2] = { ["CLSID"] = "DIS_LD-10_DUAL_L" }, [6] = { ["CLSID"] = "DIS_LD-10_DUAL_R" } }, ["strike"] = { [4] = { ["CLSID"] = "DIS_WMD7" }, [5] = { ["CLSID"] = "DIS_GBU_10" }, [3] = { ["CLSID"] = "DIS_GBU_10" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" } } } }, ["Ju-88A4"] = { ["altitude"] = 4000, ["speed"] = 125, ["payload"] = { ["fuel"] = 2120, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_WMD7" }, [3] = { ["CLSID"] = "DIS_TANK1100" }, [5] = { ["CLSID"] = "DIS_TANK1100" }, [6] = { ["CLSID"] = "DIS_GBU_12" }, [2] = { ["CLSID"] = "DIS_GBU_12" } }, ["antiship"] = { [5] = { ["CLSID"] = "DIS_C-802AK" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [3] = { ["CLSID"] = "DIS_C-802AK" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [6] = { ["CLSID"] = "DIS_C-701IR" }, [2] = { ["CLSID"] = "DIS_C-701IR" } }, ["cap"] = { [1] = { ["CLSID"] = "DIS_PL-5EII" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [6] = { ["CLSID"] = "DIS_SD-10_DUAL_R" }, [2] = { ["CLSID"] = "DIS_SD-10_DUAL_L" } }, ["sead"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_SPJ_POD" }, [5] = { ["CLSID"] = "DIS_LS_6_500" }, [3] = { ["CLSID"] = "DIS_LS_6_500" }, [2] = { ["CLSID"] = "DIS_LD-10_DUAL_L" }, [6] = { ["CLSID"] = "DIS_LD-10_DUAL_R" } }, ["strike"] = { [4] = { ["CLSID"] = "DIS_WMD7" }, [5] = { ["CLSID"] = "DIS_GBU_10" }, [3] = { ["CLSID"] = "DIS_GBU_10" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" } } } }, ["KC-135"] = { ["altitude"] = 4800, ["speed"] = 220, ["payload"] = { ["fuel"] = 90700, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_WMD7" }, [3] = { ["CLSID"] = "DIS_TANK1100" }, [5] = { ["CLSID"] = "DIS_TANK1100" }, [6] = { ["CLSID"] = "DIS_GBU_12" }, [2] = { ["CLSID"] = "DIS_GBU_12" } }, ["antiship"] = { [5] = { ["CLSID"] = "DIS_C-802AK" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [3] = { ["CLSID"] = "DIS_C-802AK" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [6] = { ["CLSID"] = "DIS_C-701IR" }, [2] = { ["CLSID"] = "DIS_C-701IR" } }, ["cap"] = { [1] = { ["CLSID"] = "DIS_PL-5EII" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [6] = { ["CLSID"] = "DIS_SD-10_DUAL_R" }, [2] = { ["CLSID"] = "DIS_SD-10_DUAL_L" } }, ["sead"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_SPJ_POD" }, [5] = { ["CLSID"] = "DIS_LS_6_500" }, [3] = { ["CLSID"] = "DIS_LS_6_500" }, [2] = { ["CLSID"] = "DIS_LD-10_DUAL_L" }, [6] = { ["CLSID"] = "DIS_LD-10_DUAL_R" } }, ["strike"] = { [4] = { ["CLSID"] = "DIS_WMD7" }, [5] = { ["CLSID"] = "DIS_GBU_10" }, [3] = { ["CLSID"] = "DIS_GBU_10" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" } } } }, ["KC130"] = { ["altitude"] = 3726, ["speed"] = 174, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 30000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_WMD7" }, [3] = { ["CLSID"] = "DIS_TANK1100" }, [5] = { ["CLSID"] = "DIS_TANK1100" }, [6] = { ["CLSID"] = "DIS_GBU_12" }, [2] = { ["CLSID"] = "DIS_GBU_12" } }, ["antiship"] = { [5] = { ["CLSID"] = "DIS_C-802AK" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [3] = { ["CLSID"] = "DIS_C-802AK" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [6] = { ["CLSID"] = "DIS_C-701IR" }, [2] = { ["CLSID"] = "DIS_C-701IR" } }, ["cap"] = { [1] = { ["CLSID"] = "DIS_PL-5EII" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [6] = { ["CLSID"] = "DIS_SD-10_DUAL_R" }, [2] = { ["CLSID"] = "DIS_SD-10_DUAL_L" } }, ["sead"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_SPJ_POD" }, [5] = { ["CLSID"] = "DIS_LS_6_500" }, [3] = { ["CLSID"] = "DIS_LS_6_500" }, [2] = { ["CLSID"] = "DIS_LD-10_DUAL_L" }, [6] = { ["CLSID"] = "DIS_LD-10_DUAL_R" } }, ["strike"] = { [4] = { ["CLSID"] = "DIS_WMD7" }, [5] = { ["CLSID"] = "DIS_GBU_10" }, [3] = { ["CLSID"] = "DIS_GBU_10" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" } } } }, ["KC135MPRS"] = { ["altitude"] = 4800, ["speed"] = 220, ["payload"] = { ["chaff"] = 120, ["flare"] = 60, ["fuel"] = 90700, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_WMD7" }, [3] = { ["CLSID"] = "DIS_TANK1100" }, [5] = { ["CLSID"] = "DIS_TANK1100" }, [6] = { ["CLSID"] = "DIS_GBU_12" }, [2] = { ["CLSID"] = "DIS_GBU_12" } }, ["antiship"] = { [5] = { ["CLSID"] = "DIS_C-802AK" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [3] = { ["CLSID"] = "DIS_C-802AK" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [6] = { ["CLSID"] = "DIS_C-701IR" }, [2] = { ["CLSID"] = "DIS_C-701IR" } }, ["cap"] = { [1] = { ["CLSID"] = "DIS_PL-5EII" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [6] = { ["CLSID"] = "DIS_SD-10_DUAL_R" }, [2] = { ["CLSID"] = "DIS_SD-10_DUAL_L" } }, ["sead"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_SPJ_POD" }, [5] = { ["CLSID"] = "DIS_LS_6_500" }, [3] = { ["CLSID"] = "DIS_LS_6_500" }, [2] = { ["CLSID"] = "DIS_LD-10_DUAL_L" }, [6] = { ["CLSID"] = "DIS_LD-10_DUAL_R" } }, ["strike"] = { [4] = { ["CLSID"] = "DIS_WMD7" }, [5] = { ["CLSID"] = "DIS_GBU_10" }, [3] = { ["CLSID"] = "DIS_GBU_10" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" } } } }, ["KJ-2000"] = { ["altitude"] = 11000, ["speed"] = 220, ["payload"] = { ["fuel"] = 70000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_WMD7" }, [3] = { ["CLSID"] = "DIS_TANK1100" }, [5] = { ["CLSID"] = "DIS_TANK1100" }, [6] = { ["CLSID"] = "DIS_GBU_12" }, [2] = { ["CLSID"] = "DIS_GBU_12" } }, ["antiship"] = { [5] = { ["CLSID"] = "DIS_C-802AK" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [3] = { ["CLSID"] = "DIS_C-802AK" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [6] = { ["CLSID"] = "DIS_C-701IR" }, [2] = { ["CLSID"] = "DIS_C-701IR" } }, ["cap"] = { [1] = { ["CLSID"] = "DIS_PL-5EII" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_TANK800" }, [6] = { ["CLSID"] = "DIS_SD-10_DUAL_R" }, [2] = { ["CLSID"] = "DIS_SD-10_DUAL_L" } }, ["sead"] = { [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" }, [4] = { ["CLSID"] = "DIS_SPJ_POD" }, [5] = { ["CLSID"] = "DIS_LS_6_500" }, [3] = { ["CLSID"] = "DIS_LS_6_500" }, [2] = { ["CLSID"] = "DIS_LD-10_DUAL_L" }, [6] = { ["CLSID"] = "DIS_LD-10_DUAL_R" } }, ["strike"] = { [4] = { ["CLSID"] = "DIS_WMD7" }, [5] = { ["CLSID"] = "DIS_GBU_10" }, [3] = { ["CLSID"] = "DIS_GBU_10" }, [7] = { ["CLSID"] = "DIS_PL-5EII" }, [1] = { ["CLSID"] = "DIS_PL-5EII" } } } }, ["Ka-27"] = { ["altitude"] = 1000, ["speed"] = 230, ["payload"] = { ["fuel"] = 2616, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["cap"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["sead"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } }, ["strike"] = { [4] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [3] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [2] = { ["CLSID"] = "{M261_INBOARD_DE_M151_C_M274}" }, [1] = { ["CLSID"] = "{88D18A5E-99C8-4B04-B40B-1C02F2018B6E}" }, [5] = { ["CLSID"] = "{IAFS_ComboPak_100}" }, [6] = { ["CLSID"] = "{AN_APG_78}" } } } }, ["Ka-50"] = { ["altitude"] = 1600, ["speed"] = 310, ["payload"] = { ["chaff"] = 0, ["flare"] = 128, ["fuel"] = 1450, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" } }, ["cap"] = { [1] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" } }, ["sead"] = { [1] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}" } }, ["strike"] = { [1] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } } } }, ["Ka-50_3"] = { ["altitude"] = 1600, ["speed"] = 310, ["payload"] = { ["chaff"] = 0, ["flare"] = 128, ["fuel"] = 1450, ["gun"] = 100 }, ["properties"] = { ["modification"] = "Ka-50_3", ["Helmet-mounted device"] = 0, ["ExhaustScreen"] = true, ["Realistic INS"] = 1, ["IMU alignment type"] = 3 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [6] = { ["CLSID"] = "{9S846_2xIGLA}" }, [4] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [5] = { ["CLSID"] = "{9S846_2xIGLA}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" } }, ["antiship"] = { [6] = { ["CLSID"] = "{9S846_2xIGLA}" }, [4] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [5] = { ["CLSID"] = "{9S846_2xIGLA}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" } }, ["cap"] = { [6] = { ["CLSID"] = "{9S846_2xIGLA}" }, [4] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [5] = { ["CLSID"] = "{9S846_2xIGLA}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" } }, ["sead"] = { [6] = { ["CLSID"] = "{9S846_2xIGLA}" }, [4] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [5] = { ["CLSID"] = "{9S846_2xIGLA}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" } }, ["strike"] = { [6] = { ["CLSID"] = "{9S846_2xIGLA}" }, [4] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [5] = { ["CLSID"] = "{9S846_2xIGLA}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" } } } }, ["L-39C"] = { ["altitude"] = 4400, ["speed"] = 125, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 980, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1, ["NS430allow"] = true, ["DismountIFRHood"] = false, ["DismountGunSight"] = false }, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [3] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [1] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } }, ["antiship"] = { [3] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [1] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } }, ["cap"] = { [3] = { ["CLSID"] = "{R-3S}" }, [1] = { ["CLSID"] = "{R-3S}" } }, ["sead"] = { [3] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [1] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } }, ["strike"] = { [3] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [1] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } } } }, ["L-39ZA"] = { ["altitude"] = 4400, ["speed"] = 125, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 980, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1, ["NS430allow"] = true, ["DismountIFRHood"] = false }, ["options"] = {}, ["radio"] = { ["frequency"] = 305, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [5] = { ["CLSID"] = "{FAB-100x2}" }, [1] = { ["CLSID"] = "{FAB-100x2}" }, [4] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [2] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } }, ["antiship"] = { [5] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [1] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [4] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [2] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } }, ["cap"] = { [5] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [4] = { ["CLSID"] = "{PK-3}" }, [2] = { ["CLSID"] = "{PK-3}" } }, ["sead"] = { [5] = { ["CLSID"] = "{FAB-100x2}" }, [1] = { ["CLSID"] = "{FAB-100x2}" }, [4] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [2] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } }, ["strike"] = { [5] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [1] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [4] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" }, [2] = { ["CLSID"] = "{FB3CE165-BF07-4979-887C-92B87F13276B}" } } } }, ["M-2000C"] = { ["altitude"] = 7010, ["speed"] = 250, ["payload"] = { ["chaff"] = 234, ["flare"] = 64, ["fuel"] = 3165, ["gun"] = 100 }, ["properties"] = { ["WpBullseye"] = 0, ["ForceINSRules"] = false, ["ReadyALCM"] = true, ["ReadyQRA"] = false, ["LoadNVGCase"] = false, ["InitHotDrift"] = 0, ["EnableTAF"] = true }, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [9] = { ["CLSID"] = "{MMagicII}" }, [8] = { ["CLSID"] = "{M2KC_08_RPL541}" }, [5] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{M2KC_02_RPL541}" }, [1] = { ["CLSID"] = "{MMagicII}" } }, ["antiship"] = { [9] = { ["CLSID"] = "{MMagicII}" }, [8] = { ["CLSID"] = "{M2KC_08_RPL541}" }, [5] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [2] = { ["CLSID"] = "{M2KC_02_RPL541}" }, [1] = { ["CLSID"] = "{MMagicII}" } }, ["cap"] = { [9] = { ["CLSID"] = "{MMagicII}" }, [8] = { ["CLSID"] = "{Matra_S530D}" }, [5] = { ["CLSID"] = "{M2KC_RPL_522}" }, [2] = { ["CLSID"] = "{Matra_S530D}" }, [1] = { ["CLSID"] = "{MMagicII}" }, [10] = { ["CLSID"] = "{Eclair}" } }, ["sead"] = { [9] = { ["CLSID"] = "{MMagicII}" }, [8] = { ["CLSID"] = "{M2KC_08_RPL541}" }, [5] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{M2KC_02_RPL541}" }, [1] = { ["CLSID"] = "{MMagicII}" } }, ["strike"] = { [9] = { ["CLSID"] = "{MMagicII}" }, [8] = { ["CLSID"] = "{M2KC_08_RPL541}" }, [5] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [2] = { ["CLSID"] = "{M2KC_02_RPL541}" }, [1] = { ["CLSID"] = "{MMagicII}" } } } }, ["MB-339A"] = { ["altitude"] = 4400, ["speed"] = 125, ["payload"] = { ["fuel"] = 626, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["MountBlindHood"] = false, ["SAAB_RGS-2_Gunsight"] = true, ["Teledyne_TCS_116-2"] = false, ["SAAB_RGS-2_Gunsight_Repeater"] = false, ["DEFA_553_Burst"] = 0.5, ["EnableCutOff"] = false, ["RocketRippleTiming"] = 62, ["BombsRippleTiming"] = 300, ["NetCrewControlPriority"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [10] = { ["CLSID"] = "{FUEL-TIP-TANK-500-R}" }, [1] = { ["CLSID"] = "{FUEL-TIP-TANK-500-L}" }, [9] = { ["CLSID"] = "{LR25_ARF8M3_API}" }, [2] = { ["CLSID"] = "{LR25_ARF8M3_API}" }, [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [4] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{FUEL-TIP-ELLITTIC-R}" }, [1] = { ["CLSID"] = "{FUEL-TIP-ELLITTIC-L}" }, [8] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }, [3] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }, [7] = { ["CLSID"] = "{MB339_DEFA553_R}" }, [4] = { ["CLSID"] = "{MB339_DEFA553_L}" } }, ["cap"] = { [10] = { ["CLSID"] = "{FUEL-TIP-TANK-500-R}" }, [1] = { ["CLSID"] = "{FUEL-TIP-TANK-500-L}" }, [9] = { ["CLSID"] = "{LR25_ARF8M3_API}" }, [2] = { ["CLSID"] = "{LR25_ARF8M3_API}" }, [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [4] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["sead"] = { [10] = { ["CLSID"] = "{FUEL-TIP-TANK-500-R}" }, [1] = { ["CLSID"] = "{FUEL-TIP-TANK-500-L}" }, [9] = { ["CLSID"] = "{LR25_ARF8M3_API}" }, [2] = { ["CLSID"] = "{LR25_ARF8M3_API}" }, [8] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [3] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [7] = { ["CLSID"] = "{Mk82SNAKEYE}" }, [4] = { ["CLSID"] = "{Mk82SNAKEYE}" } }, ["strike"] = { [10] = { ["CLSID"] = "{FUEL-TIP-ELLITTIC-R}" }, [1] = { ["CLSID"] = "{FUEL-TIP-ELLITTIC-L}" }, [8] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }, [3] = { ["CLSID"] = "{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}" }, [7] = { ["CLSID"] = "{MB339_DEFA553_R}" }, [4] = { ["CLSID"] = "{MB339_DEFA553_L}" } } } }, ["MB-339APAN"] = { ["altitude"] = 4400, ["speed"] = 125, ["payload"] = { ["fuel"] = 626, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["UnlimitedSmoke"] = false, ["NetCrewControlPriority"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = {} }, ["MQ-9 Reaper"] = { ["altitude"] = 6000, ["speed"] = 80, ["payload"] = { ["fuel"] = 1300, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [1] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{GBU-38}" }, [3] = { ["CLSID"] = "{GBU-38}" }, [2] = { ["CLSID"] = "{GBU-38}" }, [1] = { ["CLSID"] = "{GBU-38}" } }, ["cap"] = { [4] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [1] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" } }, ["sead"] = { [4] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [3] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [2] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" }, [1] = { ["CLSID"] = "{DB769D48-67D7-42ED-A2BE-108D566C8B1E}" } }, ["strike"] = { [4] = { ["CLSID"] = "{GBU-38}" }, [3] = { ["CLSID"] = "{GBU-38}" }, [2] = { ["CLSID"] = "{GBU-38}" }, [1] = { ["CLSID"] = "{GBU-38}" } } } }, ["Mi-24P"] = { ["altitude"] = 880, ["speed"] = 270, ["payload"] = { ["chaff"] = 0, ["flare"] = 192, ["fuel"] = 1701, ["gun"] = 100 }, ["properties"] = { ["LeftEngineResource"] = 90, ["RightEngineResource"] = 90, ["ExhaustScreen"] = true, ["NS430allow"] = true, ["PilotNVG"] = true, ["OperatorNVG"] = true, ["R60equipment"] = true, ["OverrideIFF"] = 0, ["GunnersAISkill"] = 90, ["SimplifiedAI"] = false, ["HideAngleBoxes"] = false, ["TrackAirTargets"] = true, ["NetCrewControlPriority"] = 0, ["HumanOrchestra"] = false }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{UB-32A-24}" }, [3] = { ["CLSID"] = "{UB-32A-24}" }, [2] = { ["CLSID"] = "{UB-32A-24}" }, [5] = { ["CLSID"] = "{UB-32A-24}" }, [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{APU_68_S-24}" }, [3] = { ["CLSID"] = "{APU_68_S-24}" }, [4] = { ["CLSID"] = "{APU_68_S-24}" }, [5] = { ["CLSID"] = "{APU_68_S-24}" } }, ["cap"] = { [4] = { ["CLSID"] = "{UB-32A-24}" }, [3] = { ["CLSID"] = "{UB-32A-24}" }, [2] = { ["CLSID"] = "{UB-32A-24}" }, [5] = { ["CLSID"] = "{UB-32A-24}" }, [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["sead"] = { [4] = { ["CLSID"] = "{UB-32A-24}" }, [3] = { ["CLSID"] = "{UB-32A-24}" }, [2] = { ["CLSID"] = "{UB-32A-24}" }, [5] = { ["CLSID"] = "{UB-32A-24}" }, [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["strike"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{APU_68_S-24}" }, [3] = { ["CLSID"] = "{APU_68_S-24}" }, [4] = { ["CLSID"] = "{APU_68_S-24}" }, [5] = { ["CLSID"] = "{APU_68_S-24}" } } } }, ["Mi-24V"] = { ["altitude"] = 880, ["speed"] = 270, ["payload"] = { ["chaff"] = 0, ["flare"] = 192, ["fuel"] = 1704, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["cap"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["sead"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["strike"] = { [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } } } }, ["Mi-26"] = { ["altitude"] = 400, ["speed"] = 255, ["payload"] = { ["chaff"] = 0, ["flare"] = 192, ["fuel"] = 9600, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["cap"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["sead"] = { [1] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [2] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [5] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" }, [6] = { ["CLSID"] = "{B919B0F4-7C25-455E-9A02-CEA51DB895E3}" } }, ["strike"] = { [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } } } }, ["Mi-28N"] = { ["altitude"] = 1196, ["speed"] = 261, ["payload"] = { ["chaff"] = 0, ["flare"] = 128, ["fuel"] = 1500, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" }, [2] = { ["CLSID"] = "{96A7F676-F956-404A-AD04-F33FB2C74884}" }, [3] = { ["CLSID"] = "{96A7F676-F956-404A-AD04-F33FB2C74884}" }, [4] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [3] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [4] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" } }, ["cap"] = { [1] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" }, [2] = { ["CLSID"] = "{96A7F676-F956-404A-AD04-F33FB2C74884}" }, [3] = { ["CLSID"] = "{96A7F676-F956-404A-AD04-F33FB2C74884}" }, [4] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" } }, ["sead"] = { [1] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" }, [2] = { ["CLSID"] = "{96A7F676-F956-404A-AD04-F33FB2C74884}" }, [3] = { ["CLSID"] = "{96A7F676-F956-404A-AD04-F33FB2C74884}" }, [4] = { ["CLSID"] = "{57232979-8B0F-4db7-8D9A-55197E06B0F5}" } }, ["strike"] = { [1] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } } } }, ["Mi-8MT"] = { ["altitude"] = 740, ["speed"] = 225, ["payload"] = { ["chaff"] = 0, ["flare"] = 128, ["fuel"] = 1929, ["gun"] = 100 }, ["properties"] = { ["ExhaustScreen"] = true, ["LeftEngineResource"] = 90, ["RightEngineResource"] = 90, ["AdditionalArmor"] = true, ["CargoHalfdoor"] = true, ["GunnersAISkill"] = 90, ["NetCrewControlPriority"] = 0, ["HumanOrchestra"] = false, ["NS430allow"] = true }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [6] = { ["CLSID"] = "GUV_VOG" }, [1] = { ["CLSID"] = "GUV_VOG" }, [5] = { ["CLSID"] = "GUV_YakB_GSHP" }, [2] = { ["CLSID"] = "GUV_YakB_GSHP" }, [4] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" }, [3] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" } }, ["antiship"] = { [6] = { ["CLSID"] = "GUV_VOG" }, [1] = { ["CLSID"] = "GUV_VOG" }, [5] = { ["CLSID"] = "GUV_YakB_GSHP" }, [2] = { ["CLSID"] = "GUV_YakB_GSHP" }, [4] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" }, [3] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" } }, ["cap"] = { [6] = { ["CLSID"] = "GUV_VOG" }, [1] = { ["CLSID"] = "GUV_VOG" }, [5] = { ["CLSID"] = "GUV_YakB_GSHP" }, [2] = { ["CLSID"] = "GUV_YakB_GSHP" }, [4] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" }, [3] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" } }, ["sead"] = { [6] = { ["CLSID"] = "GUV_VOG" }, [1] = { ["CLSID"] = "GUV_VOG" }, [5] = { ["CLSID"] = "GUV_YakB_GSHP" }, [2] = { ["CLSID"] = "GUV_YakB_GSHP" }, [4] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" }, [3] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" } }, ["strike"] = { [6] = { ["CLSID"] = "GUV_VOG" }, [1] = { ["CLSID"] = "GUV_VOG" }, [5] = { ["CLSID"] = "GUV_YakB_GSHP" }, [2] = { ["CLSID"] = "GUV_YakB_GSHP" }, [4] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" }, [3] = { ["CLSID"] = "{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}" } } } }, ["MiG-15bis"] = { ["altitude"] = 6040, ["speed"] = 236.11111111111111, ["payload"] = { ["fuel"] = 1172, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 3.75, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "FAB_100M" }, [2] = { ["CLSID"] = "FAB_100M" } }, ["antiship"] = { [1] = { ["CLSID"] = "FAB_100M" }, [2] = { ["CLSID"] = "FAB_100M" } }, ["cap"] = { [1] = { ["CLSID"] = "PTB300_MIG15" }, [2] = { ["CLSID"] = "PTB300_MIG15" } }, ["sead"] = { [1] = { ["CLSID"] = "FAB_100M" }, [2] = { ["CLSID"] = "FAB_100M" } }, ["strike"] = { [1] = { ["CLSID"] = "FAB_100M" }, [2] = { ["CLSID"] = "FAB_100M" } } } }, ["MiG-15bis_FC"] = { ["altitude"] = 6040, ["speed"] = 236.11111111111111, ["payload"] = { ["fuel"] = 1172, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 3.75, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "FAB_50" }, [2] = { ["CLSID"] = "FAB_50" } }, ["antiship"] = { [1] = { ["CLSID"] = "FAB_50" }, [2] = { ["CLSID"] = "FAB_50" } }, ["cap"] = { [1] = { ["CLSID"] = "PTB300_MIG15" }, [2] = { ["CLSID"] = "PTB300_MIG15" } }, ["sead"] = { [1] = { ["CLSID"] = "FAB_50" }, [2] = { ["CLSID"] = "FAB_50" } }, ["strike"] = { [1] = { ["CLSID"] = "FAB_50" }, [2] = { ["CLSID"] = "FAB_50" } } } }, ["MiG-19P"] = { ["altitude"] = 7000, ["speed"] = 236.11111111111111, ["payload"] = { ["fuel"] = 1800, ["gun"] = 100 }, ["properties"] = { ["MountSIRENA"] = false, ["MissileToneVolume"] = 5, ["NAV_Initial_Hdg"] = 0, ["ADF_FAR_Frequency"] = 625, ["ADF_NEAR_Frequency"] = 303, ["ADF_Selected_Frequency"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" }, [3] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" } }, ["antiship"] = { [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" }, [3] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" } }, ["cap"] = { [6] = { ["CLSID"] = "{K-13A}" }, [1] = { ["CLSID"] = "{K-13A}" }, [5] = { ["CLSID"] = "PTB760_MIG19" }, [2] = { ["CLSID"] = "PTB760_MIG19" } }, ["sead"] = { [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" }, [3] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" } }, ["strike"] = { [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" }, [3] = { ["CLSID"] = "{ORO57K_S5M_HEFRAG}" } } } }, ["MiG-21Bis"] = { ["altitude"] = 8000, ["speed"] = 223, ["payload"] = { ["chaff"] = 18, ["flare"] = 40, ["fuel"] = 2280, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [6] = { ["CLSID"] = "{ASO-2}" }, [3] = { ["CLSID"] = "{PTB_800_MIG21}" }, [2] = { ["CLSID"] = "{UB-32_S5M}" }, [4] = { ["CLSID"] = "{UB-32_S5M}" }, [1] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } }, ["antiship"] = { [6] = { ["CLSID"] = "{ASO-2}" }, [3] = { ["CLSID"] = "{PTB_800_MIG21}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [1] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } }, ["cap"] = { [3] = { ["CLSID"] = "{PTB_800_MIG21}" }, [2] = { ["CLSID"] = "{R-3R}" }, [4] = { ["CLSID"] = "{R-3R}" }, [1] = { ["CLSID"] = "{R-60 2L}" }, [5] = { ["CLSID"] = "{R-60 2R}" }, [6] = { ["CLSID"] = "{ASO-2}" } }, ["sead"] = { [6] = { ["CLSID"] = "{ASO-2}" }, [3] = { ["CLSID"] = "{PTB_800_MIG21}" }, [2] = { ["CLSID"] = "{UB-32_S5M}" }, [4] = { ["CLSID"] = "{UB-32_S5M}" }, [1] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } }, ["strike"] = { [6] = { ["CLSID"] = "{ASO-2}" }, [3] = { ["CLSID"] = "{PTB_800_MIG21}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [1] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } } } }, ["MiG-23MLD"] = { ["altitude"] = 7400, ["speed"] = 210, ["payload"] = { ["chaff"] = 60, ["flare"] = 60, ["fuel"] = 3800, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [4] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [5] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } }, ["antiship"] = { [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [4] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [5] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } }, ["cap"] = { [2] = { ["CLSID"] = "{CCF898C9-5BC7-49A4-9D1E-C3ED3D5166A1}" }, [3] = { ["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}" }, [4] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [5] = { ["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}" }, [6] = { ["CLSID"] = "{CCF898C9-5BC7-49A4-9D1E-C3ED3D5166A1}" } }, ["sead"] = { [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [4] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [5] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" } }, ["strike"] = { [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [4] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [5] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" } } } }, ["MiG-25PD"] = { ["altitude"] = 9680, ["speed"] = 280, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 15245, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [3] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [4] = { ["CLSID"] = "{APU-60-1_R_60M}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [3] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [4] = { ["CLSID"] = "{APU-60-1_R_60M}" } }, ["cap"] = { [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [3] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [4] = { ["CLSID"] = "{APU-60-1_R_60M}" } }, ["sead"] = { [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [3] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [4] = { ["CLSID"] = "{APU-60-1_R_60M}" } }, ["strike"] = { [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [3] = { ["CLSID"] = "{4EDBA993-2E34-444C-95FB-549300BF7CAF}" }, [4] = { ["CLSID"] = "{APU-60-1_R_60M}" } } } }, ["MiG-25RBT"] = { ["altitude"] = 9680, ["speed"] = 280, ["payload"] = { ["fuel"] = 15245, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{R-60 2L}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{R-60 2R}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{R-60 2L}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{R-60 2R}" } }, ["cap"] = { [1] = { ["CLSID"] = "{R-60 2L}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{R-60 2R}" } }, ["sead"] = { [1] = { ["CLSID"] = "{R-60 2L}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{R-60 2R}" } }, ["strike"] = { [1] = { ["CLSID"] = "{R-60 2L}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{R-60 2R}" } } } }, ["MiG-27K"] = { ["altitude"] = 6800, ["speed"] = 210, ["payload"] = { ["chaff"] = 60, ["flare"] = 60, ["fuel"] = 4500, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [8] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" } }, ["antiship"] = { [8] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [5] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" } }, ["cap"] = { [2] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [8] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" } }, ["sead"] = { [2] = { ["CLSID"] = "{752AF1D2-EBCC-4bd7-A1E7-2357F5601C70}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [5] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [8] = { ["CLSID"] = "{752AF1D2-EBCC-4bd7-A1E7-2357F5601C70}" } }, ["strike"] = { [2] = { ["CLSID"] = "{BA565F89-2373-4A84-9502-A0E017D3A44A}" }, [3] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [5] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [8] = { ["CLSID"] = "{BA565F89-2373-4A84-9502-A0E017D3A44A}" } } } }, ["MiG-29A"] = { ["altitude"] = 7200, ["speed"] = 222, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 3376, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [2] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["sead"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["strike"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } } } }, ["MiG-29G"] = { ["altitude"] = 7200, ["speed"] = 222, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 3376, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["sead"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["strike"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } } } }, ["MiG-29S"] = { ["altitude"] = 7200, ["speed"] = 222, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 3493, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [6] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [2] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["sead"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["strike"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [7] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } } } }, ["MiG-31"] = { ["altitude"] = 8400, ["speed"] = 280, ["payload"] = { ["fuel"] = 15500, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}" }, [2] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [3] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [4] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [5] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [6] = { ["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}" }, [2] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [3] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [4] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [5] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [6] = { ["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}" } }, ["cap"] = { [1] = { ["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}" }, [2] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [3] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [4] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [5] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [6] = { ["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}" } }, ["sead"] = { [1] = { ["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}" }, [2] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [3] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [4] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [5] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [6] = { ["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}" } }, ["strike"] = { [1] = { ["CLSID"] = "{B0DBC591-0F52-4F7D-AD7B-51E67725FB81}" }, [2] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [3] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [4] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [5] = { ["CLSID"] = "{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}" }, [6] = { ["CLSID"] = "{275A2855-4A79-4B2D-B082-91EA2ADF4691}" } } } }, ["Mirage 2000-5"] = { ["altitude"] = 6584, ["speed"] = 170, ["payload"] = { ["chaff"] = 112, ["flare"] = 16, ["fuel"] = 3160, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["sead"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["strike"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } } } }, ["Mirage-F1AD"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["sead"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["strike"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } } } }, ["Mirage-F1AZ"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["sead"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } }, ["strike"] = { [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [3] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [4] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [5] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [6] = { ["CLSID"] = "{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}" }, [7] = { ["CLSID"] = "{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}" }, [8] = { ["CLSID"] = "{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}" }, [9] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" } } } }, ["Mirage-F1B"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3045, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1, ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1BD"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3045, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1, ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1BE"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3045, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1, ["IFFMode4Disabled"] = 1, ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1BQ"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3045, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1, ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1C"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250LD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250LD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1C-200"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250LD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250LD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CE"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1, ["IFFMode4Disabled"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CG"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "CLB4-PYLON-SAMP250HD" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "CLB4-PYLON-SAMP250HD" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CH"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CJ"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CK"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CR"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [3] = { ["CLSID"] = "PTB-1200-F1" }, [5] = { ["CLSID"] = "PTB-1200-F1" }, [4] = { ["CLSID"] = "{CLB4_SAMP400HD}" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CT"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1CZ"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_IR}" }, [3] = { ["CLSID"] = "{R530F_IR}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1DDA"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3045, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1, ["SoloFlight"] = false, ["NetCrewControlPriority"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1ED"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [1] = { ["CLSID"] = "{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1EDA"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1EE"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3246, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1, ["IFFMode4Disabled"] = 1, ["INSStartMode"] = 1, ["RWR_type"] = "ALR_300" }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1EH"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{R530F_EM}" }, [3] = { ["CLSID"] = "{R530F_EM}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1EQ"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 0, ["flare"] = 0, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{MATRA_F1_SNEBT256}" }, [5] = { ["CLSID"] = "{MATRA_F1_SNEBT256}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{MATRA_F1_SNEBT256}" }, [5] = { ["CLSID"] = "{MATRA_F1_SNEBT256}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1JA"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "DIS_PL-8B" }, [6] = { ["CLSID"] = "DIS_PL-8B" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1M-CE"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3356, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["Mirage-F1M-EE"] = { ["altitude"] = 6096, ["speed"] = 300, ["payload"] = { ["chaff"] = 30, ["flare"] = 15, ["fuel"] = 3246, ["gun"] = 100 }, ["properties"] = { ["RadarCoverSettings"] = 1, ["MissSimplLock"] = 1, ["ChaffMultiNumber"] = 1, ["ChaffMultiTime"] = 1, ["ChaffProgramNumber"] = 1, ["ChaffProgramTime"] = 1, ["FlareMultiNumber"] = 1, ["FlareMultiTime"] = 1, ["GunBurstSettings"] = 1, ["RocketBurstF1"] = 1, ["RocketBurstF4"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["antiship"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } }, ["cap"] = { [7] = { ["CLSID"] = "{R550_Magic_1}" }, [1] = { ["CLSID"] = "{R550_Magic_1}" }, [5] = { ["CLSID"] = "{S530F}" }, [3] = { ["CLSID"] = "{S530F}" }, [4] = { ["CLSID"] = "PTB-1200-F1" } }, ["sead"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP250HD}" }, [6] = { ["CLSID"] = "{SAMP250HD}" }, [3] = { ["CLSID"] = "{SAMP250HD}" }, [5] = { ["CLSID"] = "{SAMP250HD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP250HD}" } }, ["strike"] = { [7] = { ["CLSID"] = "{AIM-9JULI}" }, [1] = { ["CLSID"] = "{AIM-9JULI}" }, [2] = { ["CLSID"] = "{SAMP400LD}" }, [6] = { ["CLSID"] = "{SAMP400LD}" }, [3] = { ["CLSID"] = "{SAMP400LD}" }, [5] = { ["CLSID"] = "{SAMP400LD}" }, [4] = { ["CLSID"] = "{CLB4_SAMP400LD}" } } } }, ["MosquitoFBMkVI"] = { ["altitude"] = 4600, ["speed"] = 115, ["payload"] = { ["fuel"] = 1483.1, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["Flare_Gun"] = 1, ["ResinLights"] = 0.15 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "{British_SAP_500LB_Bomb_Mk5}" }, [1] = { ["CLSID"] = "{British_SAP_500LB_Bomb_Mk5}" }, [4] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" }, [3] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" } }, ["antiship"] = { [1] = { ["CLSID"] = "" }, [2] = { ["CLSID"] = "" }, [3] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" }, [4] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" }, [5] = { ["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}" }, [6] = { ["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}" } }, ["cap"] = { [1] = { ["CLSID"] = "" }, [2] = { ["CLSID"] = "" }, [3] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" }, [4] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" }, [5] = { ["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}" }, [6] = { ["CLSID"] = "{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}" } }, ["sead"] = { [2] = { ["CLSID"] = "{British_SAP_500LB_Bomb_Mk5}" }, [1] = { ["CLSID"] = "{British_SAP_500LB_Bomb_Mk5}" }, [4] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" }, [3] = { ["CLSID"] = "{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}" } }, ["strike"] = { [2] = { ["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short}" }, [1] = { ["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short}" }, [4] = { ["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}" }, [3] = { ["CLSID"] = "{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}" } } } }, ["OH-58D"] = { ["altitude"] = 2400, ["speed"] = 195, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 454, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "AGM114x2_OH_58" }, [2] = { ["CLSID"] = "M260_HYDRA" } }, ["antiship"] = { [1] = { ["CLSID"] = "AGM114x2_OH_58" }, [2] = { ["CLSID"] = "M260_HYDRA" } }, ["cap"] = { [1] = { ["CLSID"] = "AGM114x2_OH_58" }, [2] = { ["CLSID"] = "M260_HYDRA" } }, ["sead"] = { [1] = { ["CLSID"] = "AGM114x2_OH_58" }, [2] = { ["CLSID"] = "M260_HYDRA" } }, ["strike"] = { [1] = { ["CLSID"] = "AGM114x2_OH_58" }, [2] = { ["CLSID"] = "M260_HYDRA" } } } }, ["OH58D"] = { ["altitude"] = 1706, ["speed"] = 200, ["payload"] = { ["chaff"] = 0, ["flare"] = 30, ["fuel"] = 333.69, ["gun"] = 100 }, ["properties"] = { ["NetCrewControlPriority"] = 0, ["Remove doors"] = true, ["PDU"] = false, ["AllowHidePDU"] = true, ["Rifles"] = true, ["MMS removal"] = false, ["Rapid Deployment Gear"] = false, ["ALQ144"] = false, ["importDrawings"] = true, ["tacNet"] = 1 }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 116, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{M260_APKWS_M151}" }, [5] = { ["CLSID"] = "OH58D_AGM_114_R" } }, ["antiship"] = { [1] = { ["CLSID"] = "OH58D_AGM_114_L" }, [5] = { ["CLSID"] = "OH58D_AGM_114_R" } }, ["cap"] = { [1] = { ["CLSID"] = "OH58D_FIM_92_L" }, [5] = { ["CLSID"] = "OH58D_FIM_92_R" } }, ["sead"] = { [1] = { ["CLSID"] = "{M260_APKWS_M151}" }, [5] = { ["CLSID"] = "OH58D_AGM_114_R" } }, ["strike"] = { [1] = { ["CLSID"] = "OH58D_AGM_114_L" }, [5] = { ["CLSID"] = "OH58D_AGM_114_R" } } } }, ["P-47D-30"] = { ["altitude"] = 5400, ["speed"] = 125, ["payload"] = { ["fuel"] = 1007, ["gun"] = 100 }, ["properties"] = { ["WaterTankContents"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{AN_M57}" } }, ["antiship"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{AN_M57}" } }, ["cap"] = { [2] = { ["CLSID"] = "{US_150GAL_FUEL_TANK}" }, [3] = { ["CLSID"] = "{US_150GAL_FUEL_TANK}" } }, ["sead"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{AN_M57}" } }, ["strike"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{AN_M57}" } } } }, ["P-47D-30bl1"] = { ["altitude"] = 5400, ["speed"] = 125, ["payload"] = { ["fuel"] = 1007, ["gun"] = 100 }, ["properties"] = { ["WaterTankContents"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" } }, ["antiship"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" } }, ["cap"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" } }, ["sead"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" } }, ["strike"] = { [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" } } } }, ["P-47D-40"] = { ["altitude"] = 5400, ["speed"] = 125, ["payload"] = { ["fuel"] = 1007, ["gun"] = 100 }, ["properties"] = { ["WaterTankContents"] = 1 }, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [4] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [5] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{US_110GAL_FUEL_TANK}" } }, ["antiship"] = { [4] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [5] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{US_110GAL_FUEL_TANK}" } }, ["cap"] = { [2] = { ["CLSID"] = "{US_150GAL_FUEL_TANK}" }, [3] = { ["CLSID"] = "{US_150GAL_FUEL_TANK}" } }, ["sead"] = { [4] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [5] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{US_110GAL_FUEL_TANK}" } }, ["strike"] = { [4] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [5] = { ["CLSID"] = "{3xM8_ROCKETS_IN_TUBES}" }, [2] = { ["CLSID"] = "{AN_M57}" }, [3] = { ["CLSID"] = "{AN_M57}" }, [1] = { ["CLSID"] = "{US_110GAL_FUEL_TANK}" } } } }, ["P-51D"] = { ["altitude"] = 5200, ["speed"] = 125, ["payload"] = { ["fuel"] = 732, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } }, ["cap"] = { [7] = { ["CLSID"] = "{DT75GAL}" }, [4] = { ["CLSID"] = "{DT75GAL}" } }, ["sead"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } }, ["strike"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } } } }, ["P-51D-30-NA"] = { ["altitude"] = 5200, ["speed"] = 125, ["payload"] = { ["fuel"] = 732, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } }, ["cap"] = { [7] = { ["CLSID"] = "{DT75GAL}" }, [4] = { ["CLSID"] = "{DT75GAL}" } }, ["sead"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } }, ["strike"] = { [10] = { ["CLSID"] = "{HVAR}" }, [9] = { ["CLSID"] = "{HVAR}" }, [8] = { ["CLSID"] = "{HVAR}" }, [7] = { ["CLSID"] = "{AN-M64}" }, [4] = { ["CLSID"] = "{AN-M64}" }, [3] = { ["CLSID"] = "{HVAR}" }, [2] = { ["CLSID"] = "{HVAR}" }, [1] = { ["CLSID"] = "{HVAR}" } } } }, ["RQ-1A Predator"] = { ["altitude"] = 3048, ["speed"] = 33.333333333333, ["payload"] = { ["fuel"] = 490, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" }, [1] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" } }, ["antiship"] = { [2] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" }, [1] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" } }, ["cap"] = { [2] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" }, [1] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" } }, ["sead"] = { [2] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" }, [1] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" } }, ["strike"] = { [2] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" }, [1] = { ["CLSID"] = "{ee368869-c35a-486a-afe7-284beb7c5d52}" } } } }, ["S-3B"] = { ["altitude"] = 4880, ["speed"] = 82.2, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 5962, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["antiship"] = { [6] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [1] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" } }, ["cap"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["sead"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["strike"] = { [6] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" }, [1] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" } } } }, ["S-3B Tanker"] = { ["altitude"] = 4880, ["speed"] = 82.2, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 6887, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["antiship"] = { [6] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [1] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" } }, ["cap"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["sead"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["strike"] = { [6] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" }, [1] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" } } } }, ["SA342L"] = { ["altitude"] = 1216, ["speed"] = 200, ["payload"] = { ["chaff"] = 0, ["flare"] = 32, ["fuel"] = 416.33, ["gun"] = 100 }, ["properties"] = { ["NS430allow"] = true, ["SA342RemoveDoors"] = false, ["RemoveTablet"] = false }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{GIAT_M621_APHE}" }, [2] = { ["CLSID"] = "{TELSON8_SNEBT251}" }, [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{GIAT_M621_APHE}" }, [2] = { ["CLSID"] = "{TELSON8_SNEBT251}" }, [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["cap"] = { [1] = { ["CLSID"] = "{SA342_Mistral_R2}" }, [2] = { ["CLSID"] = "{SA342_Mistral_L2}" }, [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["sead"] = { [1] = { ["CLSID"] = "{GIAT_M621_APHE}" }, [2] = { ["CLSID"] = "{TELSON8_SNEBT251}" }, [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["strike"] = { [1] = { ["CLSID"] = "{GIAT_M621_APHE}" }, [2] = { ["CLSID"] = "{TELSON8_SNEBT251}" }, [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } } } }, ["SA342M"] = { ["altitude"] = 1216, ["speed"] = 200, ["payload"] = { ["chaff"] = 0, ["flare"] = 32, ["fuel"] = 416.33, ["gun"] = 100 }, ["properties"] = { ["NS430allow"] = true, ["RemoveTablet"] = false }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{HOT3_R2_M}" }, [2] = { ["CLSID"] = "{HOT3_L2_M}" }, [3] = { ["CLSID"] = "FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{HOT3_R2_M}" }, [2] = { ["CLSID"] = "{HOT3_L2_M}" }, [3] = { ["CLSID"] = "FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["cap"] = { [1] = { ["CLSID"] = "{HOT3_R2_M}" }, [2] = { ["CLSID"] = "{HOT3_L2_M}" }, [3] = { ["CLSID"] = "FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["sead"] = { [1] = { ["CLSID"] = "{HOT3_R2_M}" }, [2] = { ["CLSID"] = "{HOT3_L2_M}" }, [3] = { ["CLSID"] = "FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["strike"] = { [1] = { ["CLSID"] = "{HOT3_R2_M}" }, [2] = { ["CLSID"] = "{HOT3_L2_M}" }, [3] = { ["CLSID"] = "FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } } } }, ["SA342Minigun"] = { ["altitude"] = 1216, ["speed"] = 200, ["payload"] = { ["chaff"] = 0, ["flare"] = 32, ["fuel"] = 416.33, ["gun"] = 100 }, ["properties"] = { ["NS430allow"] = true, ["RemoveTablet"] = false }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["antiship"] = { [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["cap"] = { [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["sead"] = { [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } }, ["strike"] = { [3] = { ["CLSID"] = "{FAS}" }, [4] = { ["CLSID"] = "{IR_Deflector}" } } } }, ["SA342Mistral"] = { ["altitude"] = 1216, ["speed"] = 200, ["payload"] = { ["chaff"] = 0, ["flare"] = 32, ["fuel"] = 416.33, ["gun"] = 100 }, ["properties"] = { ["NS430allow"] = true, ["RemoveTablet"] = false }, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = {} }, ["SH-3W"] = { ["altitude"] = 1000, ["speed"] = 222, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 2132, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = {} }, ["SH-60B"] = { ["altitude"] = 1804, ["speed"] = 250, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 1100, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" } }, ["cap"] = { [1] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" } }, ["sead"] = { [1] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" } }, ["strike"] = { [1] = { ["CLSID"] = "{7B8DCEB4-820B-4015-9B48-1028A4195692}" } } } }, ["SpitfireLFMkIX"] = { ["altitude"] = 5200, ["speed"] = 125, ["payload"] = { ["fuel"] = 277.59853044, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["antiship"] = { [6] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [1] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" } }, ["cap"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["sead"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["strike"] = { [6] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" }, [1] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" } } } }, ["SpitfireLFMkIXCW"] = { ["altitude"] = 5200, ["speed"] = 125, ["payload"] = { ["fuel"] = 277.59853044, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["antiship"] = { [6] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [1] = { ["CLSID"] = "{8B7CADF9-4954-46B3-8CFB-93F2F5B90B03}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" } }, ["cap"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["sead"] = { [6] = { ["CLSID"] = "{444BA8AE-82A7-4345-842E-76154EFCCA46}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [4] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [3] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [2] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [1] = { ["CLSID"] = "{69DC8AE7-8F77-427B-B8AA-B19D3F478B66}" } }, ["strike"] = { [6] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" }, [1] = { ["CLSID"] = "{AF42E6DF-9A60-46D8-A9A0-1708B241AADB}" } } } }, ["Su-17M4"] = { ["altitude"] = 6080, ["speed"] = 174, ["payload"] = { ["chaff"] = 64, ["flare"] = 64, ["fuel"] = 3770, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [2] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [3] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [4] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" }, [5] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" }, [6] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [8] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" } }, ["antiship"] = { [8] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [6] = { ["CLSID"] = "{3468C652-E830-4E73-AFA9-B5F260AB7C3D}" }, [3] = { ["CLSID"] = "{3468C652-E830-4E73-AFA9-B5F260AB7C3D}" }, [2] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" } }, ["cap"] = { [1] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [2] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [3] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [4] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" }, [5] = { ["CLSID"] = "{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}" }, [6] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [8] = { ["CLSID"] = "{3858707D-F5D5-4bbb-BDD8-ABB0530EBC7C}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [2] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [3] = { ["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}" }, [4] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [5] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [6] = { ["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [8] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" } }, ["strike"] = { [2] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [3] = { ["CLSID"] = "{B4FC81C9-B861-4E87-BBDC-A1158E648EBF}" }, [4] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [5] = { ["CLSID"] = "{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}" }, [6] = { ["CLSID"] = "{B4FC81C9-B861-4E87-BBDC-A1158E648EBF}" }, [7] = { ["CLSID"] = "{APU-60-1_R_60M}" } } } }, ["Su-24M"] = { ["altitude"] = 7000, ["speed"] = 210, ["payload"] = { ["chaff"] = 96, ["flare"] = 96, ["fuel"] = 11700, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" }, [2] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" }, [8] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{4D13E282-DF46-4B23-864A-A9423DFDE504}" }, [5] = { ["CLSID"] = "{16602053-4A12-40A2-B214-AB60D481B20E}" }, [7] = { ["CLSID"] = "{4D13E282-DF46-4B23-864A-A9423DFDE504}" }, [8] = { ["CLSID"] = "{APU-60-1_R_60M}" } }, ["cap"] = { [1] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" }, [2] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" }, [8] = { ["CLSID"] = "{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}" } }, ["sead"] = { [1] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" }, [2] = { ["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}" }, [5] = { ["CLSID"] = "{0519A264-0AB6-11d6-9193-00A0249B6F00}" }, [7] = { ["CLSID"] = "{E86C5AA5-6D49-4F00-AD2E-79A62D6DDE26}" }, [8] = { ["CLSID"] = "{6DADF342-D4BA-4D8A-B081-BA928C4AF86D}" } }, ["strike"] = { [1] = { ["CLSID"] = "{APU-60-1_R_60M}" }, [2] = { ["CLSID"] = "{BA565F89-2373-4A84-9502-A0E017D3A44A}" }, [3] = { ["CLSID"] = "{BA565F89-2373-4A84-9502-A0E017D3A44A}" }, [6] = { ["CLSID"] = "{BA565F89-2373-4A84-9502-A0E017D3A44A}" }, [7] = { ["CLSID"] = "{BA565F89-2373-4A84-9502-A0E017D3A44A}" }, [8] = { ["CLSID"] = "{APU-60-1_R_60M}" } } } }, ["Su-24MR"] = { ["altitude"] = 7000, ["speed"] = 210, ["payload"] = { ["chaff"] = 96, ["flare"] = 96, ["fuel"] = 11700, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = {} }, ["Su-25"] = { ["altitude"] = 4000, ["speed"] = 180, ["payload"] = { ["chaff"] = 128, ["flare"] = 128, ["fuel"] = 2835, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [2] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [3] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [6] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [9] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [10] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [8] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [7] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [6] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" }, [5] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" }, [4] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [3] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["cap"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [2] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [3] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [6] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [9] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [10] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["sead"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [2] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [3] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [6] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [9] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [10] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["strike"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [3] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [4] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [5] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" }, [6] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" }, [7] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [8] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [10] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } } } }, ["Su-25T"] = { ["altitude"] = 4000, ["speed"] = 180, ["payload"] = { ["chaff"] = 128, ["flare"] = 128, ["fuel"] = 3790, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [2] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [11] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["antiship"] = { [11] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}" }, [9] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [8] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [7] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" }, [5] = { ["CLSID"] = "{D4A8D9B9-5C45-42e7-BBD2-0E54F8308432}" }, [4] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [3] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [2] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}" }, [10] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["cap"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [2] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{0511E528-EA28-4caf-A212-00D1408DF10A}" }, [11] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["sead"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}" }, [2] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [4] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [5] = { ["CLSID"] = "{B5CA9846-776E-4230-B4FD-8BCC9BFB1676}" }, [6] = { ["CLSID"] = "{0519A264-0AB6-11d6-9193-00A0249B6F00}" }, [7] = { ["CLSID"] = "{B5CA9846-776E-4230-B4FD-8BCC9BFB1676}" }, [8] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [9] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [10] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [11] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}" } }, ["strike"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}" }, [2] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{E8D4652F-FD48-45B7-BA5B-2AE05BB5A9CF}" }, [4] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [5] = { ["CLSID"] = "{E2C426E3-8B10-4E09-B733-9CDC26520F48}" }, [7] = { ["CLSID"] = "{E2C426E3-8B10-4E09-B733-9CDC26520F48}" }, [8] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [9] = { ["CLSID"] = "{E8D4652F-FD48-45B7-BA5B-2AE05BB5A9CF}" }, [10] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [11] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}" } } } }, ["Su-25TM"] = { ["altitude"] = 4000, ["speed"] = 180, ["payload"] = { ["chaff"] = 128, ["flare"] = 128, ["fuel"] = 3790, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [11] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}" }, [2] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{E8D4652F-FD48-45B7-BA5B-2AE05BB5A9CF}" }, [5] = { ["CLSID"] = "{2234F529-1D57-4496-8BB0-0150F9BDBBD3}" }, [6] = { ["CLSID"] = "{F4920E62-A99A-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{2234F529-1D57-4496-8BB0-0150F9BDBBD3}" }, [9] = { ["CLSID"] = "{E8D4652F-FD48-45B7-BA5B-2AE05BB5A9CF}" }, [10] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [11] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}" } }, ["cap"] = { [1] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" }, [2] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [7] = { ["CLSID"] = "{E92CBFE5-C153-11d8-9897-000476191836}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{FC56DF80-9B09-44C5-8976-DCFAFF219062}" }, [11] = { ["CLSID"] = "{682A481F-0CB5-4693-A382-D00DD4A156D7}" } }, ["sead"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}" }, [2] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{752AF1D2-EBCC-4bd7-A1E7-2357F5601C70}" }, [4] = { ["CLSID"] = "{752AF1D2-EBCC-4bd7-A1E7-2357F5601C70}" }, [5] = { ["CLSID"] = "{B5CA9846-776E-4230-B4FD-8BCC9BFB1676}" }, [6] = { ["CLSID"] = "{0519A264-0AB6-11d6-9193-00A0249B6F00}" }, [7] = { ["CLSID"] = "{B5CA9846-776E-4230-B4FD-8BCC9BFB1676}" }, [8] = { ["CLSID"] = "{752AF1D2-EBCC-4bd7-A1E7-2357F5601C70}" }, [9] = { ["CLSID"] = "{752AF1D2-EBCC-4bd7-A1E7-2357F5601C70}" }, [10] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [11] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}" } }, ["strike"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82D}" }, [2] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{E8D4652F-FD48-45B7-BA5B-2AE05BB5A9CF}" }, [4] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [5] = { ["CLSID"] = "{E2C426E3-8B10-4E09-B733-9CDC26520F48}" }, [7] = { ["CLSID"] = "{E2C426E3-8B10-4E09-B733-9CDC26520F48}" }, [8] = { ["CLSID"] = "{79D73885-0801-45a9-917F-C90FE1CE3DFC}" }, [9] = { ["CLSID"] = "{E8D4652F-FD48-45B7-BA5B-2AE05BB5A9CF}" }, [10] = { ["CLSID"] = "{CBC29BFE-3D24-4C64-B81D-941239D12249}" }, [11] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82C}" } } } }, ["Su-27"] = { ["altitude"] = 7400, ["speed"] = 170, ["payload"] = { ["chaff"] = 96, ["flare"] = 96, ["fuel"] = 9400, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [10] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [8] = { ["CLSID"] = "{TWIN_B_8M1_S_8KOM}" }, [7] = { ["CLSID"] = "{MBD3_U6_5*FAB-250}" }, [6] = { ["CLSID"] = "{53BE25A4-C86C-4571-9BC0-47D668349595}" }, [5] = { ["CLSID"] = "{MBD3_U6_3*FAB-250_fwd}" }, [4] = { ["CLSID"] = "{MBD3_U6_5*FAB-250}" }, [3] = { ["CLSID"] = "{TWIN_B_8M1_S_8KOM}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["antiship"] = { [10] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [8] = { ["CLSID"] = "{TWIN_S25}" }, [7] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{TWIN_S25}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [4] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [5] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [6] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [7] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [8] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["sead"] = { [10] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [8] = { ["CLSID"] = "{TWIN_B_8M1_S_8KOM}" }, [7] = { ["CLSID"] = "{MBD3_U6_5*FAB-250}" }, [6] = { ["CLSID"] = "{53BE25A4-C86C-4571-9BC0-47D668349595}" }, [5] = { ["CLSID"] = "{MBD3_U6_3*FAB-250_fwd}" }, [4] = { ["CLSID"] = "{MBD3_U6_5*FAB-250}" }, [3] = { ["CLSID"] = "{TWIN_B_8M1_S_8KOM}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["strike"] = { [10] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [8] = { ["CLSID"] = "{TWIN_S25}" }, [7] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [3] = { ["CLSID"] = "{TWIN_S25}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" } } } }, ["Su-30"] = { ["altitude"] = 6900, ["speed"] = 170, ["payload"] = { ["chaff"] = 96, ["flare"] = 96, ["fuel"] = 9400, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{F72F47E5-C83A-4B85-96ED-D3E46671EE9A}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{F72F47E5-C83A-4B85-96ED-D3E46671EE9A}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}" }, [4] = { ["CLSID"] = "{4D13E282-DF46-4B23-864A-A9423DFDE504}" }, [5] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [6] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [7] = { ["CLSID"] = "{4D13E282-DF46-4B23-864A-A9423DFDE504}" }, [8] = { ["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{88DAC840-9F75-4531-8689-B46E64E42E53}" }, [4] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [5] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [6] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [7] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [8] = { ["CLSID"] = "{88DAC840-9F75-4531-8689-B46E64E42E53}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["sead"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}" }, [4] = { ["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}" }, [5] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [6] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [7] = { ["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}" }, [8] = { ["CLSID"] = "{D8F2C90B-887B-4B9E-9FE2-996BC9E9AF03}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["strike"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{39821727-F6E2-45B3-B1F0-490CC8921D1E}" }, [5] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [6] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [8] = { ["CLSID"] = "{39821727-F6E2-45B3-B1F0-490CC8921D1E}" }, [9] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } } } }, ["Su-33"] = { ["altitude"] = 7400, ["speed"] = 170, ["payload"] = { ["chaff"] = 48, ["flare"] = 48, ["fuel"] = 9500, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["antiship"] = { [12] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [9] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [8] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [7] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [3] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["cap"] = { [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{B79C379A-9E87-4E50-A1EE-7F7E29C2E87A}" }, [4] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [5] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [6] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [7] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [8] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [9] = { ["CLSID"] = "{E8069896-8435-4B90-95C0-01A03AE6E400}" }, [10] = { ["CLSID"] = "{B79C379A-9E87-4E50-A1EE-7F7E29C2E87A}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } }, ["sead"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["strike"] = { [12] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [10] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [9] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [8] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [7] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [6] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [5] = { ["CLSID"] = "{37DCC01E-9E02-432F-B61D-10C166CA2798}" }, [4] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [3] = { ["CLSID"] = "{A0648264-4BC0-4EE8-A543-D119F6BA4257}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [1] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" } } } }, ["Su-34"] = { ["altitude"] = 6000, ["speed"] = 170, ["payload"] = { ["chaff"] = 64, ["flare"] = 64, ["fuel"] = 9800, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{X-31A}" }, [4] = { ["CLSID"] = "{X-31A}" }, [5] = { ["CLSID"] = "{X-31A}" }, [6] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [7] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [8] = { ["CLSID"] = "{X-31A}" }, [9] = { ["CLSID"] = "{X-31A}" }, [10] = { ["CLSID"] = "{X-31A}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["cap"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["sead"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{X-31P}" }, [4] = { ["CLSID"] = "{X-31P}" }, [6] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [7] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [9] = { ["CLSID"] = "{X-31P}" }, [10] = { ["CLSID"] = "{X-31P}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["strike"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [4] = { ["CLSID"] = "{39821727-F6E2-45B3-B1F0-490CC8921D1E}" }, [9] = { ["CLSID"] = "{39821727-F6E2-45B3-B1F0-490CC8921D1E}" }, [10] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } } } }, ["TF-51D"] = { ["altitude"] = 5200, ["speed"] = 125, ["payload"] = { ["fuel"] = 501, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 124, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{X-31A}" }, [4] = { ["CLSID"] = "{X-31A}" }, [5] = { ["CLSID"] = "{X-31A}" }, [6] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [7] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [8] = { ["CLSID"] = "{X-31A}" }, [9] = { ["CLSID"] = "{X-31A}" }, [10] = { ["CLSID"] = "{X-31A}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["cap"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [4] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [5] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [6] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [7] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [8] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [9] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [10] = { ["CLSID"] = "{3C612111-C7AD-476E-8A8E-2485812F4E5C}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["sead"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{X-31P}" }, [4] = { ["CLSID"] = "{X-31P}" }, [6] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [7] = { ["CLSID"] = "{9B25D316-0434-4954-868F-D51DB1A38DF0}" }, [9] = { ["CLSID"] = "{X-31P}" }, [10] = { ["CLSID"] = "{X-31P}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } }, ["strike"] = { [1] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82F}" }, [2] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [3] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [4] = { ["CLSID"] = "{39821727-F6E2-45B3-B1F0-490CC8921D1E}" }, [9] = { ["CLSID"] = "{39821727-F6E2-45B3-B1F0-490CC8921D1E}" }, [10] = { ["CLSID"] = "{B4C01D60-A8A3-4237-BD72-CA7655BC0FE9}" }, [11] = { ["CLSID"] = "{FBC29BFE-3D24-4C64-B81D-941239D12249}" }, [12] = { ["CLSID"] = "{44EE8698-89F9-48EE-AF36-5FD31896A82A}" } } } }, ["Tornado GR4"] = { ["altitude"] = 6080, ["speed"] = 120, ["payload"] = { ["chaff"] = 90, ["flare"] = 45, ["fuel"] = 4663, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [4] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [1] = { ["CLSID"] = "{8C3F26A2-FA0F-11d5-9190-00A0249B6F00}" } }, ["antiship"] = { [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{1461CD18-429A-42A9-A21F-4C621ECD4573}" }, [4] = { ["CLSID"] = "{1461CD18-429A-42A9-A21F-4C621ECD4573}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [1] = { ["CLSID"] = "{8C3F26A2-FA0F-11d5-9190-00A0249B6F00}" } }, ["cap"] = { [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [4] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [1] = { ["CLSID"] = "{8C3F26A2-FA0F-11d5-9190-00A0249B6F00}" } }, ["sead"] = { [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [10] = { ["CLSID"] = "{E6747967-B1F0-4C77-977B-AB2E6EB0C102}" }, [9] = { ["CLSID"] = "{E6747967-B1F0-4C77-977B-AB2E6EB0C102}" }, [7] = { ["CLSID"] = "" }, [8] = { ["CLSID"] = "" }, [4] = { ["CLSID"] = "{E6747967-B1F0-4C77-977B-AB2E6EB0C102}" }, [5] = { ["CLSID"] = "" }, [6] = { ["CLSID"] = "" }, [3] = { ["CLSID"] = "{E6747967-B1F0-4C77-977B-AB2E6EB0C102}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [1] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" } }, ["strike"] = { [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [9] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [4] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [1] = { ["CLSID"] = "{8C3F26A2-FA0F-11d5-9190-00A0249B6F00}" } } } }, ["Tornado IDS"] = { ["altitude"] = 6080, ["speed"] = 120, ["payload"] = { ["chaff"] = 90, ["flare"] = 45, ["fuel"] = 4663, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [6] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [7] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [8] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [2] = { ["CLSID"] = "{7210496B-7B81-4B52-80D6-8529ECF847CD}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{7210496B-7B81-4B52-80D6-8529ECF847CD}" }, [9] = { ["CLSID"] = "{7210496B-7B81-4B52-80D6-8529ECF847CD}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [11] = { ["CLSID"] = "{7210496B-7B81-4B52-80D6-8529ECF847CD}" }, [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" } }, ["cap"] = { [1] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [5] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [6] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [7] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [8] = { ["CLSID"] = "{BCE4E030-38E9-423E-98ED-24BE3DA87C32}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" } }, ["sead"] = { [1] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [2] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [9] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [11] = { ["CLSID"] = "{B06DD79A-F21E-4EB9-BD9D-AB3844618C93}" }, [12] = { ["CLSID"] = "{8C3F26A2-FA0F-11d5-9190-00A0249B6F00}" } }, ["strike"] = { [1] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" }, [2] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [3] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [4] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [9] = { ["CLSID"] = "{0D33DDAE-524F-4A4E-B5B8-621754FE3ADE}" }, [10] = { ["CLSID"] = "{6CEB49FC-DED8-4DED-B053-E1F033FF72D3}" }, [11] = { ["CLSID"] = "{EF124821-F9BB-4314-A153-E0E2FE1162C4}" }, [12] = { ["CLSID"] = "{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}" } } } }, ["Tu-142"] = { ["altitude"] = 4800, ["speed"] = 208, ["payload"] = { ["chaff"] = 48, ["flare"] = 48, ["fuel"] = 87000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{C42EE4C3-355C-4B83-8B22-B39430B8F4AE}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{C42EE4C3-355C-4B83-8B22-B39430B8F4AE}" } }, ["cap"] = { [1] = { ["CLSID"] = "{C42EE4C3-355C-4B83-8B22-B39430B8F4AE}" } }, ["sead"] = { [1] = { ["CLSID"] = "{C42EE4C3-355C-4B83-8B22-B39430B8F4AE}" } }, ["strike"] = { [1] = { ["CLSID"] = "{C42EE4C3-355C-4B83-8B22-B39430B8F4AE}" } } } }, ["Tu-160"] = { ["altitude"] = 6000, ["speed"] = 236, ["payload"] = { ["chaff"] = 72, ["flare"] = 72, ["fuel"] = 171000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" }, [2] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" }, [2] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["cap"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" }, [2] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["sead"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" }, [2] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["strike"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" }, [2] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } } } }, ["Tu-22M3"] = { ["altitude"] = 5400, ["speed"] = 250, ["payload"] = { ["chaff"] = 48, ["flare"] = 48, ["fuel"] = 50000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [5] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [4] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [3] = { ["CLSID"] = "{BDAD04AA-4D4A-4E51-B958-180A89F963CF}" }, [2] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [1] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" } }, ["antiship"] = { [5] = { ["CLSID"] = "{12429ECF-03F0-4DF6-BCBD-5D38B6343DE1}" }, [1] = { ["CLSID"] = "{12429ECF-03F0-4DF6-BCBD-5D38B6343DE1}" } }, ["cap"] = { [5] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [4] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [3] = { ["CLSID"] = "{BDAD04AA-4D4A-4E51-B958-180A89F963CF}" }, [2] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [1] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" } }, ["sead"] = { [5] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [4] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [3] = { ["CLSID"] = "{BDAD04AA-4D4A-4E51-B958-180A89F963CF}" }, [2] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" }, [1] = { ["CLSID"] = "{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}" } }, ["strike"] = { [3] = { ["CLSID"] = "{AD5E5863-08FC-4283-B92C-162E2B2BD3FF}" } } } }, ["Tu-95MS"] = { ["altitude"] = 4800, ["speed"] = 208, ["payload"] = { ["chaff"] = 48, ["flare"] = 48, ["fuel"] = 87000, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["antiship"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["cap"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["sead"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } }, ["strike"] = { [1] = { ["CLSID"] = "{0290F5DE-014A-4BB1-9843-D717749B1DED}" } } } }, ["UH-1H"] = { ["altitude"] = 740, ["speed"] = 204, ["payload"] = { ["chaff"] = 0, ["flare"] = 60, ["fuel"] = 631, ["gun"] = 100 }, ["properties"] = { ["ExhaustScreen"] = true, ["GunnersAISkill"] = 90, ["EngineResource"] = 90, ["SoloFlight"] = false, ["NetCrewControlPriority"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["antiship"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["cap"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["sead"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["strike"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } } } }, ["UH-60A"] = { ["altitude"] = 1268, ["speed"] = 237, ["payload"] = { ["chaff"] = 30, ["flare"] = 30, ["fuel"] = 1100, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["antiship"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["cap"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["sead"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } }, ["strike"] = { [1] = { ["CLSID"] = "M134_L" }, [2] = { ["CLSID"] = "XM158_MK5" }, [5] = { ["CLSID"] = "XM158_MK5" }, [6] = { ["CLSID"] = "M134_R" } } } }, ["WingLoong-I"] = { ["altitude"] = 3000, ["speed"] = 60, ["payload"] = { ["fuel"] = 400, ["gun"] = 100 }, ["properties"] = {}, ["options"] = { ["EPLRS"] = true }, ["radio"] = { ["frequency"] = 127.5, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["antiship"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["cap"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["sead"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["strike"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } } } }, ["Yak-40"] = { ["altitude"] = 4400, ["speed"] = 145, ["payload"] = { ["fuel"] = 3080, ["gun"] = 100 }, ["properties"] = {}, ["options"] = {}, ["radio"] = { ["frequency"] = 251, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["antiship"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["cap"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["sead"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["strike"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } } } }, ["Yak-52"] = { ["altitude"] = 1600, ["speed"] = 52.77777777777778, ["payload"] = { ["fuel"] = 87.84, ["gun"] = 100 }, ["properties"] = { ["SoloFlight"] = false, ["PropellorType"] = 0, ["NetCrewControlPriority"] = 0 }, ["options"] = {}, ["radio"] = { ["frequency"] = 132, ["modulation"] = 0 }, ["pylons"] = { ["attack"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["antiship"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["cap"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["sead"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } }, ["strike"] = { [2] = { ["CLSID"] = "DIS_AKD-10" }, [1] = { ["CLSID"] = "DIS_AKD-10" } } } } } Library.environment = {} Library.environment.windAmount = { CALM = 1, LIGHT_BREEZE = 2, MODERATE_BREEZE = 3, STRONG_BREEZE = 4, GALE = 5, STORM = 6 } do local DAYTIME_TABLE = { ["Afghanistan"] = { { 05 * 60 + 31, 18 * 60 + 33 }, { 05 * 60 + 14, 19 * 60 + 00 }, { 04 * 60 + 40, 19 * 60 + 24 }, { 03 * 60 + 53, 19 * 60 + 54 }, { 03 * 60 + 12, 20 * 60 + 27 }, { 02 * 60 + 54, 20 * 60 + 53 }, { 03 * 60 + 09, 20 * 60 + 48 }, { 03 * 60 + 42, 20 * 60 + 12 }, { 04 * 60 + 11, 19 * 60 + 24 }, { 04 * 60 + 35, 18 * 60 + 42 }, { 04 * 60 + 59, 18 * 60 + 15 }, { 05 * 60 + 22, 18 * 60 + 14 }, }, ["Caucasus"] = { { 08 * 60 + 26, 17 * 60 + 57 }, { 07 * 60 + 49, 18 * 60 + 30 }, { 07 * 60 + 14, 19 * 60 + 01 }, { 07 * 60 + 30, 19 * 60 + 34 }, { 06 * 60 + 35, 20 * 60 + 06 }, { 05 * 60 + 33, 20 * 60 + 40 }, { 06 * 60 + 06, 20 * 60 + 18 }, { 06 * 60 + 39, 19 * 60 + 45 }, { 07 * 60 + 11, 19 * 60 + 13 }, { 08 * 60 + 02, 18 * 60 + 40 }, { 08 * 60 + 17, 18 * 60 + 07 }, { 08 * 60 + 39, 17 * 60 + 45 }, }, ["Falklands"] = { { 04 * 60 + 42, 20 * 60 + 48 }, { 05 * 60 + 32, 19 * 60 + 54 }, { 06 * 60 + 24, 18 * 60 + 43 }, { 07 * 60 + 18, 17 * 60 + 40 }, { 08 * 60 + 08, 16 * 60 + 57 }, { 08 * 60 + 51, 16 * 60 + 56 }, { 09 * 60 + 04, 17 * 60 + 31 }, { 08 * 60 + 33, 18 * 60 + 19 }, { 07 * 60 + 33, 19 * 60 + 07 }, { 06 * 60 + 24, 20 * 60 + 01 }, { 05 * 60 + 17, 20 * 60 + 53 }, { 04 * 60 + 36, 21 * 60 + 17 }, }, ["GermanyCW"] = { { 08 * 60 + 09, 16 * 60 + 25 }, { 07 * 60 + 22, 17 * 60 + 19 }, { 06 * 60 + 20, 18 * 60 + 11 }, { 06 * 60 + 08, 20 * 60 + 05 }, { 05 * 60 + 10, 20 * 60 + 56 }, { 04 * 60 + 42, 21 * 60 + 31 }, { 05 * 60 + 02, 21 * 60 + 22 }, { 05 * 60 + 49, 20 * 60 + 31 }, { 06 * 60 + 40, 19 * 60 + 21 }, { 07 * 60 + 32, 18 * 60 + 11 }, { 07 * 60 + 28, 16 * 60 + 13 }, { 08 * 60 + 11, 15 * 60 + 52 }, }, ["Iraq"] = { { 07 * 60 + 06, 17 * 60 + 33 }, { 06 * 60 + 58, 17 * 60 + 58 }, { 06 * 60 + 30, 18 * 60 + 21 }, { 05 * 60 + 50, 18 * 60 + 44 }, { 05 * 60 + 14, 19 * 60 + 06 }, { 04 * 60 + 53, 19 * 60 + 15 }, { 04 * 60 + 56, 19 * 60 + 03 }, { 05 * 60 + 15, 18 * 60 + 28 }, { 05 * 60 + 36, 17 * 60 + 48 }, { 05 * 60 + 56, 17 * 60 + 11 }, { 06 * 60 + 20, 16 * 60 + 54 }, { 06 * 60 + 47, 17 * 60 + 04 }, }, ["Kola"] = { { 11 * 60 + 52, 14 * 60 + 02 }, { 09 * 60 + 15, 16 * 60 + 50 }, { 07 * 60 + 07, 18 * 60 + 47 }, { 04 * 60 + 49, 20 * 60 + 48 }, { 02 * 60 + 10, 23 * 60 + 24 }, { 00 * 60 + 00, 23 * 60 + 59 }, { 00 * 60 + 00, 23 * 60 + 59 }, { 03 * 60 + 59, 21 * 60 + 41 }, { 06 * 60 + 03, 19 * 60 + 19 }, { 07 * 60 + 56, 17 * 60 + 08 }, { 10 * 60 + 16, 14 * 60 + 47 }, { 12 * 60 + 00, 13 * 60 + 01 }, }, ["MarianaIslands"] = { { 07 * 60 + 10, 16 * 60 + 15 }, { 06 * 60 + 50, 16 * 60 + 45 }, { 06 * 60 + 13, 17 * 60 + 11 }, { 05 * 60 + 31, 19 * 60 + 35 }, { 05 * 60 + 00, 19 * 60 + 59 }, { 04 * 60 + 49, 20 * 60 + 18 }, { 05 * 60 + 31, 20 * 60 + 17 }, { 05 * 60 + 24, 19 * 60 + 51 }, { 05 * 60 + 46, 19 * 60 + 10 }, { 06 * 60 + 09, 18 * 60 + 28 }, { 06 * 60 + 37, 15 * 60 + 58 }, { 07 * 60 + 03, 15 * 60 + 54 }, }, ["MarianaIslandsWWII"] = { { 07 * 60 + 10, 16 * 60 + 15 }, { 06 * 60 + 50, 16 * 60 + 45 }, { 06 * 60 + 13, 17 * 60 + 11 }, { 05 * 60 + 31, 19 * 60 + 35 }, { 05 * 60 + 00, 19 * 60 + 59 }, { 04 * 60 + 49, 20 * 60 + 18 }, { 05 * 60 + 31, 20 * 60 + 17 }, { 05 * 60 + 24, 19 * 60 + 51 }, { 05 * 60 + 46, 19 * 60 + 10 }, { 06 * 60 + 09, 18 * 60 + 28 }, { 06 * 60 + 37, 15 * 60 + 58 }, { 07 * 60 + 03, 15 * 60 + 54 }, }, ["Nevada"] = { { 07 * 60 + 21, 16 * 60 + 19 }, { 06 * 60 + 58, 16 * 60 + 51 }, { 06 * 60 + 21, 17 * 60 + 18 }, { 06 * 60 + 37, 18 * 60 + 44 }, { 06 * 60 + 04, 19 * 60 + 10 }, { 05 * 60 + 53, 19 * 60 + 29 }, { 06 * 60 + 05, 19 * 60 + 27 }, { 06 * 60 + 29, 19 * 60 + 00 }, { 06 * 60 + 53, 18 * 60 + 17 }, { 07 * 60 + 28, 17 * 60 + 34 }, { 06 * 60 + 47, 16 * 60 + 02 }, { 07 * 60 + 14, 15 * 60 + 58 }, }, ["Normandy"] = { { 09 * 60 + 23, 17 * 60 + 01 }, { 08 * 60 + 43, 17 * 60 + 52 }, { 07 * 60 + 48, 18 * 60 + 37 }, { 06 * 60 + 43, 19 * 60 + 24 }, { 05 * 60 + 50, 20 * 60 + 09 }, { 05 * 60 + 26, 20 * 60 + 40 }, { 05 * 60 + 42, 20 * 60 + 34 }, { 06 * 60 + 23, 19 * 60 + 51 }, { 07 * 60 + 08, 18 * 60 + 48 }, { 07 * 60 + 53, 17 * 60 + 44 }, { 08 * 60 + 42, 16 * 60 + 52 }, { 09 * 60 + 21, 16 * 60 + 34 }, }, ["PersianGulf"] = { { 07 * 60 + 34, 17 * 60 + 17 }, { 07 * 60 + 22, 17 * 60 + 39 }, { 06 * 60 + 55, 17 * 60 + 55 }, { 06 * 60 + 23, 18 * 60 + 09 }, { 06 * 60 + 01, 18 * 60 + 25 }, { 05 * 60 + 55, 18 * 60 + 39 }, { 06 * 60 + 05, 18 * 60 + 40 }, { 06 * 60 + 20, 18 * 60 + 21 }, { 06 * 60 + 32, 17 * 60 + 50 }, { 06 * 60 + 45, 17 * 60 + 19 }, { 07 * 60 + 04, 16 * 60 + 58 }, { 07 * 60 + 25, 16 * 60 + 58 }, }, ["SinaiMap"] = { { 07 * 60 + 10, 16 * 60 + 15 }, { 06 * 60 + 50, 16 * 60 + 45 }, { 06 * 60 + 13, 17 * 60 + 11 }, { 05 * 60 + 31, 19 * 60 + 35 }, { 05 * 60 + 00, 19 * 60 + 59 }, { 04 * 60 + 49, 20 * 60 + 18 }, { 05 * 60 + 31, 20 * 60 + 17 }, { 05 * 60 + 24, 19 * 60 + 51 }, { 05 * 60 + 46, 19 * 60 + 10 }, { 06 * 60 + 09, 18 * 60 + 28 }, { 06 * 60 + 37, 15 * 60 + 58 }, { 07 * 60 + 03, 15 * 60 + 54 }, }, ["Syria"] = { { 07 * 60 + 10, 16 * 60 + 15 }, { 06 * 60 + 50, 16 * 60 + 45 }, { 06 * 60 + 13, 17 * 60 + 11 }, { 05 * 60 + 31, 19 * 60 + 35 }, { 05 * 60 + 00, 19 * 60 + 59 }, { 04 * 60 + 49, 20 * 60 + 18 }, { 05 * 60 + 31, 20 * 60 + 17 }, { 05 * 60 + 24, 19 * 60 + 51 }, { 05 * 60 + 46, 19 * 60 + 10 }, { 06 * 60 + 09, 18 * 60 + 28 }, { 06 * 60 + 37, 15 * 60 + 58 }, { 07 * 60 + 03, 15 * 60 + 54 }, }, ["TheChannel"] = { { 09 * 60 + 23, 17 * 60 + 01 }, { 08 * 60 + 43, 17 * 60 + 52 }, { 07 * 60 + 48, 18 * 60 + 37 }, { 06 * 60 + 43, 19 * 60 + 24 }, { 05 * 60 + 50, 20 * 60 + 09 }, { 05 * 60 + 26, 20 * 60 + 40 }, { 05 * 60 + 42, 20 * 60 + 34 }, { 06 * 60 + 23, 19 * 60 + 51 }, { 07 * 60 + 08, 18 * 60 + 48 }, { 07 * 60 + 53, 17 * 60 + 44 }, { 08 * 60 + 42, 16 * 60 + 52 }, { 09 * 60 + 21, 16 * 60 + 34 }, } } function Library.environment.getDayTime(monthIndex, sunset) monthIndex = DCSEx.math.clamp(monthIndex or env.mission.date.Month, 1, 12) sunset = sunset or false if not env or not env.mission or not env.mission.theatre then return 0 end if not DAYTIME_TABLE[env.mission.theatre] then return 0 end local sunIndex = 1 if sunset then sunIndex = 2 end return DAYTIME_TABLE[env.mission.theatre][monthIndex][sunIndex] * 60 end function Library.environment.isItNightTime(timeOfDayInSeconds) if not env or not env.mission or not env.mission.theatre then return false end if not DAYTIME_TABLE[env.mission.theatre] then return false end timeOfDayInSeconds = math.max(0, timeOfDayInSeconds or timer.getAbsTime()) if timeOfDayInSeconds > 86400 then while timeOfDayInSeconds > 86400 do timeOfDayInSeconds = timeOfDayInSeconds - 86400 end end local sunriseTime = Library.environment.getDayTime(nil, false) local sunsetTime = Library.environment.getDayTime(nil, true) return timeOfDayInSeconds < sunriseTime or timeOfDayInSeconds > sunsetTime end function Library.environment.getWindAverage() local windSpeed = 0 local windSpeedValuesCount = 0 if not env or not env.mission or not env.mission.weather or not env.mission.weather.wind then return 0 end for _,v in ipairs({"at8000", "atGround", "at2000"}) do if env.mission.weather.wind[v] and env.mission.weather.wind[v].speed then windSpeed = windSpeed + env.mission.weather.wind[v].speed windSpeedValuesCount = windSpeedValuesCount + 1 end end windSpeed = math.max(0, windSpeed / windSpeedValuesCount) return windSpeed end function Library.environment.getWindLevel() local windSpeed = Library.environment.getWindAverage() if windSpeed < 1 then return Library.environment.windAmount.CALM elseif windSpeed < 4 then return Library.environment.windAmount.LIGHT_BREEZE elseif windSpeed < 8 then return Library.environment.windAmount.MODERATE_BREEZE elseif windSpeed < 14 then return Library.environment.windAmount.STRONG_BREEZE elseif windSpeed < 21 then return Library.environment.windAmount.GALE else return Library.environment.windAmount.STORM end end end Library.factions = {} Library.factions.defaults = { "USA", "Russia" } Library.factions.tables = {} -- do -- Library.factions.tables["China"] = {} -- Library.factions.tables["China"].theaters = {} -- Library.factions.tables["China"].timePeriods = {} -- Library.factions.tables["China"].units = {} -- Library.factions.tables["China"].units[DCSEx.enums.timePeriod.WORLD_WAR_2] = {} -- Library.factions.tables["China"].units[DCSEx.enums.timePeriod.KOREA_WAR] = {} -- Library.factions.tables["China"].units[DCSEx.enums.timePeriod.VIETNAM_WAR] = {} -- Library.factions.tables["China"].units[DCSEx.enums.timePeriod.COLD_WAR] = {} -- Library.factions.tables["China"].units[DCSEx.enums.timePeriod.MODERN] = { -- [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE] = { "HL_ZU-23", "tt_ZU-23" }, -- [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_STATIC] = { "ZU-23 Closed Insurgent", "ZU-23 Insurgent" }, -- [DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS] = { "Igla manpad INS", "SA-18 Igla-S manpad" }, -- [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG] = { "*SA-2" }, -- [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM] = { "*SA-2", "*SA-3" }, -- [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT] = { "Osa 9A33 ln", "Tor 9A331" }, -- [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR] = { "Strela-1 9P31" }, -- [DCSEx.enums.unitFamily.GROUND_APC] = { "HL_DSHK", "HL_KORD", "tt_DSHK", "tt_KORD", "BMD-1", "BMP-1", "Boman", "BRDM-2", "BTR_D", "BTR-80" }, -- [DCSEx.enums.unitFamily.GROUND_ARTILLERY] = { "Grad-URAL", "SAU 2-C9", "SAU Akatsia", "SAU Gvozdika", "SAU Msta", "Smerch", "SpGH_Dana", "Uragan_BM-27" }, -- [DCSEx.enums.unitFamily.GROUND_INFANTRY] = { "Infantry AK Ins" }, -- [DCSEx.enums.unitFamily.GROUND_MBT] = { "ZTZ96B" }, -- [DCSEx.enums.unitFamily.GROUND_SS_MISSILE] = { "Scud_B" }, -- [DCSEx.enums.unitFamily.GROUND_UNARMED] = { "Land_Rover_101_FC", "Land_Rover_109_S3", "Ural-375", "Ural-4320 APA-5D", "Ural-4320T" }, -- [DCSEx.enums.unitFamily.HELICOPTER_ATTACK] = { "Mi-24V", "Mi-28N" }, -- [DCSEx.enums.unitFamily.HELICOPTER_TRANSPORT] = { "Mi-8MT", "Mi-26" }, -- [DCSEx.enums.unitFamily.PLANE_AWACS] = { "A-50" }, -- [DCSEx.enums.unitFamily.PLANE_BOMBER] = { "Tu-22M3" }, -- [DCSEx.enums.unitFamily.PLANE_FIGHTER] = { "MiG-21Bis" }, -- [DCSEx.enums.unitFamily.PLANE_TANKER] = { "IL-78M" }, -- [DCSEx.enums.unitFamily.PLANE_TRANSPORT] = { "An-26B" }, -- [DCSEx.enums.unitFamily.PLANE_UAV] = { "WingLoong-I" }, -- [DCSEx.enums.unitFamily.SHIP_CARGO] = { "Dry-cargo ship-1", "Dry-cargo ship-2", "ELNYA", "Ship_Tilde_Supply" }, -- [DCSEx.enums.unitFamily.SHIP_CARRIER] = { "KUZNECOW" }, -- [DCSEx.enums.unitFamily.SHIP_CRUISER] = { "MOSCOW", "PIOTR" }, -- [DCSEx.enums.unitFamily.SHIP_FRIGATE] = { "leander-gun-andromeda", "leander-gun-ariadne", "leander-gun-condell", "leander-gun-lynch" }, -- [DCSEx.enums.unitFamily.SHIP_LIGHT] = { "speedboat" }, -- [DCSEx.enums.unitFamily.SHIP_MISSILE_BOAT] = { "ALBATROS", "BDK-775", "MOLNIYA" }, -- [DCSEx.enums.unitFamily.SHIP_SUBMARINE] = { "KILO", "SOM" }, -- -- [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Bunker", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Sandbox", "Workshop A" }, -- [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Workshop A" }, -- } -- end do Library.factions.tables["Insurgents"] = {} Library.factions.tables["Insurgents"].theaters = {} Library.factions.tables["Insurgents"].timePeriods = {} Library.factions.tables["Insurgents"].units = {} Library.factions.tables["Insurgents"].units[DCSEx.enums.timePeriod.WORLD_WAR_2] = {} Library.factions.tables["Insurgents"].units[DCSEx.enums.timePeriod.KOREA_WAR] = {} Library.factions.tables["Insurgents"].units[DCSEx.enums.timePeriod.VIETNAM_WAR] = {} Library.factions.tables["Insurgents"].units[DCSEx.enums.timePeriod.COLD_WAR] = {} Library.factions.tables["Insurgents"].units[DCSEx.enums.timePeriod.MODERN] = { [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE] = { "HL_ZU-23", "tt_ZU-23" }, [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_STATIC] = { "ZU-23 Closed Insurgent", "ZU-23 Insurgent" }, [DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS] = { "Igla manpad INS", "SA-18 Igla-S manpad" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG] = { "*SA-2" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM] = { "*SA-2", "*SA-3" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT] = { "Osa 9A33 ln", "Tor 9A331" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR] = { "Strela-1 9P31" }, [DCSEx.enums.unitFamily.GROUND_APC] = { "HL_DSHK", "HL_KORD", "tt_DSHK", "tt_KORD", "BMD-1", "BMP-1", "Boman", "BRDM-2", "BTR_D", "BTR-80" }, [DCSEx.enums.unitFamily.GROUND_ARTILLERY] = { "Grad-URAL", "SAU 2-C9", "SAU Akatsia", "SAU Gvozdika", "SAU Msta", "Smerch", "SpGH_Dana", "Uragan_BM-27" }, [DCSEx.enums.unitFamily.GROUND_INFANTRY] = { "Infantry AK Ins" }, [DCSEx.enums.unitFamily.GROUND_MBT] = { "T-55", "T-72B" }, [DCSEx.enums.unitFamily.GROUND_SS_MISSILE] = { "Scud_B" }, [DCSEx.enums.unitFamily.GROUND_UNARMED] = { "Land_Rover_101_FC", "Land_Rover_109_S3", "Ural-375", "Ural-4320 APA-5D", "Ural-4320T" }, [DCSEx.enums.unitFamily.HELICOPTER_ATTACK] = { "Mi-24V", "Mi-28N" }, [DCSEx.enums.unitFamily.HELICOPTER_TRANSPORT] = { "Mi-8MT", "Mi-26" }, [DCSEx.enums.unitFamily.PLANE_ATTACK] = { "Su-25" }, [DCSEx.enums.unitFamily.PLANE_AWACS] = { "A-50" }, [DCSEx.enums.unitFamily.PLANE_BOMBER] = { "Tu-22M3" }, [DCSEx.enums.unitFamily.PLANE_FIGHTER] = { "MiG-21Bis" }, [DCSEx.enums.unitFamily.PLANE_TANKER] = { "IL-78M" }, [DCSEx.enums.unitFamily.PLANE_TRANSPORT] = { "An-26B" }, [DCSEx.enums.unitFamily.PLANE_UAV] = { "WingLoong-I" }, [DCSEx.enums.unitFamily.SHIP_CARGO] = { "Dry-cargo ship-1", "Dry-cargo ship-2", "ELNYA", "Ship_Tilde_Supply" }, [DCSEx.enums.unitFamily.SHIP_CARRIER] = { "KUZNECOW" }, [DCSEx.enums.unitFamily.SHIP_CRUISER] = { "MOSCOW", "PIOTR" }, [DCSEx.enums.unitFamily.SHIP_FRIGATE] = { "leander-gun-andromeda", "leander-gun-ariadne", "leander-gun-condell", "leander-gun-lynch" }, [DCSEx.enums.unitFamily.SHIP_LIGHT] = { "speedboat" }, [DCSEx.enums.unitFamily.SHIP_MISSILE_BOAT] = { "ALBATROS", "BDK-775", "MOLNIYA" }, [DCSEx.enums.unitFamily.SHIP_SUBMARINE] = { "KILO", "SOM" }, -- [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Bunker", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Sandbox", "Workshop A" }, [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Workshop A" }, } end do local factionName = "Middle-eastern state" if env.mission.theatre == "PersianGulf" then factionName = "Saudi Arabia" elseif env.mission.theatre == "Syria" then factionName = "Syria" Library.factions.defaults[coalition.side.RED] = "Syria" end Library.factions.tables[factionName] = {} Library.factions.tables[factionName].theaters = {"PersianGulf"," Syria"} Library.factions.tables[factionName].timePeriods = {} Library.factions.tables[factionName].units = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.WORLD_WAR_2] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.KOREA_WAR] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.VIETNAM_WAR] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.COLD_WAR] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.MODERN] = { [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE] = { "Ural-375 ZU-23", "ZSU_57_2", "ZSU-23-4 Shilka" }, [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_STATIC] = { "ZU-23 Emplacement Closed", "ZU-23 Emplacement" }, [DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS] = { "SA-18 Igla manpad", "SA-18 Igla-S manpad" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG] = { "*SA-2", "*SA-10" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM] = { "*SA-3", "*SA-6", "*SA-11" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT] = { "2S6 Tunguska", "Osa 9A33 ln", "Tor 9A331" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR] = { "Strela-1 9P31", "Strela-10M3" }, [DCSEx.enums.unitFamily.GROUND_APC] = { "BMD-1", "BMP-1", "BMP-2", "BMP-3", "Boman", "BRDM-2", "BTR_D", "BTR-80", "BTR-82A", "Grad_FDDM", "MTLB" }, [DCSEx.enums.unitFamily.GROUND_ARTILLERY] = { "Grad-URAL", "SAU 2-C9", "SAU Akatsia", "SAU Gvozdika", "SAU Msta", "Smerch", "SpGH_Dana", "Uragan_BM-27" }, [DCSEx.enums.unitFamily.GROUND_INFANTRY] = { "Infantry AK", "Infantry AK ver2", "Infantry AK ver3", "Paratrooper AKS-74", "Paratrooper RPG-16", "Soldier AK" }, [DCSEx.enums.unitFamily.GROUND_MBT] = { "T-55", "T-72B", "T-80UD", "T-90" }, [DCSEx.enums.unitFamily.GROUND_SS_MISSILE] = { "Scud_B" }, [DCSEx.enums.unitFamily.GROUND_UNARMED] = { "Ural-375", "Ural-4320 APA-5D", "Ural-4320T" }, [DCSEx.enums.unitFamily.HELICOPTER_ATTACK] = { "Ka-50", "Mi-24V", "Mi-28N" }, [DCSEx.enums.unitFamily.HELICOPTER_TRANSPORT] = { "Ka-27", "Mi-8MT", "Mi-26" }, [DCSEx.enums.unitFamily.PLANE_ATTACK] = { "Su-25" }, [DCSEx.enums.unitFamily.PLANE_AWACS] = { "A-50" }, [DCSEx.enums.unitFamily.PLANE_BOMBER] = { "Tu-22M3", "Tu-95MS", "Tu-160" }, [DCSEx.enums.unitFamily.PLANE_FIGHTER] = { "MiG-21Bis" }, [DCSEx.enums.unitFamily.PLANE_TANKER] = { "IL-78M" }, [DCSEx.enums.unitFamily.PLANE_TRANSPORT] = { "An-26B", "An-30M", "IL-76MD" }, [DCSEx.enums.unitFamily.PLANE_UAV] = { "WingLoong-I" }, [DCSEx.enums.unitFamily.HELICOPTER_ATTACK] = { "Ka-50", "Mi-24V", "Mi-28N" }, [DCSEx.enums.unitFamily.SHIP_CARGO] = { "Dry-cargo ship-1", "Dry-cargo ship-2", "ELNYA", "Ship_Tilde_Supply" }, [DCSEx.enums.unitFamily.SHIP_CARRIER] = { "CV_1143_5", "KUZNECOW" }, [DCSEx.enums.unitFamily.SHIP_CRUISER] = { "MOSCOW", "PIOTR" }, [DCSEx.enums.unitFamily.SHIP_FRIGATE] = { "NEUSTRASH", "REZKY" }, [DCSEx.enums.unitFamily.SHIP_LIGHT] = { "speedboat" }, [DCSEx.enums.unitFamily.SHIP_MISSILE_BOAT] = { "ALBATROS", "BDK-775", "MOLNIYA" }, [DCSEx.enums.unitFamily.SHIP_SUBMARINE] = { "IMPROVED_KILO", "KILO", "SOM" }, -- [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Bunker", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Sandbox", "Workshop A" }, [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Workshop A" }, } ------------------------------------------------------------------------ -- Create Iran faction from generic "Middle-Eastern state" coalition ------------------------------------------------------------------------ Library.factions.tables["Iran"] = DCSEx.table.deepCopy(Library.factions.tables[factionName]) Library.factions.tables["Iran"].theaters = {"PersianGulf"} if env.mission.theatre == "PersianGulf" then Library.factions.defaults[coalition.side.RED] = "Iran" end -- Iran have F-14 too table.insert(Library.factions.tables["Iran"].units[DCSEx.enums.timePeriod.MODERN][DCSEx.enums.unitFamily.PLANE_FIGHTER], "F-14A-135-GR") end do local factionName = "Russia" -- if env.mission.date.Year < 1990 then -- factionName = "USSR" -- end Library.factions.defaults[coalition.side.RED] = factionName Library.factions.tables[factionName] = {} Library.factions.tables[factionName].theaters = {} Library.factions.tables[factionName].timePeriods = {} Library.factions.tables[factionName].units = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.WORLD_WAR_2] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.KOREA_WAR] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.VIETNAM_WAR] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.COLD_WAR] = {} Library.factions.tables[factionName].units[DCSEx.enums.timePeriod.MODERN] = { [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE] = { "Ural-375 ZU-23", "ZSU_57_2", "ZSU-23-4 Shilka" }, [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_STATIC] = { "ZU-23 Emplacement Closed", "ZU-23 Emplacement" }, [DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS] = { "SA-18 Igla manpad", "SA-18 Igla-S manpad" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG] = { "*SA-2", "*SA-10" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG] = { "*SA-10" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM] = { "*SA-3", "*SA-6", "*SA-11" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT] = { "2S6 Tunguska", "Osa 9A33 ln", "Tor 9A331" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR] = { "Strela-1 9P31", "Strela-10M3" }, [DCSEx.enums.unitFamily.GROUND_APC] = { "BMD-1", "BMP-1", "BMP-2", "BMP-3", "Boman", "BRDM-2", "BTR_D", "BTR-80", "BTR-82A", "Grad_FDDM", "MTLB" }, [DCSEx.enums.unitFamily.GROUND_ARTILLERY] = { "Grad-URAL", "SAU 2-C9", "SAU Akatsia", "SAU Gvozdika", "SAU Msta", "Smerch", "SpGH_Dana", "Uragan_BM-27" }, [DCSEx.enums.unitFamily.GROUND_INFANTRY] = { "Infantry AK", "Infantry AK ver2", "Infantry AK ver3", "Paratrooper AKS-74", "Paratrooper RPG-16", "Soldier AK" }, [DCSEx.enums.unitFamily.GROUND_MBT] = { "T-55", "T-72B", "T-80UD", "T-90" }, [DCSEx.enums.unitFamily.GROUND_SS_MISSILE] = { "Scud_B" }, [DCSEx.enums.unitFamily.GROUND_UNARMED] = { "Ural-375", "Ural-4320 APA-5D", "Ural-4320T" }, [DCSEx.enums.unitFamily.HELICOPTER_ATTACK] = { "Ka-50", "Mi-24V", "Mi-28N" }, [DCSEx.enums.unitFamily.HELICOPTER_TRANSPORT] = { "Ka-27", "Mi-8MT", "Mi-26" }, [DCSEx.enums.unitFamily.PLANE_ATTACK] = { "Su-25" }, [DCSEx.enums.unitFamily.PLANE_AWACS] = { "A-50" }, [DCSEx.enums.unitFamily.PLANE_BOMBER] = { "Tu-22M3", "Tu-95MS", "Tu-160" }, [DCSEx.enums.unitFamily.PLANE_FIGHTER] = { "MiG-29", "Su-27", "Su-33" }, [DCSEx.enums.unitFamily.PLANE_TANKER] = { "IL-78M" }, [DCSEx.enums.unitFamily.PLANE_TRANSPORT] = { "An-26B", "An-30M", "IL-76MD" }, [DCSEx.enums.unitFamily.PLANE_UAV] = { "WingLoong-I" }, [DCSEx.enums.unitFamily.HELICOPTER_ATTACK] = { "Ka-50", "Mi-24V", "Mi-28N" }, [DCSEx.enums.unitFamily.SHIP_CARGO] = { "Dry-cargo ship-1", "Dry-cargo ship-2", "ELNYA", "Ship_Tilde_Supply" }, [DCSEx.enums.unitFamily.SHIP_CARRIER] = { "CV_1143_5", "KUZNECOW" }, [DCSEx.enums.unitFamily.SHIP_CRUISER] = { "MOSCOW", "PIOTR" }, [DCSEx.enums.unitFamily.SHIP_FRIGATE] = { "NEUSTRASH", "REZKY" }, [DCSEx.enums.unitFamily.SHIP_LIGHT] = { "speedboat" }, [DCSEx.enums.unitFamily.SHIP_MISSILE_BOAT] = { "ALBATROS", "BDK-775", "MOLNIYA" }, [DCSEx.enums.unitFamily.SHIP_SUBMARINE] = { "IMPROVED_KILO", "KILO", "SOM" }, -- [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Bunker", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Sandbox", "Workshop A" }, [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Workshop A" }, } end Library.factions.defaults[coalition.side.BLUE] = "USA" do Library.factions.tables["USA"] = {} Library.factions.tables["USA"].theaters = {} Library.factions.tables["USA"].timePeriods = {} Library.factions.tables["USA"].units = {} Library.factions.tables["USA"].units[DCSEx.enums.timePeriod.WORLD_WAR_2] = {} Library.factions.tables["USA"].units[DCSEx.enums.timePeriod.KOREA_WAR] = {} Library.factions.tables["USA"].units[DCSEx.enums.timePeriod.VIETNAM_WAR] = {} Library.factions.tables["USA"].units[DCSEx.enums.timePeriod.COLD_WAR] = {} Library.factions.tables["USA"].units[DCSEx.enums.timePeriod.MODERN] = { [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE] = { "Gepard", "Vulcan" }, [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_STATIC] = { "Gepard", "Vulcan" }, [DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS] = { "Soldier stinger" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG] = { "*Patriot" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM] = { "*HAWK", "*NASAMS" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT] = { "rapier_fsa", "Roland ADS" }, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR] = { "M6 Linebacker", "M48 Chaparral", "M1097 Avenger" }, [DCSEx.enums.unitFamily.GROUND_APC] = { "AAV7", "Cobra", "LAV-25", "M-2 Bradley", "M-113", "M1045 HMMWV TOW", "M1126 Stryker ICV", "M1128 Stryker MGS", "Marder", "MCV-80", "MLRS FDDM", "TPZ" }, [DCSEx.enums.unitFamily.GROUND_ARTILLERY] = { "M-109", "MLRS" }, [DCSEx.enums.unitFamily.GROUND_INFANTRY] = { "Soldier M4 GRG", "Soldier M4", "Soldier M249", "Soldier RPG" }, [DCSEx.enums.unitFamily.GROUND_MBT] = { "Challenger2", "Leclerc", "Leopard-2", "Leopard1A3", "M-1 Abrams", "Merkava_Mk4" }, [DCSEx.enums.unitFamily.GROUND_SS_MISSILE] = { "Scud_B" }, [DCSEx.enums.unitFamily.GROUND_UNARMED] = { "Land_Rover_101_FC", "Land_Rover_109_S3", "M 818" }, [DCSEx.enums.unitFamily.HELICOPTER_ATTACK] = { "AH-1W", "AH-64D", "OH-58D", "SA342L", "SA342M", "SA342Minigun", "SA342Mistral" }, [DCSEx.enums.unitFamily.HELICOPTER_TRANSPORT] = { "CH-47D", "CH-53E", "SH-60B", "UH-60A" }, [DCSEx.enums.unitFamily.PLANE_ATTACK] = { "A-10C_2" }, [DCSEx.enums.unitFamily.PLANE_AWACS] = { "E-2C", "E-3A" }, [DCSEx.enums.unitFamily.PLANE_BOMBER] = { "B-1B Lancer", "B-52H" }, [DCSEx.enums.unitFamily.PLANE_FIGHTER] = { "F-16C_50", "FA-18C_hornet" }, [DCSEx.enums.unitFamily.PLANE_TANKER] = { "KC-135", "KC135MPRS" }, [DCSEx.enums.unitFamily.PLANE_TRANSPORT] = { "C-17A", "C-130" }, [DCSEx.enums.unitFamily.PLANE_UAV] = { "RQ-1A Predator" }, [DCSEx.enums.unitFamily.SHIP_CARGO] = { "Dry-cargo ship-1", "Dry-cargo ship-2", "ELNYA", "Ship_Tilde_Supply" }, [DCSEx.enums.unitFamily.SHIP_CARRIER] = { "CVN_71", "CVN_72", "CVN_73", "CVN_75", "hms_invincible", "LHA_Tarawa", "Stennis" }, [DCSEx.enums.unitFamily.SHIP_CRUISER] = { "TICONDEROG" }, [DCSEx.enums.unitFamily.SHIP_FRIGATE] = { "PERRY", "USS_Arleigh_Burke_IIa" }, [DCSEx.enums.unitFamily.SHIP_LIGHT] = { "speedboat" }, [DCSEx.enums.unitFamily.SHIP_MISSILE_BOAT] = { "CastleClass_01", "La_Combattante_II" }, [DCSEx.enums.unitFamily.SHIP_SUBMARINE] = { "santafe" }, -- [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Bunker", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Sandbox", "Workshop A" }, [DCSEx.enums.unitFamily.STATIC_STRUCTURE] = { "af_hq", ".Command Center", "Building01_PBR", "Building02_PBR", "Building03_PBR", "Building04_PBR", "Building05_PBR", "Chemical tank A", "Comms tower M", "FARP Fuel Depot", "outpost", "Workshop A" }, } end -- The "Any" faction has access to all units from all other factions do Library.factions.tables["Any"] = {} Library.factions.tables["Any"].theaters = {} Library.factions.tables["Any"].timePeriods = {} Library.factions.tables["Any"].units = {} local function copyUnitTableToAny(factionID, timePeriod) Library.factions.tables["Any"].units[timePeriod] = {} for k,_ in pairs(Library.factions.tables[factionID].units[timePeriod]) do Library.factions.tables["Any"].units[timePeriod][k] = Library.factions.tables["Any"].units[timePeriod][k] or {} for _,u in ipairs(Library.factions.tables[factionID].units[timePeriod][k]) do if not DCSEx.table.contains(Library.factions.tables["Any"].units[timePeriod][k], u) then table.insert(Library.factions.tables["Any"].units[timePeriod][k], u) end end end end for k,_ in pairs(Library.factions.tables) do if k ~= "Any" then for _,tp in pairs(DCSEx.enums.timePeriod) do copyUnitTableToAny(k, tp) end end end end -- do -- for k,_ in pairs(Library.factions.tables) do -- for _,tp in pairs(DCSEx.enums.timePeriod) do -- if not Library.factions.tables[k].units[tp] or #Library.factions.tables[k].units[tp] == 0 then -- -- end -- end -- end -- end -- If default red faction is "Russia" and "Russia" is named "USSR" in this time period, change its name in the default if Library.factions.tables["USSR"] and Library.factions.defaults[coalition.side.RED] == "Russia" then Library.factions.defaults[coalition.side.RED] = "USSR" end function Library.factions.getUnits(faction, unitFamilies, count, singleType) singleType = singleType or false local timePeriod = TUM.settings.getValue(TUM.settings.id.TIME_PERIOD) if not unitFamilies then return nil end if not Library.factions.tables[faction] then return nil end if not Library.factions.tables[faction].units then return nil end if not Library.factions.tables[faction].units[timePeriod] then return nil end if type(unitFamilies) == "number" then unitFamilies = { unitFamilies } end count = math.max(1, count or 1) local validUnits = {} for _,f in ipairs(unitFamilies) do local unitList = Library.factions.tables[faction].units[timePeriod][f] if unitList and #unitList > 0 then for __,u in ipairs(unitList) do if not DCSEx.table.contains(validUnits, u) then table.insert(validUnits, u) end end end end if #validUnits == 0 then return nil end local selectedUnits = {} if singleType then local unitType = DCSEx.table.getRandom(validUnits) for _=1,count do table.insert(selectedUnits, unitType) end else for _=1,count do table.insert(selectedUnits, DCSEx.table.getRandom(validUnits)) end end return selectedUnits end do -- local function mergeFactions() -- end -- local function setDefaultUnitsIfMissing(unitTypes, defaults) -- if not unitTypes or #unitTypes == 0 then -- return defaults -- end -- return unitTypes -- end -- for k,_ in pairs(Library.factions) do -- if not Library.factions[k][DCSEx.enums.unitFamily.SHIP_CARGO] = { "Dry-cargo ship-1", "Dry-cargo ship-2", "ELNYA", "Ship_Tilde_Supply" }, -- end end Library.groupTemplates = { } Library.groupTemplates["*HAWK"] = { { dx = 32.279602998366, dy = -40.996889924631, name = "Hawk sr", heading = 0 }, { dx = 0, dy = 0, name = "Hawk pcp", heading = 0 }, { dx = -34.076534003809, dy = 41.931256096927, name = "Hawk cwar", heading = 0 }, { dx = -73.507952767894, dy = -58.130136438762, name = "Hawk tr", heading = 3.8397243543875 }, { dx = -53.646780668367, dy = -135.33353399258, name = "Hawk ln", heading = 4.7123889803847 }, { dx = -137.08263885655, dy = -113.8479052746, name = "Hawk ln", heading = 3.8397243543875 }, { dx = -143.06468370894, dy = -28.566666166706, name = "Hawk ln", heading = 2.6179938779915 }, { dx = 71.695053443613, dy = 58.889218891971, name = "Hawk tr", heading = 0.69813170079773 }, { dx = 142.58862828931, dy = 26.52486901707, name = "Hawk ln", heading = 5.7595865315813 }, { dx = 139.59213643564, dy = 111.20097058237, name = "Hawk ln", heading = 0.69813170079773 }, { dx = 51.990893861743, dy = 137.17585691391, name = "Hawk ln", heading = 1.5707963267949 } } Library.groupTemplates["*NASAMS"] = { { dx = 0, dy = 0, name = "NASAMS_Command_Post", heading = 6.2765352930821 }, { dx = -14.042657040991, dy = 54.532318175887, name = "NASAMS_LN_B", heading = 2.3561944901923 }, { dx = 51.255698199675, dy = -5.1489742484409, name = "NASAMS_LN_B", heading = 6.2765352930821 }, { dx = 29.255535502103, dy = 55.936583879986, name = "NASAMS_LN_C", heading = 1.5707963267949 }, { dx = 21.063985561486, dy = 15.680967029068, name = "NASAMS_Radar_MPQ64F1", heading = 6.2765352930821 }, { dx = -18.499094251951, dy = -14.299637664692, name = "M 818", heading = 1.5707963267949 }, { dx = -7.042956299847, dy = -18.311686379602, name = "M 818", heading = 1.5707963267949 } } Library.groupTemplates["*Patriot"] = { { dx = 0, dy = 0, name = "Patriot str", heading = 0 }, { dx = -19.60004352557, dy = 9.2644465620397, name = "Patriot EPP", heading = 0 }, { dx = -35.248201985043, dy = -0.8707412587828, name = "Patriot ECS", heading = 0 }, { dx = -52.779034586449, dy = -20.804649357509, name = "Patriot AMG", heading = 4.7123889803847 }, { dx = -35.511640445024, dy = 16.23725082296, name = "Patriot cp", heading = 0 }, { dx = 136.71587389408, dy = -115.36026572896, name = "Patriot ln", heading = 5.9341194567807 }, { dx = 233.22284679177, dy = -169.50440608741, name = "Patriot ln", heading = 5.9341194567807 }, { dx = 302.6260036147, dy = -119.57223135463, name = "Patriot ln", heading = 0 }, { dx = 173.84730488189, dy = -29.940192911235, name = "Patriot ln", heading = 0 }, { dx = 287.4638047662, dy = 8.9459295797569, name = "Patriot ln", heading = 0 }, { dx = 101.78340133674, dy = 47.897296695373, name = "Patriot ln", heading = 0.3490658503988 }, { dx = 187.95200156058, dy = 104.06103102239, name = "Patriot ln", heading = 0.3490658503988 }, { dx = -31.67915746152, dy = 171.21775733319, name = "M1097 Avenger", heading = 5.9341194567807 }, { dx = 46.357670822879, dy = -267.34404672193, name = "M1097 Avenger", heading = 0 }, { dx = -68.129344288536, dy = -146.06991632772, name = "Hummer", heading = 5.9341194567807 }, { dx = -81.188374167279, dy = -130.70164152705, name = "Hummer", heading = 5.9341194567807 }, { dx = -95.083442423507, dy = -114.72675693111, name = "M978 HEMTT Tanker", heading = 5.9341194567807 }, { dx = -55.049316178425, dy = -162.07189504143, name = "M 818", heading = 5.9341194567807 }, { dx = 139.89969071567, dy = -62.41809110227, name = "M 818", heading = 5.9341194567807 }, { dx = -26.639011004663, dy = 25.619801495515, name = "M 818", heading = 1.5707963267949 } } Library.groupTemplates["*Rapier"] = { { dx = 0, dy = 0, name = "rapier_fsa_blindfire_radar", heading = 0.013157135472537 }, { dx = -14.178539628003, dy = 10.201632172, name = "rapier_fsa_optical_tracker_unit", heading = 3.1590459461097 }, { dx = -66.224154607, dy = 1.2103631389982, name = "rapier_fsa_launcher", heading = 0.017453292519943 }, { dx = -50.662342819996, dy = 58.961975773003, name = "rapier_fsa_launcher", heading = 5.7595865315813 }, { dx = -54.812159296009, dy = -56.368340474997, name = "rapier_fsa_launcher", heading = 0.80285145591739 }, { dx = 49.050959151995, dy = 45.906522844001, name = "Land_Rover_101_FC", heading = 4.1364303272266 }, { dx = 36.182838894005, dy = 58.774643101002, name = "Land_Rover_109_S3", heading = 4.1364303272266 }, { dx = 32.038867964002, dy = 61.828095365003, name = "Land_Rover_109_S3", heading = 4.1364303272266 }, { dx = 22.442303705, dy = 69.897933492997, name = "Land_Rover_109_S3", heading = 4.1364303272266 }, { dx = 52.758722615996, dy = 42.634966846002, name = "Land_Rover_101_FC", heading = 4.1364303272266 }, { dx = 39.890602357991, dy = 55.066879637001, name = "Land_Rover_101_FC", heading = 4.1364303272266 } } Library.groupTemplates["*SA-10"] = { { dx = 0.69314285699511, dy = 127.97571428004, name = "S-300PS 40B6MD sr", heading = 0 }, { dx = -22.516027817794, dy = 246.55467524601, name = "S-300PS 64H6E sr", heading = 3.1415926535898 }, { dx = 0, dy = 0, name = "S-300PS 40B6M tr", heading = 4.7123889803847 }, { dx = 23.579234991223, dy = 246.55467524601, name = "S-300PS 54K6 cp", heading = 3.1415926535898 }, { dx = 83.349983285123, dy = -1.3806866992963, name = "S-300PS 5P85C ln", heading = 3.1415926535898 }, { dx = 82.498640577192, dy = 16.104647497996, name = "S-300PS 5P85D ln", heading = 3.3161255787892 }, { dx = 82.547616217693, dy = -18.227276489837, name = "S-300PS 5P85D ln", heading = 2.9670597283904 }, { dx = -82.640406328603, dy = -0.41562629467808, name = "S-300PS 5P85C ln", heading = 0 }, { dx = -81.939684967569, dy = 17.115632734494, name = "S-300PS 5P85D ln", heading = 6.1086523819802 }, { dx = -81.939684967569, dy = -17.99454369233, name = "S-300PS 5P85D ln", heading = 0.17453292519943 }, { dx = -9.0858776818495, dy = 187.67713509151, name = "generator_5i57", heading = 1.5707963267949 }, { dx = 0.83760223048739, dy = 187.51811292395, name = "generator_5i57", heading = 1.5707963267949 }, { dx = -59.823818980018, dy = 168.63468487991, name = "ATZ-5", heading = 0 }, { dx = -59.823818980018, dy = 179.2654343833, name = "ATZ-5", heading = 0 }, { dx = 20.947679329896, dy = -62.811427216162, name = "GAZ-66", heading = 1.5707963267949 }, { dx = 66.751355714747, dy = 151.35592090525, name = "ATZ-60_Maz", heading = 3.9269908169872 }, { dx = 59.63926918729, dy = 158.46800743265, name = "ATZ-60_Maz", heading = 3.9269908169872 }, { dx = -16.327227612433, dy = -62.472874663305, name = "KAMAZ Truck", heading = 1.5707963267949 } } Library.groupTemplates["*SA-11"] = { { dx = 0, dy = 0, name = "SA-11 Buk SR 9S18M1", heading = 0 }, { dx = 2.6563550499995, dy = 100.877549925, name = "SA-11 Buk LN 9A310M1", heading = 4.7123889803847 }, { dx = -3.9905785699957, dy = -102.252741427, name = "SA-11 Buk LN 9A310M1", heading = 1.553343034275 }, { dx = -105.82160159, dy = 4.8958284879991, name = "SA-11 Buk LN 9A310M1", heading = 0.034906585039887 }, { dx = 99.169831179999, dy = -3.3463691979996, name = "SA-11 Buk LN 9A310M1", heading = 3.1415926535898 }, { dx = 129.64229952999, dy = -104.569064854, name = "ATZ-10", heading = 2.3212879051525 }, { dx = 120.44134814, dy = -112.000602515, name = "ATZ-10", heading = 2.4958208303519 }, { dx = 27.63662248, dy = 21.425097783998, name = "ZiL-131 APA-80", heading = 1.5882496193148 }, { dx = 42.172491459991, dy = -20.017069267, name = "Ural-4320-31", heading = 0.05235987755983 }, { dx = 42.172491459991, dy = -28.818736966998, name = "Ural-4320-31", heading = 0.034906585039887 }, { dx = 22.603219309996, dy = 21.425097783998, name = "Ural-375 PBU", heading = 1.5882496193148 }, { dx = -13.972843719996, dy = -17.667666831003, name = "SA-11 Buk CC 9S470M1", heading = 1.553343034275 } } Library.groupTemplates["*SA-12"] = { { dx = -2.7678518560006, dy = 65.945864259964, name = "S-300V 9S19 sr", heading = 0 }, { dx = 30.036823454, dy = 0.38328663993161, name = "S-300V 9S15 sr", heading = 0 }, { dx = 0, dy = 0, name = "S-300V 9S457 cp", heading = 0 }, { dx = -4.7906990489992, dy = 131.80077842996, name = "S-300V 9S32 tr", heading = 0 }, { dx = -25.033639470001, dy = 87.880609649932, name = "S-300V 9A83 ln", heading = 0 }, { dx = -24.414217594, dy = 73.324195559951, name = "S-300V 9A83 ln", heading = 0 }, { dx = -27.062572916, dy = 115.16459542001, name = "S-300V 9A83 ln", heading = 0 }, { dx = -27.415392823001, dy = 131.74713105999, name = "S-300V 9A83 ln", heading = 0 }, { dx = 56.555745099, dy = 43.894974149996, name = "S-300V 9A83 ln", heading = 0 }, { dx = 56.202925191001, dy = 62.947249140008, name = "S-300V 9A83 ln", heading = 0 }, { dx = 54.791645562, dy = 83.763623669976, name = "S-300V 9A83 ln", heading = 0 }, { dx = 46.323967789, dy = 115.87023522996, name = "S-300V 9A83 ln", heading = 0 }, { dx = 45.971147881, dy = 136.33378985, name = "S-300V 9A83 ln", heading = 0 }, { dx = 43.854228438, dy = 155.03324492997, name = "S-300V 9A83 ln", heading = 0 }, { dx = -19.300534956999, dy = 185.37575695, name = "S-300V 9A83 ln", heading = 0 }, { dx = 1.8686594770006, dy = 184.67011713993, name = "S-300V 9A83 ln", heading = 0 }, { dx = 26.918872890999, dy = 183.96447732998, name = "S-300V 9A83 ln", heading = 0 }, { dx = -27.768212731, dy = 148.68248660001, name = "S-300V 9A83 ln", heading = 0 }, { dx = -24.685397394, dy = 57.669850319973, name = "S-300V 9A83 ln", heading = 0 } } Library.groupTemplates["*SA-17"] = { { dx = 0, dy = 0, name = "SA-11 Buk SR 9S18M1", heading = 0 }, { dx = -2.65635505, dy = -100.87754992, name = "SA-17 Buk M1-2 LN 9A310M1-2", heading = 4.7123889803847 }, { dx = 3.9905785699998, dy = 102.25274143007, name = "SA-17 Buk M1-2 LN 9A310M1-2", heading = 1.553343034275 }, { dx = 105.82160159, dy = -4.8958284899127, name = "SA-17 Buk M1-2 LN 9A310M1-2", heading = 0.034906585039887 }, { dx = -99.16983118, dy = 3.3463692000369, name = "SA-17 Buk M1-2 LN 9A310M1-2", heading = 3.1415926535898 }, { dx = 13.97284372, dy = 17.667666830006, name = "SA-11 Buk CC 9S470M1", heading = 1.553343034275 } } Library.groupTemplates["*SA-2"] = { { dx = -61.142498229994, dy = 165.65584994, name = "p-19 s-125 sr", heading = 2.2165681500328 }, { dx = 0, dy = 0, name = "SNR_75V", heading = 0.0038885041518015 }, { dx = 79.099061770001, dy = -47.096697396999, name = "S_75M_Volhov", heading = 5.4803338512622 }, { dx = 0.21820687000582, dy = 106.800532487, name = "S_75M_Volhov", heading = 1.535889741755 }, { dx = -1.8276942699886, dy = -98.244225791997, name = "S_75M_Volhov", heading = 4.6774823953448 }, { dx = -85.254996139993, dy = -46.869375048002, name = "S_75M_Volhov", heading = 3.8048177693476 }, { dx = -87.755541969993, dy = 57.926227576005, name = "S_75M_Volhov", heading = 2.3561944901923 }, { dx = 80.690318210007, dy = 54.289070001003, name = "S_75M_Volhov", heading = 0.92502450355699 }, { dx = 29.956672100001, dy = 44.636165102005, name = "ZIL-131 KUNG", heading = 4.1713369122664 }, { dx = 25.126949860001, dy = 47.889142120999, name = "ZIL-131 KUNG", heading = 4.1713369122664 }, { dx = -49.941045745189, dy = 164.38476072691, name = "Ural-4320 APA-5D", heading = 0.68067840827779 }, { dx = -118.28563314999, dy = -171.162132111, name = "ATMZ-5", heading = 0.87266462599716 }, { dx = -137.35942972999, dy = -151.259040031, name = "ATMZ-5", heading = 1.0297442586767 }, { dx = -168.04336334999, dy = -84.915399762001, name = "Ural-4320T", heading = 5.4279739737024 }, { dx = -151.45745328999, dy = -70.817376204999, name = "Ural-4320T", heading = 5.3407075111026 } } Library.groupTemplates["*SA-20B"] = { { dx = 54.7553751285, dy = 2.4498900099425, name = "S-300PMU2 64H6E2 sr", heading = 0 }, { dx = 21.342219296499, dy = 115.70961456001, name = "S-300PMU1 40B6MD sr", heading = 0 }, { dx = 0, dy = 0, name = "S-300PMU2 54K6E2 cp", heading = 0 }, { dx = -26.435087682701, dy = 298.86609738995, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = -27.534276526401, dy = 263.14245996997, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 1.044633408299, dy = 343.93283998, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 23.578004703, dy = 343.38324555999, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 74.6902859324, dy = 295.01893644, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 78.537446885099, dy = 198.29031820002, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 80.186230150599, dy = 171.36019152997, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 76.3390691978, dy = 143.88047044002, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 73.0415026669, dy = 245.55543847999, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 73.0415026669, dy = 274.13434840995, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 49.4089425286, dy = 342.83365113998, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = -28.083870948201, dy = 235.11314446002, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = -26.435087682701, dy = 204.88545126002, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = -25.885493260901, dy = 178.50491900998, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = -25.335898839101, dy = 149.37641466002, name = "S-300PMU2 5P85SE2 ln", heading = 0 }, { dx = 18.035892917, dy = 247.96266972995, name = "S-300PMU2 92H6E tr", heading = 0 } } Library.groupTemplates["*SAM SA-23"] = { { dx = -1.2347728040004, dy = 110.10662005993, name = "S-300VM 9S19M2 sr", heading = 0 }, { dx = 70.4840989479, dy = -0.34044244000688, name = "S-300VM 9S15M2 sr", heading = 0 }, { dx = 0, dy = 0, name = "S-300VM 9S457ME cp", heading = 0 }, { dx = -5.5379051088003, dy = 263.58500561002, name = "S-300VM 9S32ME tr", heading = 0 }, { dx = -80.1369902307, dy = 214.60380041995, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = -54.833154493501, dy = 353.77489698003, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = -23.5045959615, dy = 354.97984153999, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = 16.8610467625, dy = 355.58231382002, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = 61.776132385099, dy = 286.38841469004, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = 81.403816244499, dy = 71.364295950043, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = 80.825083776699, dy = 104.35204660997, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = 79.6676188412, dy = 136.76106480998, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = 68.1271059684, dy = 206.20737319998, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = 62.570004083, dy = 245.10708640004, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = -88.5716021431, dy = 277.26091749, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = -84.354296186901, dy = 247.13730350998, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = -78.9320456717, dy = 75.432703869999, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = -79.534517951201, dy = 106.15879012004, name = "S-300VM 9A83ME ln", heading = 0 }, { dx = -81.643089840001, dy = 131.03149978002, name = "S-300VM 9A83ME ln", heading = 0 } } Library.groupTemplates["*SA-3"] = { { dx = 33.753619990006, dy = -73.286112753005, name = "p-19 s-125 sr", heading = 6.2641478001644 }, { dx = 0, dy = 0, name = "snr s-125 tr", heading = 6.2641478001644 }, { dx = -54.395544479994, dy = 20.411364487998, name = "5p73 s-125 ln", heading = 3.1590459461097 }, { dx = -55.65154957, dy = -15.115636602, name = "5p73 s-125 ln", heading = 3.1590459461097 }, { dx = -26.404573919994, dy = 38.533723629997, name = "5p73 s-125 ln", heading = 3.1590459461097 }, { dx = -28.378296209994, dy = -36.108864519003, name = "5p73 s-125 ln", heading = 3.1590459461097 }, { dx = -0.19719014999282, dy = 16.417675958997, name = "ZIL-131 KUNG", heading = 1.5707963267949 }, { dx = 6.6801895600074, dy = 13.694317328001, name = "ZiL-131 APA-80", heading = 3.1241393610699 }, { dx = 73.148097120007, dy = 24.177887045, name = "GAZ-66", heading = 1.6057029118348 }, { dx = 67.422903450002, dy = 24.220744209997, name = "GAZ-66", heading = 1.6406094968747 }, { dx = 62.727714700013, dy = 24.526952171, name = "GAZ-66", heading = 1.5707963267949 }, { dx = 39.803062310006, dy = -66.502451588, name = "ZiL-131 APA-80", heading = 1.6406094968747 } } Library.groupTemplates["*SA-5"] = { { dx = -21.700644880009, dy = 46.873392940033, name = "p-19 s-125 sr", heading = 0 }, { dx = 0, dy = 0, name = "RPC_5N62V", heading = 0 }, { dx = -22.568670669978, dy = -47.741418740014, name = "RLS_19J6", heading = 0 }, { dx = -53.291560299986, dy = -96.214918539976, name = "S-200_Launcher", heading = 0 }, { dx = -50.615134440013, dy = 96.785124419956, name = "S-200_Launcher", heading = 0 }, { dx = 37.9898636, dy = -128.44787637005, name = "S-200_Launcher", heading = 0 }, { dx = 42.272167960007, dy = 132.77268947999, name = "S-200_Launcher", heading = 0 }, { dx = 138.76056035003, dy = -94.454724150011, name = "S-200_Launcher", heading = 0 }, { dx = 136.79007635004, dy = 94.711739629973, name = "S-200_Launcher", heading = 0 }, { dx = 46.961911459395, dy = -62.291868640343, name = "Ural-375", heading = 5.4628805587423 }, { dx = 46.463913819985, dy = 64.697529679979, name = "Ural-375", heading = 0.78539816339745 }, { dx = 137.66849846969, dy = 0.55932146019768, name = "2S6 Tunguska", heading = 5.8643062867009 } } Library.groupTemplates["*SA-6"] = { { dx = 0, dy = 0, name = "Kub 1S91 str", heading = 0 }, { dx = 2.6563550499995, dy = 100.877549925, name = "Kub 2P25 ln", heading = 4.7123889803847 }, { dx = -3.9905785699957, dy = -102.252741427, name = "Kub 2P25 ln", heading = 1.553343034275 }, { dx = -105.82160159, dy = 4.8958284879991, name = "Kub 2P25 ln", heading = 0.034906585039887 }, { dx = 99.169831179999, dy = -3.3463691979996, name = "Kub 2P25 ln", heading = 3.1415926535898 }, { dx = 129.64229952999, dy = -104.569064854, name = "ATZ-10", heading = 2.3212879051525 }, { dx = 120.44134814, dy = -112.000602515, name = "ATZ-10", heading = 2.4958208303519 }, { dx = 25.605996860002, dy = 20.019633917, name = "ZiL-131 APA-80", heading = 1.5882496193148 }, { dx = 42.172491459991, dy = -20.017069267, name = "Ural-4320-31", heading = 0.05235987755983 }, { dx = 42.172491459991, dy = -28.818736966998, name = "Ural-4320-31", heading = 0.034906585039887 }, { dx = 22.038305519993, dy = 20.113878987999, name = "Ural-375 PBU", heading = 1.5882496193148 } } Library.objectNames = {} do local GROUP_PRIORITY = { -- lower in the list means higher priority "carrier", "submarine", "warship", "missile boat", "armed ship", "cargo ship", "speedboat", "ship", "interceptor", "fighter", "bomber", "AWACS", "tanker", "transport", "UAV", "aircraft", "attack helicopter", "transport helicopter", "helicopter", "IR SAM", "SHORAD", "AAA", "SAM tracking radar", "SAM search radar", "SAM launcher", "air defense", "artillery", "armor", "truck", "vehicle", "MANPADS", "infantry", "structure", "building", "unknown" } local namesTable = { ["1L13 EWR"] = "EWR 1L13", ["2B11 mortar"] = "Mortar 2B11 120mm", ["2S6 Tunguska"] = "SA-19 \"Tunguska\"", ["55G6 EWR"] = "EWR 55G6", ["5p73 s-125 ln"] = "SA-3 \"Goa\" launcher", ["A-10A"] = "A-10A", ["A-10C"] = "A-10C", ["A-10C_2"] = "A-10C", ["A-20G"] = "A-20G", ["A-50"] = "A-50", ["AA8"] = "fire truck", ["AAV7"] = "AAV-7", ["AH-1W"] = "AH-1W", ["AH-64A"] = "AH-64A", ["AH-64D"] = "AH-64D", ["AH-64D_BLK_II"] = "AH-64D", ["AJS37"] = "AJS37", ["ALBATROS"] = "Grisha-class corvette", ["Allies_Director"] = "Allies Rangefinder", ["An-26B"] = "An-26B", ["An-30M"] = "An-30M", ["ara_vdm"] = "Colossus-class aircraft carrier", ["atconveyor"] = "container ship", ["ATMZ-5"] = "ATMZ-5 fuel truck", ["ATZ-10"] = "ATZ-10 fuel truck", ["ATZ-5"] = "ATZ-5 fuel truck", ["ATZ-60_Maz"] = "ATZ-60 fuel truck", ["AV8BNA"] = "AV-8B", ["B-17G"] = "B-17G", ["B-1B"] = "B-1B", ["B-52H"] = "B-52H", ["B600_drivable"] = "B600 tug", ["BDK-775"] = "Ropucha-class landing ship", ["Bedford_MWD"] = "Bedford truck", ["Bf-109K-4"] = "Bf 109", ["Blitz_36-6700A"] = "Opel Blitz truck", ["BMD-1"] = "BMD-1 IFV", ["BMP-1"] = "BMP-1 IFV", ["BMP-2"] = "BMP-2 IFV", ["BMP-3"] = "BMP-3 IFV", ["bofors40"] = "Bofors 40mm AAA", ["Boxcartrinity"] = "Flatcar", ["BRDM-2"] = "BRDM-2 APC", ["BTR-80"] = "BTR-80 APC", ["BTR-82A"] = "BTR-82A IFV", ["BTR_D"] = "BTR-RD APC", ["Bunker"] = "Bunker", ["C-101CC"] = "C-101CC", ["C-101EB"] = "C-101EB", ["C-130"] = "C-130", ["C-17A"] = "C-17A", ["C-47"] = "C-47", ["CastleClass_01"] = "Castle-class ship", ["CCKW_353"] = "CCKW 353 truck", ["Centaur_IV"] = "Centaur IV tank", ["CH-47D"] = "CH-47D", ["CH-47Fbl1"] = "CH-47F", ["CH-53E"] = "CH-53E", ["Challenger2"] = "Challenger II MBT", ["Chieftain_mk3"] = "Chieftain tank", ["Christen Eagle II"] = "Christen Eagle II", ["Churchill_VII"] = "Churchill VII tank", ["Coach a passenger"] = "passenger car", ["Coach a platform"] = "coach", ["Coach a tank blue"] = "coach", ["Coach a tank yellow"] = "coach", ["Coach cargo open"] = "open wagon", ["Coach cargo"] = "freight van", ["Cobra"] = "Cobra APC", ["Cromwell_IV"] = "Cromwell tank", ["CV_1143_5"] = "Kuznetsov-class carrier", ["CVN_71"] = "Nimitz-class carrier", ["CVN_72"] = "Nimitz-class carrier", ["CVN_73"] = "Nimitz-class carrier", ["CVN_75"] = "Nimitz-class carrier", ["Daimler_AC"] = "Daimler armoured car", ["Dog Ear radar"] = "\"Dog Ear\" search radar", ["DR_50Ton_Flat_Wagon"] = "armored train wagon", ["DRG_Class_86"] = "armored locomotive", ["Dry-cargo ship-1"] = "cargo ship", ["Dry-cargo ship-2"] = "cargo ship", ["E-2C"] = "E-2D", ["E-3A"] = "E-3A", ["Electric locomotive"] = "locomotive", ["Elefant_SdKfz_184"] = "Jagdpanzer Elefant", ["ELNYA"] = "Altay-class oiler", ["ES44AH"] = "locomotive", ["Essex"] = "Essex-class carrier", ["F-117A"] = "F-117A", ["F-14A"] = "F-14A", ["F-14A-135-GR"] = "F-14A", ["F-14B"] = "F-14B", ["F-15C"] = "F-15C", ["F-15E"] = "F-15E", ["F-15ESE"] = "F-15E", ["F-16A MLU"] = "F-16A", ["F-16A"] = "F-16A", ["F-16C bl.50"] = "F-16C", ["F-16C bl.52d"] = "F-16C", ["F-16C_50"] = "F-16C", ["F-4E"] = "F-4E", ["F-4E-45MC"] = "F-4E", ["F-5E"] = "F-5E", ["F-5E-3"] = "F-5E", ["F-5E-3_FC"] = "F-5E", ["F-86F Sabre"] = "F-86F", ["F-86F_FC"] = "F-86F", ["F/A-18A"] = "F/A-18A", ["F/A-18C"] = "F/A-18C", ["F4U-1D"] = "F4U Corsair", ["F4U-1D_CW"] = "F4U Corsair", ["FA-18C_hornet"] = "F/A-18C", ["Falcon_Gyrocopter"] = "gyrocopter", ["fire_control"] = "Bunker with Fire Control Center", ["flak18"] = "Flak 18 AAA", ["flak30"] = "Flak 38 AAA", ["flak36"] = "Flak 36 AAA", ["flak37"] = "Flak 37 AAA", ["flak38"] = "Flak-Vierling 38 AAA", ["flak41"] = "Flak 41 AAA", ["Flakscheinwerfer_37"] = "Flakscheinwerfer 37", ["Forrestal"] = "Forrestal-class carrier", ["FPS-117 Dome"] = "FPS-117 radar dome", ["FPS-117 ECS"] = "FPS-117 search radar", ["FPS-117"] = "FPS-117 search radar", ["FuMG-401"] = "Freya radar", ["FuSe-65"] = "Würzburg radar", ["FW-190A8"] = "Fw 190", ["FW-190D9"] = "Fw 190", ["GAZ-3307"] = "GAZ-3307 truck", ["GAZ-3308"] = "GAZ-3308 truck", ["GAZ-66"] = "GAZ-66 truck", ["GD-20"] = "GD-20 lift truck", ["generator_5i57"] = "diesel power station", ["Gepard"] = "Flakpanzer Gepard", ["German_covered_wagon_G10"] = "covered wagon", ["German_tank_wagon"] = "tank wagon", ["Grad-URAL"] = "BM-21 Grad MLRS", ["Grad_FDDM"] = "BM-21 Grad fire direction data manager", ["H-6J"] = "H-6J", ["HandyWind"] = "bulker ship", ["HarborTug"] = "harbor tug", ["Hawk cwar"] = "Hawk SAM radar", ["Hawk ln"] = "Hawk SAM launcher", ["Hawk pcp"] = "Hawk SAM command post", ["Hawk sr"] = "Hawk SAM search radar", ["Hawk tr"] = "Hawk SAM tracker radar", ["Hawk"] = "Hawk", ["HEMTT TFFT"] = "HEMMT TFFT fire truck", ["HEMTT_C-RAM_Phalanx"] = "Centurion C-RAM", ["Higgins_boat"] = "Higgins landing craft", ["HL_B8M1"] = "MLRS on technical", ["HL_DSHK"] = "technical", ["HL_KORD"] = "technical", ["HL_ZU-23"] = "ZU-23 AAA on technical", ["hms_invincible"] = "Invincible-class aircraft carrier", ["Horch_901_typ_40_kfz_21"] = "Horch 901 car", ["house1arm"] = "barracks", ["house2arm"] = "watch tower", ["houseA_arm"] = "building", ["HQ-7_LN_P"] = "HQ-7 SHORAD", ["HQ-7_LN_SP"] = "HQ-7B SHORAD", ["HQ-7_STR_SP"] = "HQ-7B SHORAD search radar", ["Hummer"] = "Hummer", ["hy_launcher"] = "Silkworm missile", ["I-16"] = "I-16", ["Igla manpad INS"] = "MANPADS", ["IKARUS Bus"] = "IKARUS-280 bus", ["IL-76MD"] = "IL-76MD", ["IL-78M"] = "IL-78M", ["IMPROVED_KILO"] = "Kilo-class submarine", ["Infantry AK Ins"] = "infantry", ["Infantry AK ver2"] = "infantry", ["Infantry AK ver3"] = "infantry", ["Infantry AK"] = "infantry", ["J-11A"] = "J-11A", ["Jagdpanther_G1"] = "Jagdpanther", ["JagdPz_IV"] = "Jagdpanzer IV", ["JF-17"] = "JF-17", ["JTAC"] = "JTAC", ["Ju-88A4"] = "Junkers Ju 88", ["Ka-27"] = "Ka-27", ["Ka-50"] = "Ka-50", ["Ka-50_3"] = "Ka-50", ["KAMAZ Truck"] = "KAMAZ 43101 truck", ["KC-135"] = "KC-135", ["KC130"] = "KC-130", ["KC135MPRS"] = "KC-135MPRS", ["KDO_Mod40"] = "Kommandogerät 40 AAA radar", ["KILO"] = "Kilo-class submarine", ["KJ-2000"] = "KJ-2000", ["KrAZ6322"] = "KrAZ-6322 truck", ["KS-19"] = "KS-19 AAA", ["Kub 1S91 str"] = "SA-6 \"Kub\" radar", ["Kub 2P25 ln"] = "SA-6 \"Kub\" launcher", ["Kubelwagen_82"] = "Kübelwagen Jeep", ["KUZNECOW"] = "Kuznetsov-class carrier", ["L-39C"] = "L-39C", ["L-39ZA"] = "L-39ZA", ["L118_Unit"] = "L118 light gun", ["La_Combattante_II"] = "La Combattante-class missile boat", ["Land_Rover_101_FC"] = "Land Rover 101 truck", ["Land_Rover_109_S3"] = "Land Rover 109 truck", ["LARC-V"] = "LARC-V truck", ["LAV-25"] = "LAV-25 IFV", ["LAZ Bus"] = "LAZ-695 bus", ["leander-gun-achilles"] = "Leander-class frigate", ["leander-gun-andromeda"] = "Leander-class frigate", ["leander-gun-ariadne"] = "Leander-class frigate", ["leander-gun-condell"] = "Condell-class frigate", ["leander-gun-lynch"] = "Duke-class frigate", ["Leclerc"] = "Leclerc MBT", ["LeFH_18-40-105"] = "leFH 18 howitzer", ["Leopard-2"] = "Leopard 2 MBT", ["leopard-2A4"] = "Leopard 2 MBT", ["leopard-2A4_trs"] = "Leopard 2 MBT", ["Leopard-2A5"] = "Leopard 2 MBT", ["Leopard1A3"] = "Leopard MBT", ["LHA_Tarawa"] = "Tarawa-class landing ship", ["LiAZ Bus"] = "LiAZ-677 bus", ["Locomotive"] = "locomotive", ["LST_Mk2"] = "Landing Ship Tank", ["M 818"] = "M939 truck", ["M-1 Abrams"] = "M1 Abrams MBT", ["M-109"] = "M109 Paladin howitzer", ["M-113"] = "M113 APC", ["M-2 Bradley"] = "M2 Bradley IFV", ["M-2000C"] = "Mirage 2000C", ["M-60"] = "M60 Patton MBT", ["M1043 HMMWV Armament"] = "Humvee", ["M1045 HMMWV TOW"] = "Humvee", ["M1097 Avenger"] = "Avenger SAM", ["M10_GMC"] = "M10 tank destroyer", ["M1126 Stryker ICV"] = "Stryker IFV", ["M1128 Stryker MGS"] = "Stryker mobile gun", ["M1134 Stryker ATGM"] = "Stryker ATGM", ["M12_GMC"] = "M12 gun motor carriage", ["M1_37mm"] = "M1 37mm AAA", ["M1A2C_SEP_V3"] = "M1 Abrams MBT", ["M2A1-105"] = "M2A1 howitzer", ["M2A1_halftrack"] = "M2A1 half-track", ["M30_CC"] = "M30 cargo carrier", ["M45_Quadmount"] = "M45 quad mount AAA", ["M48 Chaparral"] = "M48 Chaparral SAM", ["M4_Sherman"] = "M4 Sherman tank", ["M4_Tractor"] = "M4 tractor", ["M4A4_Sherman_FF"] = "M4 Sherman tank", ["M6 Linebacker"] = "Linebacker SAM", ["M8_Greyhound"] = "M8 Greyhound scout", ["M978 HEMTT Tanker"] = "M978 HEMTT fuel truck", ["Marder"] = "Marder IFV", ["Maschinensatz_33"] = "generator", ["MaxxPro_MRAP"] = "MRAP MaxxPro APC", ["MAZ-6303"] = "MAZ-6303 truck", ["MB-339A"] = "MB-339A", ["MB-339APAN"] = "MB-339A", ["MCV-80"] = "FV510 Warrior IFV", ["Merkava_Mk4"] = "Merkava IV MBT", ["Mi-24P"] = "Mi-24P", ["Mi-24V"] = "Mi-24V", ["Mi-26"] = "Mi-26", ["Mi-28N"] = "Mi-28N", ["Mi-8MT"] = "Mi-8MT", ["MiG-15bis"] = "MiG-15bis", ["MiG-15bis_FC"] = "MiG-15bis", ["MiG-19P"] = "MiG-19P", ["MiG-21Bis"] = "MiG-21Bis", ["MiG-23MLD"] = "MiG-23MLD", ["MiG-25PD"] = "MiG-25PD", ["MiG-25RBT"] = "MiG-25RBT", ["MiG-27K"] = "MiG-27K", ["MiG-29A"] = "MiG-29A", ["MiG-29G"] = "MiG-29G", ["MiG-29S"] = "MiG-29S", ["MiG-31"] = "MiG-31", ["Mirage 2000-5"] = "Mirage 2000-5", ["Mirage-F1AD"] = "Mirage F1AD", ["Mirage-F1AZ"] = "Mirage F1AZ", ["Mirage-F1B"] = "Mirage F1B", ["Mirage-F1BD"] = "Mirage F1BD", ["Mirage-F1BE"] = "Mirage F1BE", ["Mirage-F1BQ"] = "Mirage F1BQ", ["Mirage-F1C"] = "Mirage F1C", ["Mirage-F1C-200"] = "Mirage F1C-200", ["Mirage-F1CE"] = "Mirage F1CE", ["Mirage-F1CG"] = "Mirage F1CG", ["Mirage-F1CH"] = "Mirage F1CH", ["Mirage-F1CJ"] = "Mirage F1CJ", ["Mirage-F1CK"] = "Mirage F1CK", ["Mirage-F1CR"] = "Mirage F1CR", ["Mirage-F1CT"] = "Mirage F1CT", ["Mirage-F1CZ"] = "Mirage F1CZ", ["Mirage-F1DDA"] = "Mirage F1DDA", ["Mirage-F1ED"] = "Mirage F1ED", ["Mirage-F1EDA"] = "Mirage F1EDA", ["Mirage-F1EE"] = "Mirage F1EE", ["Mirage-F1EH"] = "Mirage F1EH", ["Mirage-F1EQ"] = "Mirage F1EQ", ["Mirage-F1JA"] = "Mirage F1JA", ["Mirage-F1M-CE"] = "Mirage F1M", ["Mirage-F1M-EE"] = "Mirage F1M", ["MJ-1_drivable"] = "tug", ["MLRS FDDM"] = "Hummer", ["MLRS"] = "M270 MLRS", ["MOLNIYA"] = "Tarantul-class corvette", ["MOSCOW"] = "Slava-class cruiser", ["MosquitoFBMkVI"] = "DH.98 Mosquito", ["MQ-9 Reaper"] = "MQ-9 Reaper", ["MTLB"] = "MTLB APC", ["NASAMS_Command_Post"] = "NASAMS SAM CC", ["NASAMS_LN_B"] = "NASAMS SAM launcher", ["NASAMS_LN_C"] = "NASAMS SAM launcher", ["NASAMS_Radar_MPQ64F1"] = "NASAMS SAM search radar", ["NEUSTRASH"] = "Neustrashimy-class frigate", ["OH-58D"] = "OH-58D", ["OH58D"] = "OH-58D", ["Osa 9A33 ln"] = "SA-8 \"Gecko\"", ["outpost"] = "outpost", ["outpost_road"] = "outpost", ["outpost_road_l"] = "outpost", ["outpost_road_r"] = "outpost", ["p-19 s-125 sr"] = "\"Flat Face\" SAM search radar", ["P-47D-30"] = "P-47D", ["P-47D-30bl1"] = "P-47D", ["P-47D-40"] = "P-47D", ["P-51D"] = "P-51D", ["P-51D-30-NA"] = "P-51D", ["P20_drivable"] = "M92 truck", ["Pak40"] = "Pak40 antitank gun", ["Paratrooper AKS-74"] = "paratrooper", ["Paratrooper RPG-16"] = "paratrooper", ["Patriot AMG"] = "Patriot SAM antenna mast group", ["Patriot cp"] = "Patriot SAM command post", ["Patriot ECS"] = "Patriot SAM engagement control station", ["Patriot EPP"] = "Patriot SAM electric power plant", ["Patriot ln"] = "Patriot SAM launcher", ["Patriot str"] = "Patriot SAM search and tracking radar", ["PERRY"] = "Perry-class frigate", ["PIOTR"] = "Kirov-class battlecruiser", ["PL5EII Loadout"] = "PL-5EII missile", ["PL8 Loadout"] = "PL-8 missile", ["PLZ05"] = "PLZ-05 howitzer", ["Predator GCS"] = "Predator control station", ["Predator TrojanSpirit"] = "Predator control link", ["PT_76"] = "PT-76 light tank", ["Pz_IV_H"] = "Panzer IV tank", ["Pz_V_Panther_G"] = "Panzer V tank", ["QF_37_AA"] = "3.7-inch AA gun", ["r11_volvo_drivable"] = "truck", ["rapier_fsa_blindfire_radar"] = "Rapier SAM tracking radar", ["rapier_fsa_launcher"] = "Rapier SAM launcher", ["rapier_fsa_optical_tracker_unit"] = "Rapier SAM optical tracker", ["RD_75"] = "SA-2 \"Guideline\" rangefinder radar", ["REZKY"] = "Gnevny-class destroyer", ["RLS_19J6"] = "SA-5 \"Gammon\" search radar", ["Roland ADS"] = "Roland SAM", ["Roland Radar"] = "Roland SAM early-warning radar", ["RPC_5N62V"] = "SA-5 \"Gammon\" tracking radar", ["RQ-1A Predator"] = "MQ-1A Predator", ["S-200_Launcher"] = "SA-5 \"Gammon\" launcher", ["S-300PS 40B6M tr"] = "SA-10 (S-300) tracking radar", ["S-300PS 40B6MD sr"] = "SA-10 (S-300) search radar", ["S-300PS 40B6MD sr_19J6"] = "SA-10 (S-300) search radar", ["S-300PS 54K6 cp"] = "SA-10 (S-300) command post", ["S-300PS 5H63C 30H6_tr"] = "SA-10 (S-300) tracking radar", ["S-300PS 5P85C ln"] = "SA-10 (S-300) launcher", ["S-300PS 5P85D ln"] = "SA-10 (S-300) launcher", ["S-300PS 64H6E sr"] = "SA-10 (S-300) search radar", ["S-3B Tanker"] = "S-3B", ["S-3B"] = "S-3B", ["S-60_Type59_Artillery"] = "S-60 57mm AAA", ["S_75_ZIL"] = "S-75 truck", ["S_75M_Volhov"] = "SA-2 \"Guideline\" launcher", ["SA-11 Buk CC 9S470M1"] = "SA-11 \"Buk\" command post", ["SA-11 Buk LN 9A310M1"] = "SA-11 \"Buk\" launcher", ["SA-11 Buk SR 9S18M1"] = "SA-11 \"Buk\" search radar", ["SA-18 Igla comm"] = "MANPADS", ["SA-18 Igla manpad"] = "MANPADS", ["SA-18 Igla-S comm"] = "MANPADS", ["SA-18 Igla-S manpad"] = "MANPADS", ["SA342L"] = "SA342L", ["SA342M"] = "SA342M", ["SA342Minigun"] = "SA342", ["SA342Mistral"] = "SA342", ["Sandbox"] = "Bunker", ["santafe"] = "Balao-class submarine", ["SAU 2-C9"] = "2S9 Nona mortar", ["SAU Akatsia"] = "2S3 Akatsia howitzer", ["SAU Gvozdika"] = "2S1 Gvozdika howitzer", ["SAU Msta"] = "2S19 Msta howitzer", ["Schnellboot_type_S130"] = "Schnellboot S130", ["Scud_B"] = "SS-1 Scud missile", ["SD10 Loadout"] = "SD-10 missile", ["Sd_Kfz_2"] = "Kettenrad motorcycle", ["Sd_Kfz_234_2_Puma"] = "Sd.Kfz. 234 armoured car", ["Sd_Kfz_251"] = "Sd.Kfz.251 Halftrack", ["Sd_Kfz_7"] = "Sd.Kfz.7 tractor", ["Seawise_Giant"] = "bulk tanker", ["SH-3W"] = "SH-3W", ["SH-60B"] = "SH-60B", ["Ship_Tilde_Supply"] = "supply ship", ["Silkworm_SR"] = "Silkworm missile search radar", ["SK_C_28_naval_gun"] = "SK C/28 naval gun", ["SKP-11"] = "SKP-11 truck", ["Smerch"] = "BM-30 Smerch MLRS", ["Smerch_HE"] = "BM-30 Smerch MLRS", ["snr s-125 tr"] = "SA-3 \"Goa\" tracking radar", ["SNR_75V"] = "SA-2 \"Guideline\" tracking radar", ["Soldier AK"] = "infantry", ["Soldier M249"] = "infantry", ["Soldier M4 GRG"] = "infantry", ["Soldier M4"] = "infantry", ["Soldier RPG"] = "infantry", ["Soldier stinger"] = "MANPADS", ["soldier_mauser98"] = "infantry", ["soldier_wwii_br_01"] = "infantry", ["soldier_wwii_us"] = "infantry", ["SOM"] = "Tango-class submarine", ["SON_9"] = "SON-9 AAA radar", ["speedboat"] = "speedboat", ["SpGH_Dana"] = "Dana howitzer", ["SpitfireLFMkIX"] = "Spitfire", ["SpitfireLFMkIXCW"] = "Spitfire", ["Stennis"] = "Nimitz-class carrier", ["Stinger comm dsr"] = "MANPADS", ["Stinger comm"] = "MANPADS", ["Strela-1 9P31"] = "SA-9 \"Strela\" launcher", ["Strela-10M3"] = "SA-13 \"Gopher\" launcher", ["Stug_III"] = "Sturmgeschütz III assault gun", ["Stug_IV"] = "Sturmgeschütz IV assault gun", ["SturmPzIV"] = "Sturmpanzer heavy assault gun", ["Su-17M4"] = "Su-17M", ["Su-24M"] = "Su-24M", ["Su-24MR"] = "Su-24MR", ["Su-25"] = "Su-25", ["Su-25T"] = "Su-25T", ["Su-25TM"] = "Su-25TM", ["Su-27"] = "Su-27", ["Su-30"] = "Su-30", ["Su-33"] = "Su-33", ["Su-34"] = "Su-34", ["Suidae"] = "Suidae", -- TODO: what is this thing??? ["T-55"] = "T-55 MBT", ["T-72B"] = "T-72B MBT", ["T-72B3"] = "T-72B MBT", ["T-80UD"] = "T-80U MBT", ["T-90"] = "T-90 MBT", ["T155_Firtina"] = "T-155 Firtina howitzer", ["TACAN_beacon"] = "portable TACAN beacon", ["tacr2a"] = "fire truck", ["Tankcartrinity"] = "Cartrinity truck", ["Tetrarch"] = "Tetrach tank", ["TF-51D"] = "TF-51D", ["TICONDEROG"] = "Ticonderoga-class cruiser", ["Tiger_I"] = "Tiger I tank", ["Tiger_II_H"] = "Tiger II tank", ["Tigr_233036"] = "Tigr IFV", ["Tor 9A331"] = "SA-15 \"Tor\" launcher", ["Tornado GR4"] = "Tornado GR4", ["Tornado IDS"] = "Tornado IDS", ["TPZ"] = "Transportpanzer Fuchs APC", ["Trolley bus"] = "ZIU-9 trolleybus", ["tt_B8M1"] = "MLRS on technical", ["tt_DSHK"] = "technical", ["tt_KORD"] = "technical", ["tt_ZU-23"] = "ZU-23 AAA on technical", ["Tu-142"] = "Tu-142", ["Tu-160"] = "Tu-160", ["Tu-22M3"] = "Tu-22M3", ["Tu-95MS"] = "Tu-95MS", ["TugHarlan_drivable"] = "M92 tug", ["TYPE-59"] = "Type 59 MBT", ["Type_052B"] = "Type 052B destroyer", ["Type_052C"] = "Type 052C destroyer", ["Type_054A"] = "Type 054A frigate", ["Type_071"] = "Type 071 amphibious transport dock", ["Type_093"] = "Type 093 submarine", ["Type_3_80mm_AA"] = "Type 3 80mm Flak", ["Type_88_75mm_AA"] = "Type 88 Flak", ["Type_89_I_Go"] = "Type 89 I Go tank", ["Type_94_25mm_AA_Truck"] = "Type 94 AAA", ["Type_94_Truck"] = "Truck Type 94", ["Type_96_25mm_AA"] = "Type 96 25mm AAA", ["Type_98_Ke_Ni"] = "Type 98 Ke Ni tank", ["Type_98_So_Da"] = "Type 98 So Da APC", ["TZ-22_KrAZ"] = "TZ-22 fuel truck", ["UAZ-469"] = "UAZ-469 jeep", ["Uboat_VIIC"] = "VIIC U-boat", ["UH-1H"] = "UH-1H", ["UH-60A"] = "UH-60A", ["Uragan_BM-27"] = "BM-27 Uragan MLRS", ["Ural ATsP-6"] = "Ural ATsP-6 fire truck", ["Ural-375 PBU"] = "Ural-4320 truck", ["Ural-375 ZU-23 Insurgent"] = "ZU-23 AAA", ["Ural-375 ZU-23"] = "ZU-23 AAA", ["Ural-375"] = "Ural-4320 truck", ["Ural-4320 APA-5D"] = "Ural 4320 truck", ["Ural-4320-31"] = "Ural-4320 truck", ["Ural-4320T"] = "Ural-4320 truck", ["USS_Arleigh_Burke_IIa"] = "Arleigh Burke-class destroyer", ["USS_Samuel_Chase"] = "Arthur Middleton-class attack transport", ["v1_launcher"] = "V-1 launch ramp", ["VAB_Mephisto"] = "Mephisto tank hunter", ["VAZ Car"] = "car", ["VINSON"] = "CVN-70 Carl Vinson", ["Vulcan"] = "M163 Vulcan AAA", ["Wellcarnsc"] = "railroad car", ["Wespe124"] = "Sd.Kfz. 124 self propelled gun", ["Willys_MB"] = "Willys MB jeep", ["WingLoong-I"] = "WingLoong-I UAV", ["Yak-40"] = "Yak-40", ["Yak-52"] = "Yak-52", ["ZBD04A"] = "ZBD-04A IFV", ["ZiL-131 APA-80"] = "ZIL-131 truck", ["ZIL-131 KUNG"] = "ZIL-131 truck", ["ZIL-135"] = "ZIL-135 truck", ["ZIL-4331"] = "ZIL-4331 truck", ["ZSU-23-4 Shilka"] = "ZSU-23-4 AAA", ["ZSU_57_2"] = "ZSU-57-2 AAA", ["ZTZ96B"] = "Type 96B MBT", ["ZU-23 Closed Insurgent"] = "ZU-23 AAA emplacement", ["ZU-23 Emplacement Closed"] = "ZU-23 AAA emplacement", ["ZU-23 Emplacement"] = "ZU-23 AAA emplacement", ["ZU-23 Insurgent"] = "ZU-23 AAA emplacement", ["ZWEZDNY"] = "civilian boat" } function Library.objectNames.get(obj) if not obj then return "nothing" end -- First, try to find a custom name in the names table local typeName = obj:getTypeName() if typeName and namesTable[typeName] then return namesTable[typeName] end -- Else, try to find a display name in the description local desc = obj:getDesc() if desc and desc.DisplayName then return desc.DisplayName end -- If nothing else was found, return the internal typename if not typeName then return "unknown" end return typeName end function Library.objectNames.getGeneric(obj, imprecise) imprecise = imprecise or false if not obj then return "nothing" end if Object.getCategory(obj) == Object.Category.SCENERY then return DCSEx.table.getRandom({"building", "structure"}) elseif Object.getCategory(obj) == Object.Category.STATIC then return DCSEx.table.getRandom({"building", "structure"}) elseif Object.getCategory(obj) == Object.Category.UNIT then local objDesc = obj:getDesc() if objDesc.category == Unit.Category.AIRPLANE then if imprecise then return "aircraft" end if obj:hasAttribute("AWACS") then return "AWACS" elseif obj:hasAttribute("Tankers") then return "tanker" elseif obj:hasAttribute("Transports") then return "transport" elseif obj:hasAttribute("Bombers") then return "bomber" elseif obj:hasAttribute("Multirole fighters") or obj:hasAttribute("Fighters") then return "fighter" elseif obj:hasAttribute("Interceptors") then return "interceptor" elseif obj:hasAttribute("UAVs") then return "UAV" else return "aircraft" end elseif objDesc.category == Unit.Category.HELICOPTER then if imprecise then return "helicopter" end if obj:hasAttribute("Attack helicopters") then return "attack helicopter" elseif obj:hasAttribute("Transport helicopters") then return "transport helicopter" else return "helicopter" end elseif objDesc.category == Unit.Category.GROUND_UNIT then if imprecise then if obj:hasAttribute("Infantry") then return "infantry" else return "vehicle" end end if obj:hasAttribute("MANPADS") then return "MANPADS" elseif obj:hasAttribute("Infantry") then return "infantry" elseif obj:hasAttribute("IR Guided SAM") then return "IR SAM" elseif obj:hasAttribute("SR SAM") then return "SHORAD" elseif obj:hasAttribute("SAM SR") then return "SAM search radar" elseif obj:hasAttribute("SAM TR") then return "SAM tracking radar" elseif obj:hasAttribute("SAM LL") then return "SAM launcher" elseif obj:hasAttribute("AAA") then return "AAA" elseif obj:hasAttribute("Air Defence") then return "air defense" elseif obj:hasAttribute("Artillery") then return "artillery" elseif obj:hasAttribute("Armored vehicles") then return "armor" elseif obj:hasAttribute("Trucks") then return "truck" else return "vehicle" end elseif objDesc.category == Unit.Category.SHIP then if obj:getTypeName() == "speedboat" then return "speedboat" end if imprecise then return "ship" end if obj:hasAttribute("Submarines") then return "submarine" elseif obj:hasAttribute("Aircraft Carriers") then return "carrier" elseif obj:hasAttribute("Heavy armed ships") then return "warship" elseif obj:hasAttribute("Light armed ships") then if (TUM.settings.getValue(TUM.settings.id.TIME_PERIOD, DCSEx.enums.timePeriod.WORLD_WAR_2)) then return "armed ship" else return "missile boat" end elseif obj:hasAttribute("Unarmed ships") then return "cargo ship" else return "ship" end elseif objDesc.category == Unit.Category.STRUCTURE then return DCSEx.table.getRandom({"building", "structure"}) end end return "unknown" end function Library.objectNames.getGenericGroup(grp, imprecise) if not grp then return "nothing" end -- Establish a list of all unit names local unitNames = {} for _,u in ipairs(grp:getUnits()) do table.insert(unitNames, Library.objectNames.getGeneric(u, imprecise)) end if #unitNames == 0 then return "unknown" end -- Pick the unit name highest in priority local groupName = nil for _,n in ipairs(GROUP_PRIORITY) do if DCSEx.table.contains(unitNames, n) then groupName = n break end end if not groupName then return "unknown" end if groupName == "SAM search radar" or groupName == "SAM launcher" or groupName == "SAM tracking radar" then return "SAM element" end return groupName end end Library.objectiveNames = {} do local nextIndex = 0 -- Shuffle table order so the same names won't always come first local names = DCSEx.table.shuffle({ "Abenaki", "Abide", "Ablow", "Abnormal", "Abrum", "Abstain", "Abyss", "Accountant", "Accura", "Aces", "Acker", "Acme", "Acrobat", "Active", "Acton", "Adin", "Adios", "Adobe", "Adorn", "Aegis", "Aero", "Aeromet", "Afton", "Agar", "Agile", "Agio", "Agony", "Ahab", "Airevac", "Airgun", "Airport", "Akela", "Aksarben", "Akula", "Alabama", "Alamo", "Albert", "Alder", "Alfa", "Alga", "Alger", "Algum", "Alkyd", "Alley", "Alleycat", "Allied", "Alloy", "Almighty", "Almug", "Alouette", "Alta", "Alva", "Ambush", "Ame", "Amino", "Amiri", "Ammo", "Amor", "Ampex", "Amt", "Amway", "Anderson", "Andrews", "Andy", "Angel", "Angle", "Angry", "Animal", "Anita", "Anker", "Ankle", "Antar", "Antic", "Antler", "Anvis", "Anzac", "Apache", "Ape", "Apex", "April", "Aprt", "Arby", "Archer", "Architect", "Arctic", "Area", "Argus", "Aria", "Aris", "Ark", "Armor", "Army", "Arnold", "Arris", "Arrow", "Arter", "Artly", "Ascot", "Ash", "Asher", "Aspen", "Assault", "Assoc", "Astor", "Astra", "Astro", "Atari", "Atilla", "Atlas", "Atoka", "Atomic", "Attack", "Auggie", "Aussie", "Austin", "Auto", "Avalanche", "Avalon", "Avenging", "Avro", "Awoke", "Axe", "Axis", "Babs", "Backspin", "Backstop", "Backy", "Bacon", "Bader", "Baf", "Baffin", "Baffle", "Bahrain", "Baja", "Balky", "Ball", "Bam", "Bama", "Bambo", "Bandage", "Bandit", "Bandsaw", "Bandwagon", "Bane", "Bang", "Banger", "Bangor", "Banjo", "Bank", "Banks", "Banshee", "Banter", "Banyan", "Banzi", "Barb", "Barba", "Barbaric", "Bard", "Bark", "Barley", "Barn", "Barney", "Baron", "Barracuda", "Barranquilla", "Barrel", "Barrier", "Bart", "Basco", "Based", "Basher", "Bastard", "Bat", "Bat", "Batman", "Baton", "Bats", "Batter", "Battle", "Battlecat", "Battlestar", "Bay", "Bayhi", "Bayside", "Baywatch", "Bazoo", "Beach", "Beachball", "Beak", "Beamer", "Bear", "Bears", "Beast", "Beaver", "Beavis", "Bec", "Beef", "Beehive", "Beeliner", "Beer", "Beermat", "Beetle", "Bema", "Bender", "Bengal", "Berry", "Berta", "Berth", "Best", "Beta", "Beth", "Betsy", "Bicep", "Biddy", "Big", "Bigfoot", "Bigget", "Biker", "Bilk", "Billfish", "Billo", "Biloxi", "Binal", "Binder", "Birch", "Bird", "Birth", "Bison", "Bixby", "Black", "Blackbird", "Blackheart", "Blackjack", "Blacksheep", "Blacksmith", "Blade", "Blademan", "Blaster", "Blay", "Blaze", "Blazer", "Bleed", "Blob", "Bloke", "Blond", "Bloodhound", "Blower", "Blown", "Blue", "Blues", "Blurb", "Bluto", "Boat", "Bobby", "Bobcat", "Bode", "Bogey", "Bogue", "Bola", "Bolar", "Bold", "Boles", "Bolling", "Bolt", "Boma", "Bomar", "Bomber", "Bona", "Bone", "Bones", "Bonnie", "Bonno", "Bonsi", "Book", "Bookie", "Bookshelf", "Boom", "Boomer", "Boot", "Borage", "Borer", "Borg", "Boron", "Bosco", "Bosen", "Bosox", "Boxcar", "Boxer", "Bozz", "Brady", "Brag", "Brandywine", "Brass", "Brat", "Brave", "Bravo", "Bray", "Brem", "Brevet", "Brew", "Brewer", "Brice", "Brick", "Brickston", "Brickwall", "Brickyard", "Brigg", "Brigham", "Briney", "Bristol", "Broadway", "Brochure", "Brock", "Broke", "Bronco", "Bronk", "Broody", "Brook", "Broom", "Brs", "Brutis", "Bucanero", "Buck", "Buckeye", "Buckshot", "Bud", "Buddha", "Buddy", "Budman", "Buff", "Buffoon", "Buggy", "Bugsy", "Build", "Bulb", "Bull", "Bulldog", "Bullet", "Bullfrog", "Bullit", "Bullseye", "Bully", "Bumpy", "Bunk", "Burger", "Burglar", "Burma", "Burner", "Burning", "Burr", "Bursa", "Burt", "Busch", "Bushmaster", "Bust", "Buster", "Butch", "Butler", "Buzz", "Buzzard", "Buzzsaw", "Buzzy", "Bylaw", "Cabal", "Cabin", "Cacti", "Cactus", "Caddo", "Caddy", "Cade", "Cadon", "Caesar", "Caeser", "Cafe", "Cagey", "Cajun", "Call", "Calumet", "Calvin", "Cam", "Camay", "Camel", "Camelback", "Camelot", "Camera", "Campo", "Camslant", "Camspac", "Cando", "Candor", "Canforce", "Canine", "Cannon", "Canoe", "Canuck", "Canvas", "Canyon", "Cap", "Cape", "Capital", "Capitole", "Capon", "Capra", "Caprock", "Caps", "Capstone", "Carbon", "Carbonate", "Cardfile", "Caribbean", "Carly", "Carmen", "Carny", "Carp", "Carpet", "Carr", "Carson", "Carty", "Case", "Casey", "Cash", "Casino", "Casio", "Casket", "Cass", "Castro", "Cat", "Catbird", "Catfish", "Catman", "Cats", "Cauldron", "Cave", "Cecil", "Cedar", "Cee", "Cef", "Ceman", "Cfe", "Cgwb", "Chain", "Chalice", "Challenger", "Champ", "Chapps", "Chaps", "Charger", "Charlie", "Charter", "Chartroom", "Chaser", "Chastise", "Check", "Checker", "Checkerboard", "Checkmate", "Cheetah", "Cheetahs", "Chemo", "Chena", "Cherokee", "Chesda", "Chestaid", "Chesty", "Cheta", "Cheth", "Chico", "Chief", "Chiefs", "Chili", "Chill", "Chime", "Chippy", "Chisel", "Chisum", "Chock", "Chocks", "Chosen", "Chris", "Chrome", "Chuck", "Chug", "Chuggs", "Chump", "Church", "Cindy", "Circus", "Cisco", "City", "Clam", "Clan", "Claw", "Clean", "Clearwater", "Cleat", "Cletus", "Climax", "Clog", "Clop", "Closeout", "Clover", "Clown", "Club", "Clubleaf", "Cluck", "Clue", "Cluny", "Cnatra", "Coach", "Coast", "Coastguard", "Cobalt", "Cobb", "Cobby", "Cobra", "Cochise", "Cock", "Coco", "Cod", "Coda", "Coder", "Cody", "Coffee", "Coffin", "Coho", "Coil", "Coke", "Colby", "Cold", "Coma", "Combat", "Combo", "Comer", "Comfy", "Commando", "Comnmand", "Comseron", "Conan", "Conda", "Condo", "Condor", "Cone", "Conform", "Congo", "Conic", "Convict", "Convoy", "Cool", "Coop", "Coors", "Cope", "Copper", "Copyright", "Coral", "Cord", "Cornhusker", "Corona", "Corso", "Corvette", "Cosmic", "Cosmo", "Coso", "Costly", "Cotam", "Cougar", "Count", "Courage", "Courageous", "Covert", "Covet", "Cowboy", "Coyote", "Craft", "Crate", "Craze", "Crazy", "Crazyhorse", "Creole", "Crest", "Cricjet", "Crisco", "Crisp", "Crooked", "Crossbow", "Crow", "Crown", "Crud", "Crumb", "Crumpet", "Crystal", "Cub", "Cuban", "Cube", "Cuda", "Cuervo", "Cufmy", "Cujo", "Culdrose", "Cult", "Cummins", "Cuppy", "Cure", "Cushion", "Cushy", "Custer", "Cutlass", "Cutthroat", "Cutty", "Cyborg", "Cyclone", "Cylon", "Cynic", "Czech", "Dabba", "Dactyl", "Dae", "Dagda", "Dagger", "Dago", "Dagon", "Dagrat", "Daily", "Dakota", "Dallas", "Dally", "Dame", "Damon", "Danda", "Dander", "Danno", "Dantic", "Dapper", "Dare", "Dark", "Dart", "Darth", "Datsun", "Datum", "Davey", "Dawg", "Dazzle", "Dea", "Deadeye", "Deadly", "Dealer", "Death", "Deck", "Decoy", "Dee", "Deecee", "Deep", "Deer", "Deerlodge", "Defender", "Defiant", "Deft", "Defy", "Delco", "Deliverance", "Delta", "Delve", "Demo", "Demonstration", "Demus", "Denali", "Deployments", "Derby", "Derma", "Derrick", "Desert", "Destroyer", "Detone", "Detroit", "Deuce", "Devil", "Devo", "Devon", "Dewey", "Diamond", "Diamondback", "Dice", "Dicey", "Dido", "Dill", "Dillon", "Dime", "Dinar", "Dino", "Dipper", "Dirca", "Dirk", "Dirt", "Dirty", "Disco", "Ditto", "Ditty", "Dive", "Dixie", "Dobby", "Dog", "Doggy", "Dollar", "Domino", "Dong", "Donna", "Doom", "Doubleshot", "Doud", "Doughboy", "Down", "Downfall", "Downy", "Dozer", "Draco", "Drag", "Dragnet", "Dragon", "Dragonfire", "Dragonfish", "Dread", "Dreamland", "Drop", "Dropkick", "Dross", "Drum", "Dryden", "Dryer", "Dubai", "Duce", "Duck", "Dude", "Duece", "Duff", "Duke", "Dunmore", "Dupe", "Duple", "Duster", "Dusty", "Dutch", "Eagle", "Earl", "Earthquake", "Easy", "Eathen", "Ecles", "Eddie", "Edgar", "Edge", "Edgy", "Egyptian", "Elcid", "Elgin", "Elton", "Elvan", "Elvis", "Emerald", "Emergency", "Emmet", "Empire", "Energy", "Enjep", "Entry", "Epic", "Epoxy", "Eskan", "Essex", "Esso", "Ethyl", "Eureka", "Eva", "Evac", "Evade", "Evader", "Even", "Event", "Evil", "Executive", "Exile", "Expert", "Expo", "Express", "Extender", "Exude", "Exult", "Exxon", "Faf", "Fagin", "Fail", "Falco", "Falcon", "Falls", "Fame", "Fang", "Fango", "Fangs", "Fantop", "Farad", "Farmer", "Farout", "Farva", "Fast", "Fatly", "Fault", "Faze", "Fazer", "Felix", "Femur", "Fend", "Fendy", "Fenny", "Fetch", "Feud", "Fever", "Fewer", "Fiber", "Fiddle", "Fido", "Fiend", "Fighting", "Filo", "Finder", "Firebird", "Firebrand", "Firehawk", "Firewood", "Firm", "First", "Fisher", "Fist", "Fitch", "Fixer", "Flag", "Flanker", "Flash", "Fleagle", "Flint", "Flite", "Florida", "Floss", "Flout", "Floyd", "Flug", "Fluky", "Flume", "Flush", "Flyer", "Flynet", "Fmn", "Fnf", "Fny", "Fog", "Foghorn", "Foil", "Folic", "Fong", "Font", "Food", "Foray", "Force", "Forces", "Forks", "Fosdick", "Foss", "Foul", "Found", "Fourney", "Fox", "Foxxy", "Foxy", "Frag", "Frank", "Frate", "Fray", "Freak", "Fred", "Freddy", "Free", "Freebie", "Freedom", "Freemason", "Freight", "Fresca", "Fried", "From", "Frontline", "Frosty", "Fujin", "Full", "Fullcard", "Fungo", "Funny", "Furor", "Furr", "Furry", "Fury", "Fuss", "Fuzzy", "Gadget", "Gaf", "Gage", "Gain", "Gainer", "Galaxy", "Gale", "Gam", "Gamble", "Gambler", "Gamma", "Gander", "Gangster", "Gannetprestwick", "Gantsec", "Garby", "Garth", "Garuda", "Gaslight", "Gaspipe", "Gasser", "Gassy", "Gate", "Gator", "Gators", "Gaucho", "Gawky", "Geld", "Gelt", "Genus", "George", "Georgia", "Geronimo", "Getup", "Geyser", "Ghost", "Giant", "Gilly", "Ginger", "Ginzu", "Gipper", "Gitmo", "Glass", "Glida", "Global", "Glory", "Gnarly", "Goal", "Goat", "Goatee", "Gobo", "Golan", "Gold", "Golden", "Golf", "Golly", "Gomer", "Gondola", "Gonzo", "Goodwrench", "Goody", "Goofy", "Goose", "Gopher", "Goral", "Gordo", "Gordon", "Gourd", "Goya", "Graceland", "Grady", "Grand", "Grant", "Grasslands", "Gray", "Greasy", "Green", "Greg", "Gremlin", "Griffin", "Grits", "Gritty", "Grizzly", "Groat", "Grouch", "Ground", "Grout", "Growl", "Grown", "Grub", "Gruman", "Grumman", "Grump", "Grumpy", "Grunt", "Grup", "Gucci", "Guda", "Guilder", "Guiness", "Gull", "Gumby", "Gun", "Gundog", "Gunfighter", "Gunman", "Gunner", "Gunny", "Gunrunner", "Gunsmoke", "Gunstar", "Guntrain", "Guss", "Guts", "Gypsy", "Habitat", "Haf", "Haggar", "Hail", "Haiti", "Hake", "Hal", "Hale", "Halibut", "Hall", "Hambone", "Hammer", "Hampshire", "Hangover", "Hank", "Hanscom", "Happy", "Harass", "Hard", "Hardball", "Hardy", "Harley", "Harm", "Harmo", "Hart", "Hassle", "Hat", "Hatch", "Hatman", "Haven", "Havoc", "Hawk", "Hawkeye", "Hawks", "Hazard", "Haze", "Hazzard", "Head", "Headcap", "Heat", "Hefty", "Heinz", "Helix", "Hell", "Hellion", "Hempy", "Hen", "Hendo", "Henry", "Herc", "Herky", "Herma", "Hershey", "Hewit", "Hewy", "Hexad", "High", "Hike", "Hilda", "Hill", "Hind", "Hippo", "Hippy", "Hiram", "Hire", "Hitman", "Hoax", "Hobby", "Hobie", "Hobo", "Hocus", "Hog", "Hogger", "Hoist", "Hoku", "Hole", "Homeplate", "Homer", "Honk", "Honor", "Hook", "Hooper", "Hoosier", "Hooter", "Hoover", "Hope", "Hops", "Hornet", "Horse", "Horseman", "Hoser", "Hoss", "Hot", "Hotdog", "Hotlips", "Hound", "Howdy", "Howel", "Howl", "Hudson", "Hue", "Huge", "Huggy", "Hugo", "Hula", "Hulk", "Hummer", "Hungry", "Hunt", "Hunter", "Huntress", "Hura", "Hurc", "Hurds", "Hurky", "Hurly", "Huron", "Hurricane", "Husk", "Husker", "Husky", "Hustler", "Hydra", "Hydramatic", "Hydro", "Hymn", "Hyper", "Hypo", "Iceman", "Icer", "Idaho", "Idler", "Idol", "Igloo", "Iguana", "Ilka", "Image", "Impact", "Impy", "Indian", "Indy", "Info", "Instigator", "Intac", "Into", "Invader", "Ionic", "Ions", "Iota", "Iowa", "Iraqouis", "Irate", "Irish", "Iron", "Ironcrow", "Ironrod", "Irony", "Island", "Islands", "Ivan", "Ivanhoe", "Ivory", "Izod", "Jabba", "Jackal", "Jackdaw", "Jackpot", "Jaded", "Jagger", "Jaguar", "Jakal", "Jake", "Jalopy", "Jama", "Jambo", "Jamie", "Jammer", "Janus", "Jape", "Jarem", "Jason", "Jasper", "Java", "Jaws", "Jax", "Jaygo", "Jazz", "Jeckyl", "Jedi", "Jeep", "Jefferson", "Jena", "Jenny", "Jersey", "Jesse", "Jest", "Jester", "Jet", "Jethro", "Jiggs", "Jigsaw", "Jimbo", "Jinx", "Jive", "Jln", "Jockey", "Jody", "John", "Jojo", "Joke", "Joker", "Jolly", "Jonas", "Jordanian", "Josa", "Jose", "Joshua", "Joss", "Joyce", "Jstars", "Juba", "Judge", "Judgement", "Jug", "Juggle", "Juggs", "Juice", "Juicy", "Juliett", "Jumbo", "Jump", "Jungle", "Junior", "Junk", "Junker", "Jury", "Just", "Justice", "Juvat", "Kahona", "Kale", "Kang", "Kanza", "Kaput", "Karma", "Kate", "Kato", "Katt", "Kava", "Kayak", "Kaycee", "Kayo", "Keep", "Kelp", "Kelt", "Kemp", "Kennard", "Ketch", "Kevlar", "Keys", "Keystone", "Kharma", "Kick", "Killer", "Kin", "Kinky", "Kiowa", "Kirby", "Kirt", "Kiska", "Kite", "Kitsap", "Kitty", "Kittyhawk", "Kiwi", "Kleenex", "Knife", "Knight", "Knighthawk", "Knightrider", "Knot", "Known", "Koala", "Kokomo", "Kong", "Koo", "Krupa", "Kuwaiti", "Lactose", "Ladon", "Lag", "Laity", "Laker", "Lame", "Lance", "Lancer", "Land", "Lando", "Landslide", "Lang", "Larado", "Largo", "Lark", "Larma", "Larsen", "Larva", "Launches", "Lava", "Leaf", "Lee", "Legal", "Lehi", "Leica", "Lemay", "Lenna", "Leopard", "Leroy", "Lester", "Lethal", "Levi", "Lexus", "Libby", "Liberty", "Lido", "Life", "Lifter", "Light", "Lightning", "Lily", "Lima", "Lime", "Lined", "Liner", "Lion", "Lippo", "Lips", "Lisa", "Lite", "Litz", "Live", "Lloyd", "Lobby", "Lobo", "Lolly", "Loma", "Lone", "Loner", "Long", "Longhorn", "Lonny", "Look", "Lookout", "Loon", "Loop", "Loosefoot", "Loper", "Lotto", "Loud", "Louie", "Lout", "Lubo", "Lucid", "Lucky", "Lugo", "Lulu", "Lump", "Lumper", "Luna", "Lunar", "Lundy", "Lusk", "Lusty", "Luzon", "Lyneham", "Lynx", "Mac", "Mace", "Mach", "Macho", "Mack", "Mad", "Madras", "Maf", "Maffs", "Mafia", "Magas", "Magnet", "Magni", "Magnum", "Magoo", "Magpie", "Mai", "Mailtruck", "Maine", "Mainiac", "Mainsail", "Majan", "Makin", "Mako", "Mala", "Malan", "Male", "Malibu", "Mallard", "Malty", "Mamba", "Mango", "Maniac", "Manta", "Maple", "Maplecat", "Marathon", "Marcotte", "Marine", "Mariner", "Mark", "Marlin", "Mars", "Marshall", "Marta", "Mash", "Mast", "Mastadon", "Matador", "Matcom", "Math", "Matra", "Matt", "Maul", "Maverick", "Maxie", "May", "Mayo", "Mazda", "Mcasca", "Mcguire", "Meat", "Medellin", "Medevac", "Medusa", "Mega", "Melba", "Meld", "Mellow", "Melon", "Melrose", "Mercury", "Merl", "Mesquite", "Metal", "Meteor", "Metman", "Mexican", "Mexico", "Miami", "Mic", "Micah", "Micro", "Midas", "Middle", "Mig", "Mike", "Miler", "Milestone", "Milky", "Mill", "Miller", "Mime", "Mind", "Mine", "Ming", "Mingo", "Miniature", "Mint", "Minty", "Minuteman", "Misfit", "Missionary", "Mississippi", "Misty", "Mite", "Mobile", "Moccasin", "Mock", "Moffett", "Mogul", "Mohawk", "Moho", "Mojo", "Molly", "Molson", "Monarch", "Money", "Mongoose", "Monster", "Monty", "Monu", "Mooch", "Moody", "Mookie", "Moola", "Moon", "Moonlight", "Moor", "Moose", "Mop", "Mope", "Moped", "More", "Morning", "Mosel", "Motel", "Mother", "Motif", "Motley", "Motown", "Mould", "Mouse", "Mover", "Moxie", "Mozam", "Mua", "Mud", "Mudbug", "Muddy", "Muff", "Mugger", "Muif", "Mull", "Mullett", "Mung", "Murk", "Murky", "Muroc", "Museum", "Mushroom", "Music", "Musket", "Mussel", "Mustang", "Mystic", "Nabob", "Nacho", "Naf", "Nail", "Nalo", "Nancy", "Nanno", "Napper", "Nappy", "Narly", "Narragansett", "Nasa", "Nascar", "Nasty", "Nat", "Nathe", "National", "Nato", "Natro", "Navel", "Navy", "Nawt", "Nears", "Neptune", "Nest", "Nevin", "Newly", "Newport", "Newsreel", "Nickel", "Nigerian", "Nighthawk", "Nightmare", "Nightstaker", "Nightstalker", "Nightwatch", "Nimrod", "Ninja", "Niobe", "Niter", "Nitro", "Noah", "Noble", "Nodak", "Node", "Nomad", "Nomex", "Noose", "North", "Northern", "Norwegian", "Noster", "Note", "Nova", "Novar", "Now", "Nucar", "Nuke", "Numa", "Oak", "Oaky", "Occult", "Ocean", "Oceanside", "Odin", "Ogre", "Ohio", "Oiler", "Oilgate", "Oilwell", "Okie", "Okra", "Old", "Olds", "Olive", "Olmis", "Olson", "Olympic", "Omaha", "Omar", "Omega", "Omen", "Omni", "Ontario", "Onyx", "Opbat", "Opec", "Open", "Operations", "Opus", "Orbit", "Orca", "Orkin", "Osage", "Otis", "Outdo", "Outgun", "Outlaw", "Outrider", "Ouzo", "Overwork", "Ox", "Oxen", "Ozark", "Pacaf", "Paccaf", "Pacer", "Pack", "Packer", "Packers", "Pacom", "Pagan", "Pageboy", "Pago", "Pagus", "Pale", "Palm", "Palmetto", "Pan", "Panama", "Pansy", "Panton", "Pants", "Paola", "Para", "Paradise", "Pard", "Pardo", "Parrot", "Parry", "Part", "Party", "Pash", "Pasha", "Password", "Pat", "Patch", "Pathfinder", "Patio", "Patlo", "Patsy", "Patty", "Patuxent", "Pave", "Pax", "Payday", "Peace", "Peach", "Peak", "Pearl", "Pecos", "Pedro", "Peewee", "Pela", "Pelican", "Pelt", "Pence", "Penguin", "Penn", "Penny", "Pepsi", "Perco", "Percy", "Perk", "Perm", "Perma", "Pesky", "Pete", "Petit", "Petro", "Phantom", "Phaser", "Philander", "Phobia", "Phoenix", "Phony", "Photon", "Pickup", "Pike", "Pikeside", "Pilgrim", "Pilot", "Pinball", "Ping", "Pinion", "Pinto", "Pirate", "Pistol", "Piston", "Pit", "Pitbull", "Pitman", "Pitstop", "Pitt", "Pitts", "Pity", "Pixie", "Pizza", "Plantation", "Plasma", "Plate", "Plead", "Plf", "Plod", "Plow", "Plug", "Plush", "Pluto", "Poison", "Poke", "Poker", "Polar", "Pole", "Polecat", "Polet", "Polly", "Polo", "Pook", "Poppy", "Poppya", "Pork", "Port", "Posey", "Possum", "Potus", "Pounce", "Power", "Predator", "Presidential", "Pride", "Prime", "Primetime", "Primo", "Pro", "Prody", "Prong", "Props", "Prose", "Proton", "Proud", "Provo", "Prowl", "Psycho", "Public", "Pucallpa", "Puerto", "Puff", "Puget", "Pull", "Pulsar", "Puma", "Pure", "Push", "Pusher", "Putt", "Pyote", "Pyramid", "Pyrex", "Python", "Quail", "Quake", "Quarterback", "Quarterdeck", "Quartet", "Quasar", "Quebec", "Queen", "Quest", "Quick", "Quid", "Quote", "Rabble", "Rac", "Race", "Racer", "Rack", "Rafair", "Rage", "Ragin", "Rags", "Ragu", "Raid", "Raider", "Rail", "Rain", "Rainbow", "Rainy", "Raleigh", "Ralph", "Ram", "Rama", "Rambo", "Rampage", "Rampart", "Ramrod", "Ranch", "Rancho", "Rancid", "Randy", "Ranger", "Rank", "Rapid", "Raptor", "Rasca", "Rascal", "Raspberry", "Raster", "Rat", "Ratch", "Rats", "Rattler", "Rattlesnake", "Ratty", "Ravage", "Rave", "Raven", "Rawhide", "Rawly", "Raygun", "Raymond", "Razor", "Razorback", "Razz", "Razzy", "Reach", "Ready", "Reaper", "Rebel", "Recap", "Recon", "Red", "Redeye", "Redhook", "Redstone", "Reef", "Reg", "Reheat", "Relax", "Remit", "Remus", "Renegade", "Reno", "Repo", "Rescue", "Researcher", "Resist", "Retail", "Retriever", "Retro", "Revere", "Rex", "Reynard", "Rhino", "Rhody", "Ribby", "Rican", "Rick", "Rico", "Ridge", "Rifle", "Riley", "Rim", "Ringo", "Ringy", "Rio", "Ripley", "Ripper", "Ripsaw", "Risco", "Riser", "Risk", "Risky", "Ritz", "Ritzy", "Rival", "Rivet", "Riyal", "Roach", "Road", "Roadstead", "Robins", "Rocco", "Rock", "Rocket", "Rockfish", "Rocky", "Rodan", "Rodd", "Rodeo", "Rogue", "Rolex", "Roll", "Roller", "Roman", "Ronin", "Roof", "Rook", "Rooster", "Rope", "Roper", "Roscoe", "Rose", "Rouge", "Rough", "Roust", "Roving", "Rowdy", "Roxanne", "Royal", "Rubbens", "Rubber", "Ruby", "Ruckus", "Rude", "Rudy", "Ruin", "Rule", "Ruler", "Rumble", "Rummy", "Runny", "Rupee", "Rushmore", "Russo", "Rust", "Rustle", "Rusty", "Ryan", "Ryder", "Rye", "Saber", "Sabre", "Safe", "Saga", "Sageunay", "Saggy", "Said", "Sail", "Saint", "Salty", "Salvage", "Sam", "Sambo", "Sammy", "Samp", "San", "Sand", "Sandie", "Sandman", "Sandy", "Santa", "Sapper", "Sapphire", "Satan", "Satel", "Saucer", "Saucy", "Saudi", "Saul", "Savage", "Save", "Savor", "Savoy", "Savvy", "Sawbuck", "Saxon", "Scalp", "Scam", "Scandal", "Scarf", "Scarface", "Scars", "Scary", "Scat", "Scatter", "Scent", "Schooner", "Scoff", "Scoot", "Score", "Scorpion", "Scorpon", "Scout", "Scream", "Screamer", "Screw", "Scron", "Scrow", "Scuba", "Sea", "Seabee", "Seagull", "Seahawk", "Seat", "Selma", "Semi", "Seminole", "Senate", "Senegal", "Sentry", "Service", "Setup", "Shack", "Shade", "Shado", "Shadow", "Shady", "Shag", "Shaka", "Shake", "Shaku", "Shall", "Sham", "Shamrock", "Shamu", "Shane", "Shank", "Shape", "Sharjah", "Shark", "Shawl", "Sheena", "Sheep", "Shep", "Shifty", "Ship", "Shoba", "Shocker", "Shoe", "Shogun", "Shooter", "Shotgun", "Showbiz", "Shrimp", "Shuck", "Shunt", "Shut", "Shutr", "Shy", "Side", "Silent", "Silky", "Silva", "Silver", "Simba", "Sinner", "Site", "Sitka", "Six", "Skagit", "Skate", "Skater", "Skeeter", "Skidoo", "Skier", "Skim", "Skinner", "Skip", "Skull", "Skyhawk", "Skyking", "Skylark", "Skywatch", "Slacker", "Slag", "Slam", "Slang", "Slash", "Slayer", "Sled", "Sleek", "Slew", "Slick", "Slider", "Slingshot", "Slip", "Slog", "Slope", "Slot", "Sloth", "Sluff", "Slug", "Slugger", "Sluggo", "Slump", "Smart", "Smash", "Smasher", "Smog", "Smoke", "Smoky", "Smyth", "Snag", "Snake", "Snap", "Snapper", "Snapshot", "Snarl", "Sneaky", "Snick", "Sniff", "Snip", "Sniper", "Snoop", "Snoopy", "Snow", "Snowbird", "Sock", "Socks", "Soda", "Solex", "Sombrero", "Song", "Sonic", "Sooner", "Sooty", "Soupy", "Sour", "Sourdough", "South", "Southeast", "Space", "Spad", "Spade", "Spar", "Sparky", "Sparrow", "Sparta", "Spartan", "Spear", "Spectre", "Speed", "Speedo", "Sperm", "Spica", "Spice", "Spider", "Spike", "Spin", "Spirit", "Spit", "Spitfire", "Spock", "Spook", "Spooky", "Sport", "Spot", "Spotted", "Sprint", "Spruce", "Spry", "Spud", "Spun", "Spunk", "Spur", "Spurt", "Spy", "Stags", "Stake", "Stalk", "Stallion", "Starbird", "Starburst", "Starfish", "Stargate", "Start", "Startrek", "Stash", "Station", "Stave", "Stealth", "Steel", "Step", "Stetson", "Stick", "Stiff", "Stine", "Sting", "Stinger", "Stint", "Stipe", "Stitch", "Stob", "Stole", "Stomp", "Stone", "Stonewall", "Stork", "Storm", "Stormy", "Stout", "Straight", "Strat", "Stray", "Strike", "Stroke", "Struck", "Strut", "Stud", "Stump", "Sui", "Suitcase", "Sulphur", "Summit", "Sumo", "Sun", "Sundance", "Sundog", "Sunflower", "Sunliner", "Sunny", "Sunshine", "Sunspot", "Super", "Surf", "Sustic", "Swam", "Swamp", "Swap", "Swat", "Sweat", "Swede", "Swedic", "Sweet", "Swift", "Swig", "Swine", "Swing", "Swiss", "Switch", "Sword", "Swordfish", "Tabor", "Tacit", "Tack", "Tacky", "Taco", "Taffy", "Tajas", "Tak", "Take", "Tally", "Talon", "Tang", "Tangy", "Tank", "Tanker", "Tape", "Taper", "Tar", "Tarbox", "Tartan", "Taste", "Tasty", "Tater", "Tazz", "Teal", "Team", "Tempo", "Tennessee", "Termite", "Terra", "Tester", "Testline", "Teton", "Tex", "Texas", "Texon", "Thinker", "Thorus", "Thread", "Three", "Thud", "Thug", "Thumper", "Thunder", "Thunderbird", "Tica", "Tier", "Tigertail", "Tigre", "Timber", "Time", "Timon", "Tin", "Tina", "Tincup", "Tipple", "Tira", "Tire", "Titan", "Titus", "Toad", "Toby", "Toga", "Togo", "Toil", "Toiler", "Toler", "Toll", "Tomahawk", "Tomcat", "Tommy", "Toner", "Tong", "Tonga", "Tonight", "Tonto", "Tonus", "Toot", "Top", "Topcat", "Topdog", "Topgun", "Tophand", "Tophat", "Torch", "Torco", "Toreador", "Torf", "Toro", "Torque", "Tory", "Total", "Totty", "Toxi", "Toxic", "Track", "Tracker", "Trail", "Train", "Trans", "Transport", "Trap", "Trapper", "Travel", "Traw", "Trek", "Trend", "Trial", "Tribe", "Tricker", "Trident", "Trigger", "Trill", "Trim", "Trist", "Triton", "Troch", "Troit", "Trojan", "Troll", "Tron", "Trooper", "Tropic", "Troubleshooter", "Trout", "Truax", "Truce", "Trucker", "Trudy", "Trump", "Tryst", "Tuff", "Tug", "Tully", "Tulsa", "Tune", "Tuppy", "Turban", "Turbo", "Turf", "Turkish", "Tusker", "Tutty", "Twig", "Tyler", "Tyrol", "Ugh", "Ugly", "Ukn", "Uncle", "Unclouded", "Uniform", "Union", "Universal", "Unsew", "Until", "Upset", "Utah", "Utter", "Vader", "Vague", "Valor", "Valvo", "Vampire", "Vandal", "Vandy", "Vapor", "Vda", "Veda", "Vega", "Vegas", "Veil", "Vein", "Vela", "Velcro", "Velva", "Venom", "Venue", "Venus", "Vermont", "Verse", "Vesty", "Vetch", "Veto", "Vette", "Victory", "View", "Viga", "Viking", "Vinal", "Vine", "Vino", "Violent", "Viper", "Visor", "Vodka", "Void", "Volga", "Volt", "Volve", "Volvo", "Voodoo", "Vulcan", "Wafer", "Wager", "Wagon", "Wake", "Walden", "Wamo", "Wang", "Want", "Wappo", "War", "Warbonnet", "Wardog", "Warfighter", "Warhawk", "Warhorse", "Warlord", "Warm", "Warriors", "Warthog", "Wash", "Wasp", "Waterbug", "Watergate", "Watt", "Waylay", "Wear", "Weasel", "Wee", "Welby", "Wellington", "Wept", "Western", "Wgy", "Whisk", "Whistler", "White", "Wicked", "Widget", "Widow", "Wigan", "Wiki", "Wild", "Wildcat", "Wildwood", "Wiley", "Will", "Willow", "Wimpy", "Winder", "Winter", "Wise", "Wisen", "Witch", "Wizzen", "Wodan", "Wolf", "Wolfpack", "Wolverine", "Wooden", "Woodn", "Woody", "Work", "Worked", "Workhorse", "Worldwide", "Worn", "Worry", "Worth", "Wrangler", "Wrestler", "Wyatt", "Wylie", "Yalta", "Yamaha", "Yard", "Yellow", "Yellowblood", "Yoda", "Yogi", "Yonder", "Yosemite", "Yowl", "Yucca", "Yukla", "Yukon", "Yule", "Zag", "Zama", "Zapper", "Zeke", "Zepel", "Zesty", "Zeta", "Zinger", "Zippy", "Zola", "Zombie", "Zonal", "Zoom", "Zorba", "Zorro" }) function Library.objectiveNames.get() nextIndex = nextIndex + 1 return names[nextIndex] end end Library.radioMessages = { pilotEjecting = { "Mayday, mayday! Taking fire, punching out now!", "Engine's gone, I'm bailing! Mark my chute!", "Bird's on fire, I'm out, call SAR!", "Control's dead, ejecting! Watch for the seat!", "Lost hydraulics, can't hold her! Bailing out!" }, pilotImHit = { "I'm hit!", "Taking fire!", "Bird's hurt, trying to hold altitude!", "Impact on fuselage, took a solid hit!", "Taking damage, warning lights all over!" }, pilotKillAir = { "Splash one $1. Rejoining.", "Good hit, $1 down! Checking six.", "$1 down. I say again, splash one!", "Kill confirmed. $1's smoking.", "Splash one $1! Got him!", "Splash confirmed! Repeat, $1 down.", "$1 smoked, good kill.", "$1 splashed, no chute seen." }, -- "$1" should be "bandit" in audio version pilotKillGround = { "Splash one $1, repeat, target down. Eyes open for secondaries.", "$1 neutralized, big boom. Watch your altitude, debris kicking up.", "$1's a fireball, one less on the ground. Moving to next grid.", "Jackpot on that $1, burning good. Stay sharp for air defense.", "Scratch one $1, repeat scratch one.", "$1's toast, good effect on target. Rolling out.", "Got the $1, solid hit. Watch for air defense in that sector.", "Splash $1, good kill.", "$1's cooked, smoke's up." }, -- "$1" should be "vehicle" in audio version pilotKillInfantry = { "$1 neutralized.", "Enemy $1 taken out.", "Good effects on $1.", "Confirmed hit, $1 down.", "$1 position destroyed." }, -- "$1" should be "infantry" in audio version pilotKillShip = { "Splash confirmed! Enemy $1 going under.", "Direct hit! $1 burning and breaking up.", "$1's out of the fight! Big secondary explosion, she's listing hard.", "$1 neutralized, heavy smoke and debris in the water.", "Splash confirmed! Hull's cracking, $1's going down.", "$1's gone! Big fireball, multiple secondaries.", "$1's dead in the water! Zero movement on deck." }, -- "$1" should be "ship" in audio version pilotKillStrike = { "Target's gone, good splash. Structure's burning, over.", "Direct hit, building's collapsing. No secondary fire yet.", "Objective neutralized, smoke's up. Moving to egress.", "Good impact on target, structure is down.", "Target destroyed, heavy debris in the AO.", "Target's leveled, no movement inside.", "Structure is toast, solid hit.", "Good hit, building's breaking apart." }, pilotLaunchGuns = { "Guns!", "Guns, guns!" }, pilotLaunchBruiser = "Bruiser!", pilotLaunchFox1 = { "Fox 1!", "Fox 1!", "Fox 1, tracking bandit." }, pilotLaunchFox2 = { "Fox 2!", "Fox 2!", "Fox 2, missile tracking." }, pilotLaunchFox3 = { "Fox 3!", "Fox 3!", "Fox 3, cranking now." }, pilotLaunchMagnum = "Magnum!", pilotLaunchPickle = { "Pickle!", "Bomb away!" }, pilotLaunchRifle = { "Rifle!", "Missile away!"}, pilotLaunchRocket = "Rockets!", pilotNewFriendlyAircraft = { "$1 CAP launched from $2, we're heading toward AO.", "$1 CAP just wheels-up from $2, we'll soon be on station.", "$1 airborne from $2, we're pushing to cover your AO.", "$1 CAP launched from $2, expect blue air in your vicinity shortly.", "$1 departed $2, we're setting up CAP near you." }, pilotWarningAAA = { "Heads up, I'm seeing tracers. AAA fire.", "AAA lighting up, stay high.", "Flight, we've got heavy flak incoming, break!", "AAA tracer fire, they've got our range, don't stay straight!", "AAA's hot under us. Stay fast, don't linger!" }, pilotWarningMANPADS = { "MANPADS launch! Flare, flare, flare!", "Flight, MANPADS in the air. Dump flares, now!", "Coming from the ground, MANPADS hot!", "Go defensive, MANPADS off your nose! Flare, flare!", "MANPADS just came up from the deck, break hard and pop everything!" }, pilotWarningSAMLaunch = { "Spike! SAM just launched, break!", "SAM up! Defensive now!", "Launch! SAM, coming fast, pump chaff, go cold!", "SAM in the air, break hard!", "SAM fired, visual smoke! Extend, extend!" }, pilotWingmanChangeAltitude = { "$1, copy, adjusting now to $2.", "$1, roger, setting new altitude to $2.", "$1, altitude change confirmed, $2.", "$1, roger that, moving to new block at $2.", "$1, adjusting as ordered to $2." }, pilotWingmanDown = { "$1! I'm hit bad! I can't hold it! Punching out now!", "$1! Mayday! Mayday! I'm on fire! Ejecting, ejecting!", "$1! They got me! Left wing's gone! I'm getting out!", "$1! They nailed me, fire in the pit! I'm outta here!", "$1! Fire in the cockpit! Can't see anything! Ejecting!", "$1! Mayday! No control! This is it, ejecting now!" }, pilotWingmanEngageAir = { "$1, copy, engaging $2 now ($3).", "$1, tally one, pressing on $2 ($3).", "$1, roger, committing on $2 ($3).", "$1, confirm, going after $2 ($3).", "$1, affirm, moving in on $2 ($3)." }, -- "$2" should be "bandits" in audio version pilotWingmanEngageNoTarget = { "$1, negative tally, unable engage.", "$1, cannot comply, blind on target.", "$1, no joy on targets, cannot proceed.", "$1, negative contact, unable to commit.", "$1, that's a no, not seeing any targets." }, pilotWingmanEngageStrike = { "$1, copy, engaging target structure ($2).", "$1, roger, moving in on the building now ($2).", "$1, copy that, setting up for strike ($2)." }, pilotWingmanEngageSurface = { "$1, engaging $2 threat ($3).", "$1, rolling in on $2 position ($3).", "$1, affirm, moving in on $2 ($3).", "$1, on target, commencing attack on $2 ($3).", "$1, weapons hot, engaging $2 ($3).", }, -- "$2" should be "target" in audio version -- pilotWingmanGoToMarker = { -- "$1, copy. Pushing to waypoint now.", -- "$1, on route to the coords, maintaining current alt.", -- "$1, proceeding as briefed, on my way.", -- "$1, moving to grid as planned.", -- "$1, heading to the point." -- }, -- pilotWingmanGoToMarkerNoMarker = { -- "$1, negative on coords, say again?", -- "$1, copy, but I don't have the point. Confirm?", -- "$1, can't push, no steerpoint." -- }, pilotWingmanOrbit = { "$1. Wilco, holding here.", "$1. Copy, orbiting now.", "$1. Roger, in the hold.", "$1. Affirm, setting up the orbit.", "$1. Orbiting at position." }, pilotWingmanRejoin = { "$1, off the perch, rejoining your side.", "$1, tally visual, coming to you.", "$1, clear, rejoining to route.", "$1, pushing up to formation.", "$1, visual, sliding back into position." }, pilotWingmanRejoinTaskComplete = { "Tasking complete, moving to your wing.", "Task done, closing back on you.", "Work's done, moving to rejoin.", "Finished here, rejoining formation.", "Tasking handled, rejoining now." }, pilotWingmanReportContacts = { "$1, tally contacts.$2", "$1, tally groups, pushing details.$2", "$1, visual on targets.$2", "$1, eyes on units.$2", "$1, contacts hot.$2", "$1, eyes on possible targets.$2", "$1, got activity out here.$2", "$1, picking something up.$2", "$1, contact confirmed.$2", }, pilotWingmanReportContactsNew = { "Heads up, new contacts just popped up.$2", "Look out, tally fresh threats.$2", "Stay sharp, eyes on new group.$2", "Eyes open, additional threats spotted.$2", "Stay alert, new activity in our sector.$2", "Be aware, got more targets popping up.$2", "Fresh contacts out there, watch your sector.$2", "Stay focused, another set of contacts just popped.$2", "Tally something new, check your surroundings.$2", }, pilotWingmanReportContactsNoJoy = { "$1, negative contacts.", "$1, clean all sectors.", "$1, sensors are clean.", "$1, nothing showing on my end.", "$1, area looks clear.", }, pilotWingmanReportStatus = { "$1, status check coming up.\n\n$2", "$1, sending full sitrep now.\n\n$2", "$1, giving you flight status.\n\n$2", "$1, pushing current status.\n\n$2", "$1, copy, reporting in.\n\n$2" }, pilotWingmanTakeOff = { "$1, wheels up, coming to join on your six.", "$1 airborne, joining on your side.", "$1 just lifted, moving to formation.", "$1, off the strip, coming to your wing.", "$1, off the deck, forming up now." }, atcRequireNearestAirbase = { -- TODO: voiceover "Roger. Vectoring you to the nearest airbase.\n$1", "Copy. Coordinates to nearest field inbound.\n$1", "Roger. Guide you direct to the nearest recovery airfield.\n$1" }, atcWeatherUpdate = { -- TODO: voiceover "Roger. Weather info coming up now.\n$1", "Copy. Weather report inbound.\n$1", "This is control, checking conditions now.\n$1", "Copy. Weather data on the way.\n$1" }, atcSafeLanding = { "Be advised: $1 is wheels down at $2 and clear of runway.", "All aircraft, $1 has landed at $2 and vacated active. Runway is open for next inbound.", "Traffic, $1 is on deck at $2 and heading to parking. Runway clear.", "All flights, $1 just rolled out at $2 and cleared the active.", "Heads up, $1 landed at $2 and moving to the ramp. Runway available for next approach." }, atcSafeLandingPlayer = { "$1, wheels on deck, welcome back. You may taxi to the parking area.", "$1, good copy on landing. Exit when able, proceed to the parking area.", "$1, touchdown confirmed. Continue to parking.", "$1, welcome home. Clear of runway and taxi to parking area.", "$1, nice landing. Taxi to parking when ready." }, awacsPicture = { "$1, picture's up.$2", "$1, sending updated picture.$2", "$1, picture transmitted.$2", "$1, sending picture, over.$2", "$1, picture is live.$2", }, awacsPictureClear = { "$1, picture clear.", "$1, picture is clean.", "$1, picture clear, nothing airborne.", "$1, picture clean at this time." }, commandBlueOnBlue = { "Check fire! You hit a friendly!", "Break, break! You just tagged blue!", "Abort! You hit a friendly asset!", "Cease fire, check your IFF!", "Blue-on-blue, blue-on-blue!", }, commandFriendlyDown = { "All flights, we lost a friendly. $1 is down. Eyes open, hostiles still active in the area.", "Friendly bird down, I repeat, friendly bird down. $1 went cold. Stay sharp, possible threat still live.", "All squadrons, heads up. $1 just took a hit and is down hard. Keep it tight.", "We've lost $1. No chute sighted. Threat's still out there.", "Friendly down. $1 is out of the fight. Maintain altitude discipline and check six.", }, commandFriendlyPilotOnGround = "Ejected pilot is stranded on the ground. Launch CSAR operations immediately.", commandNewEnemyAircraft = { "Be advised, enemy fighters airborne from $2, heading unknown.", "To all flights, enemy fighters just launched from $2, expect contact in your sector.", "Flights, bogeys off $2, monitor radar and standby.", "Enemy birds wheels-up from $2, likely pushing toward your AO.", "Hostile aircraft launch confirmed from $2, maintain alert status." }, commandMissionComplete = { "All flights, mission objectives confirmed complete. You're clear to RTB.", "All leads, targets neutralized. Good work out there. Proceed to home plate.", "All squadrons, job's done. Exit the AO on your current route and check in with tower on approach for recovery.", "All flights, tasking is finished. Return to base, tower will advise final.", "All squadrons, good job, we're outta here. Break off and RTB." }, commandObjectiveComplete = { "All callsigns, objective $1 complete. Proceed to next objective.", "All flights, objective $1 is in the bag. Move to next phase as briefed.", "Flight leads, objective $1 secured. You're clear to proceed with the remainder.", "Work's done on objective $1. Push on to your next set.", "All flights, objective $1 wrapped, keep on the good work.", "All callsigns, objective $1's done. Proceed direct to next waypoint." }, commandObjectiveCoordinates = "Copy, navigational assist for objective $1.\n\n$2", commandObjectiveCoordinatesPrecise = "Copy, navigational assist for objective $1.\n\n$2", commandObjectivesManyLeft = { "Stay focused, people. We still have work to do.\n\n$1", "Our work is not done yet, we have a lot to do.\n\n$1", "Flights, you've got a couple of tasks left, keep moving down the list.\n\n$1", "Still a few objectives outstanding, don't break until they're complete.\n\n$1", "Alright people, keep your focus, more work ahead before you can head home.\n\n$1", "All flights, maintain timeline. You've got more boxes to check before RTB.\n\n$1" }, commandObjectivesOneLeft = { "All flights, you've got one last task before you're done.\n\n$1", "Flights, almost home. One objective remaining, then you're RTB.\n\n$1", "All flights, you're down to the final push. Complete this and you're done.\n\n$1", "All leads, one more on the board. Finish it and head back to base.\n\n$1", "Flights, you're not clear yet. One last objective to wrap up.\n\n$1", "Come on people, one last push and we're done.\n\n$1", "Just one objective to complete and we're done.\n\n$1" }, jtacSmokeOK = { "$1, target marked with $2 smoke, over.", "$1, $2 smoke out, standby for visual confirmation.", "$1, target marked, $2 smoke on deck.", "$1, mark complete, look for $2 smoke north of the road.", "$1, $2 smoke is up, call visual when you have it." }, jtacSmokeNoTarget = { "$1, no target to mark at this time, over.", "$1, negative mark, no target.", "$1, no joy on target, unable to mark.", "$1, no mark available, stand by for update.", "$1, negative smoke, target not established." }, jtacSmokeAlreadyOut = { "$1, target already marked, smoke on deck.", "$1, mark's up, resmoke already in place, over.", "$1, smoke is already out, advise when visual.", "$1, you're good, mark is already on the target.", "$1, target already marked with smoke." }, playerATCRequireNearestAirbase = { -- TODO: voiceover "Control, request vectors to nearest suitable base for recovery.", "Control, requesting nearest friendly airfield for landing, over.", "Control, negative on original destination, request alternate field nearest current position.", "Control, requesting location and frequency for closest towered airfield." }, playerATCWeatherUpdate = { -- TODO: voiceover "Control, request latest weather update, over.", "Control, need current weather and visibility.", "Control, what's the weather looking like out there?", "Control, checking weather, particularly wind.", }, playerAwacsBogeyDope = { "$1, request bogey dope.", "$1, bogey dope." }, playerAwacsPicture = { "$1, request picture.", "$1, picture when able.", "$1, need a picture.", "$1, request full picture.", "$1, picture update." }, playerCommandMissionStatus = { "Command, request update on mission status.", "Command, request SITREP on current mission status, over.", "Command, how's the mission picture? Any updates?", "Command, confirm progress on objectives, over.", "Command, need an update on situation, what's the status?", "Command, mission timeline check, are we on schedule?" }, playerCommandRequireObjectives = { "Command, request objective $1 coordinates, over.", "Command, send me grid for objective $1.", "Command, need objective $1 location, over.", "Command, pass coordinates for objective $1.", "Command, confirm grid on objective $1." }, playerWingmanChangeAltitude = { "Flight, adjust your altitude to $1.", "Flight, set new altitude to $1.", "Flight, stabilize at $1.", "Flight, update altitude profile to $1.", "Flight, altitude correction, go to $1." }, playerWingmanCoverMe = { "Flight, need cover now.", "Flight, keep my six clean.", "Flight, engaged defensive, cover me!", "Flight, break off and clear my tail.", "Flight, keep bandits off me." }, playerWingmanEngageAirDefense = { "Flight, prioritize $1, engage now.", "Flight, take down $1 systems.", "Flight, suppress $1 threats.", "Flight, $1 is yours, take it out.", "Flight, eliminate $1 positions." }, -- "$1" should be "air defense" in audio version playerWingmanEngageBandits = { "Flight, engage $1.", "Flight, you're cleared hot on $1.", "Flight, commit on $1 when ready.", "Flight, engage $1, your discretion.", "Flight, you're free to engage $1." }, -- "$1" should be "bandits" in audio version playerWingmanEngageGround = { "Flight, engage $1 targets.", "Flight, prosecute $1 targets ahead.", "Flight, engage all $1 contacts.", "Flight, strike $1 positions.", "Flight, take the lead on $1 targets.", }, -- "$1" should be "ground" in audio version playerWingmanEngageShips = { "Flight, engage enemy $1 now.", "Flight, strike $1 in your sector.", "Flight, take the lead on enemy $1.", }, -- "$1" should be "ships" in audio version playerWingmanEngageStrike = { "Flight, take out target building.", "Flight, hit target structure.", "Flight, clear to hit target building.", "Flight, strike target building, confirm visual.", }, -- playerWingmanGoToMarker = { -- "Flight, proceed to waypoint.", -- "Flight, push to the hold point now.", -- "Flight, push to station and hold.", -- "Flight, set up in the assigned area.", -- "Flight, move to designated steerpoint." -- }, playerWingmanOrbit = { "Flight, orbit at position.", "Flight, set up an orbit.", "Flight, hold on position.", "Flight, anchor on current position.", "Flight, orbit overhead." }, playerWingmanRejoin = { "Flight, rejoin my side.", "Flight, push it up, rejoin formation.", "Flight, come back to route.", "Flight, tighten it up.", "Flight, rejoin tactical." }, playerWingmanReportContacts = { "Flight, tally anything?", "Flight, got any hits?", "Flight, eyes or sensors on anything?", "Flight, see anything out there?", "Flight, any contacts your side?", }, playerWingmanReportStatus = { "Flight, confirm you're set.", "Flight, how are you looking?", "Flight, report in.", "Flight, status check.", "Flight, talk me through your state." }, playerJTACSmoke = { "$1, request smoke on objective $2, over.", "$1, mark objective $2 with smoke, how copy?", "$1, need a smoke mark on objective $2, standby for talk-on.", "$1, can you pop smoke on objective $2? Need visual confirmation.", "$1, give me a smoke mark near objective $2, confirm when ready.", }, } -- ==================================================================================== -- ENGAGEMENT RANGES OF VARIOUS SAM SYSTEMS -- ==================================================================================== Library.samRanges = { ["*HAWK"] = DCSEx.converter.nmToMeters(25), ["*NASAMS"] = DCSEx.converter.nmToMeters(8), ["*Patriot"] = DCSEx.converter.nmToMeters(54), ["*SA-2"] = DCSEx.converter.nmToMeters(23), ["*SA-3"] = DCSEx.converter.nmToMeters(10), ["*SA-5"] = DCSEx.converter.nmToMeters(4.5), ["*SA-6"] = DCSEx.converter.nmToMeters(13), ["*SA-10"] = DCSEx.converter.nmToMeters(65), ["*SA-11"] = DCSEx.converter.nmToMeters(20), ["Osa 9A33 ln"] = DCSEx.converter.nmToMeters(8), } Library.tasks = {} Library.tasks.antishipCargo = { taskFamily = DCSEx.enums.taskFamily.ANTISHIP, description = { briefing = { "Enemy cargo ships are delivering weapons and supplies to frontline units. Sinking them will disrupt their logistics and slow their advance.", "Cargo ships are moving fuel, ammo, and enemy reinforcements. Take them out to choke the enemy's front-line operations.", "Intel confirms that enemy cargo ships are carrying weapons and reinforcements. They should be destroyed immediately.", "Reconnaissance confirms that enemy cargo vessels are transporting materiel vital to the enemy's continued resistance. Interdiction is required.", "Logistical interdiction remains a top priority. A group of enemy cargo ships must be destroyed to limit their strategic reach." }, short = "Sink enemy cargo ships", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 0, surfaceType = land.SurfaceType.WATER, targetCount = { 2, 2 }, targetFamilies = { DCSEx.enums.unitFamily.SHIP_CARGO }, waypointInaccuracy = DCSEx.converter.nmToMeters(5.0) } Library.tasks.antiShipCorvette = { taskFamily = DCSEx.enums.taskFamily.ANTISHIP, description = { briefing = { "An enemy missile boat was detected within strike range of our troops. Neutralize it before it can launch.", "An enemy missile boat has entered our waters. You are authorized to engage and neutralize.", "An enemy corvette is operating within weapons release range of our task force. Its engagement is necessary to preempt an attack.", "An hostile craft possesses the capability to strike high-value naval assets. Its destruction is imperative to ensure fleet security.", "The target is a missile-equipped enemy vessel posing a direct threat to allied maritime operations. It must be destroyed at once." }, short = "Sink enemy missile boat", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 0, surfaceType = land.SurfaceType.WATER, targetCount = { 1, 1 }, targetFamilies = { DCSEx.enums.unitFamily.SHIP_MISSILE_BOAT }, waypointInaccuracy = DCSEx.converter.nmToMeters(5.0) } Library.tasks.groundAttackAPC = { taskFamily = DCSEx.enums.taskFamily.GROUND_ATTACK, description = { briefing = { "Enemy APCs are moving to reinforce frontline positions. Neutralizing them now will cripple their mobility and delay their counterattack.", "Taking out these APCs disrupts enemy troop deployments and buys our ground forces critical time to consolidate gains.", "Enemy armored personnel carriers are transporting infantry toward our exposed flank. Engage immediately to prevent a breakthrough.", "Our troops are under pressure. Eliminating those APCs will ease the fight and reduce incoming fire on their position.", "Recon confirms high-value targets in the APC convoy, including command elements. Destroying them now will cause significant disruption." }, short = "Destroy enemy APCs", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 3, 4 }, targetFamilies = { DCSEx.enums.unitFamily.GROUND_APC }, waypointInaccuracy = DCSEx.converter.nmToMeters(2.5) } Library.tasks.groundAttackArmorConvoy = { taskFamily = DCSEx.enums.taskFamily.GROUND_ATTACK, description = { briefing = { "An enemy armor column is moving toward our forward positions. Destroying it now will prevent a breakthrough and protect our ground forces.", "An enemy armor column is advancing rapidly toward our main supply route. If we don't stop them here, they'll cut off our logistics.", "You are to neutralize a key enemy armored unit before it reaches the battlefield. Hitting them now gives us the upper hand in the coming engagement.", "An armor column is heading toward a populated area. Eliminate the threat before it reaches the city and endangers civilians.", "This enemy armor column is the primary threat to our flank. Striking them now will stopp them from rolling through our defenses.", }, short = "Destroy enemy armor column", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC, DCSEx.enums.taskFlag.MOVING, DCSEx.enums.taskFlag.ON_ROADS }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 3, 4 }, targetFamilies = { DCSEx.enums.unitFamily.GROUND_APC, DCSEx.enums.unitFamily.GROUND_APC, DCSEx.enums.unitFamily.GROUND_MBT }, waypointInaccuracy = DCSEx.converter.nmToMeters(2.5) } Library.tasks.groundAttackArtillery = { taskFamily = DCSEx.enums.taskFamily.GROUND_ATTACK, description = { briefing = { "Enemy artillery is shelling our forward positions and delaying our advance. Take them out to clear the way for ground troops.", "Enemy artillery is hammering our lines and must be silenced immediately. Hit them hard, our soldiers are counting on it.", "A group of artillery batteries is a key part of the enemy's defensive network. Neutralizing it will open a gap in their lines.", "Our forces are pinned down by enemy artillery and taking losses. Eliminating the artillery threat will save lives and keep the momentum on our side.", "High command has prioritized the destruction of enemy artillery to enable a broader offensive. This objective is critical." }, short = "Destroy enemy artillery", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 3, 4 }, targetFamilies = { DCSEx.enums.unitFamily.GROUND_ARTILLERY }, waypointInaccuracy = DCSEx.converter.nmToMeters(2.5) } Library.tasks.groundAttackMBT = { taskFamily = DCSEx.enums.taskFamily.GROUND_ATTACK, description = { briefing = { "Enemy armor is advancing on our front lines. Neutralizing these tanks is critical to halting their momentum.", "Intel confirms enemy tanks are threatening a key supply route. Strike now to preserve our logistics corridor.", "Enemy tanks are the last major obstacle before our ground forces can break through. Hit them hard and clear the way.", "An enemy armor column was spotted nearby. Eliminate it before they regroup and launch a counterattack.", "Enemy tanks are guarding a location vital to the enemy's retreat. Destroy them to trap their forces and cut off escape." }, short = "Destroy enemy MBTs", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 2, 4 }, targetFamilies = { DCSEx.enums.unitFamily.GROUND_MBT }, waypointInaccuracy = DCSEx.converter.nmToMeters(2.5) } Library.tasks.groundAttackSSMissiles = { taskFamily = DCSEx.enums.taskFamily.GROUND_ATTACK, description = { briefing = { "Enemy missile launchers are targeting civilian and military infrastructure. Taking them out will cripple their long-range strike capability.", "Mobile TEL units are prepping for launch - this is a time-critical strike to neutralize the threat before missiles are airborne.", "Enemy missiles have already caused casualties among allied forces. Eliminating the launchers is essential for force protection.", "Destroying enemy missile launchers will degrade enemy morale and disrupt their command structure - it's a high-value tactical win.", "Missile launchers are being used to strike nearby towns. Your precision strike today will prevent further suffering and save lives.", }, short = "Destroy enemy SS missiles", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 3, 4 }, targetFamilies = { DCSEx.enums.unitFamily.GROUND_SS_MISSILE }, waypointInaccuracy = DCSEx.converter.nmToMeters(2.5) } Library.tasks.groundAttackTrucksConvoy = { taskFamily = DCSEx.enums.taskFamily.GROUND_ATTACK, description = { briefing = { "Intelligence confirms that an enemy convoy is transporting essential logistical supplies. Engaging this target is critical to degrading their operational capabilities.", "The designated convoy represents a significant threat to our frontline forces by sustaining enemy combat effectiveness; its neutralization is a priority.", "An enemy convoy is facilitating the movement of vital materiel. A successful strike will disrupt their supply chain and impede their operational tempo.", "The targeted convoy plays a pivotal role in enemy logistics. Effectively striking this formation will significantly impair their combat readiness.", "A convoy of enemy trucks is integral to enemy sustainment efforts. Your strike will contribute significantly to operational success." }, short = "Destroy enemy truck convoy", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC, DCSEx.enums.taskFlag.MOVING, DCSEx.enums.taskFlag.ON_ROADS }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 3, 4 }, targetFamilies = { DCSEx.enums.unitFamily.GROUND_UNARMED }, waypointInaccuracy = DCSEx.converter.nmToMeters(2.5) } Library.tasks.interceptionTransport = { taskFamily = DCSEx.enums.taskFamily.INTERCEPTION, description = { briefing = { "Enemy strike planes are closing on our ground forces. Intercept them before they tear our lines apart.", "Hostile attack aircraft are en route to hit our armor columns. Engage and destroy before they reach the battlefield.", "Enemy attack wings have crossed into our airspace, targeting supply convoys. Stop them or our front will collapse.", "Strike aircraft are inbound to launch precision attacks on our positions. Your mission: intercept and neutralize immediately.", "Enemy attack planes are preparing a low-level assault on our troops. Cut them off before they can deliver their payload." }, short = "Intercept enemy attack aircraft", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = nil, targetCount = { 2, 2 }, targetFamilies = { DCSEx.enums.unitFamily.PLANE_ATTACK }, waypointInaccuracy = DCSEx.converter.nmToMeters(6.0) } Library.tasks.interceptionBomber = { taskFamily = DCSEx.enums.taskFamily.INTERCEPTION, description = { briefing = { "Enemy bomber inbound. If it reaches its target, thousands of civilians are at risk. You're the last line to stop it before it crosses the border.", "Intel confirms a hostile bomber on approach to critical infrastructure. Your mission: intercept and neutralize before it gets within strike range.", "An enemy bomber is carrying high-yield ordnance toward a populated zone. Failure to intercept means catastrophic loss. Scramble now.", "Hostile bomber detected on vector to our forward base. Engage immediately; do not allow it to release payload.", "Enemy bomber is on a direct course for our command center. Intercept at all costs. Success ensures the survival of our forces." }, short = "Intercept enemy bomber", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = nil, targetCount = { 1, 1 }, targetFamilies = { DCSEx.enums.unitFamily.PLANE_BOMBER }, waypointInaccuracy = DCSEx.converter.nmToMeters(8.0) } Library.tasks.interceptionTransport = { taskFamily = DCSEx.enums.taskFamily.INTERCEPTION, description = { briefing = { "Enemy transport is inbound with troops and supplies. Stop it before it reinforces their front line.", "Hostile cargo aircraft is carrying critical equipment to enemy forces. Intercept and destroy before delivery.", "Enemy transport plane detected. Intel suggests it's moving high-value assets. Do not let it reach its destination.", "Transport aircraft is ferrying reinforcements across the border. Interception is the only way to halt their buildup.", "Enemy logistics bird is airborne. Taking it out cripples their supply chain. Engage immediately." }, short = "Intercept enemy transport aircraft", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = nil, targetCount = { 1, 1 }, targetFamilies = { DCSEx.enums.unitFamily.PLANE_TRANSPORT }, waypointInaccuracy = DCSEx.converter.nmToMeters(8.0) } Library.tasks.seadLong = { taskFamily = DCSEx.enums.taskFamily.SEAD, description = { briefing = { "Engagement of this enemy SAM site is essential to mitigate threats to our aircraft and maintain air superiority in the operational theater.", "Neutralizing this hostile surface-to-air missile installation will significantly reduce risks to our flight operations and support ongoing ground maneuvers.", "The elimination of this SAM site is imperative to ensure safe ingress and egress corridors for our air assets during the mission.", "Suppressing this SAM site is a strategic priority to safeguard our air operations and maintain operational momentum.", "This SAM installation represents a critical threat vector that must be neutralized to protect both aircrew and mission integrity.", "Striking this enemy SAM site will preserve the freedom of maneuver necessary for successful execution of subsequent air operations.", "Destroying this SAM site is vital to maintaining the tactical advantage and ensuring force protection throughout the engagement area.", "The removal of this hostile SAM site is a prerequisite for sustained air dominance and mission accomplishment." }, short = "Destroy enemy SAM site", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.DESTROY_TRACK_RADARS_ONLY }, minimumDistance = DCSEx.converter.nmToMeters(80.0), safeRadius = 250, surfaceType = land.SurfaceType.LAND, targetCount = { 1, 1 }, targetFamilies = { DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG }, waypointInaccuracy = 0.0 } Library.tasks.seadMedium = { taskFamily = DCSEx.enums.taskFamily.SEAD, description = { briefing = { "Engagement of this enemy SAM site is essential to mitigate threats to our aircraft and maintain air superiority in the operational theater.", "Neutralizing this hostile surface-to-air missile installation will significantly reduce risks to our flight operations and support ongoing ground maneuvers.", "The elimination of this SAM site is imperative to ensure safe ingress and egress corridors for our air assets during the mission.", "Suppressing this SAM site is a strategic priority to safeguard our air operations and maintain operational momentum.", "This SAM installation represents a critical threat vector that must be neutralized to protect both aircrew and mission integrity.", "Striking this enemy SAM site will preserve the freedom of maneuver necessary for successful execution of subsequent air operations.", "Destroying this SAM site is vital to maintaining the tactical advantage and ensuring force protection throughout the engagement area.", "The removal of this hostile SAM site is a prerequisite for sustained air dominance and mission accomplishment." }, short = "Destroy enemy SAM site", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.DESTROY_TRACK_RADARS_ONLY }, minimumDistance = DCSEx.converter.nmToMeters(40.0), safeRadius = 250, surfaceType = land.SurfaceType.LAND, targetCount = { 1, 1 }, targetFamilies = { DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM }, waypointInaccuracy = 0.0 } Library.tasks.strikeScenery = { taskFamily = DCSEx.enums.taskFamily.STRIKE, description = { briefing = { "A civilian building is being used as an enemy command post. Take it out before they coordinate another strike.", "Intel confirms hostile forces are operating from inside a civilian structure. Neutralize it to stop further attacks.", "A civilian building has been repurposed as a weapons cache. Destroy it before those arms hit the front lines.", "Enemy anti-air control is housed in a civilian facility. Eliminate it to open the skies for our forces.", "Recon shows a civilian structure is shielding enemy leadership. Bringing it down cripples their chain of command." }, short = "Destroy occupied building", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC, DCSEx.enums.taskFlag.SCENERY_TARGET }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 1, 1 }, targetFamilies = { DCSEx.enums.unitFamily.STATIC_SCENERY }, waypointInaccuracy = 0.0 } Library.tasks.strikeStructure = { taskFamily = DCSEx.enums.taskFamily.STRIKE, description = { briefing = { "Target structure is critical to enemy operations. Destroy it to cripple their plans.", "That installation is a key asset. Eliminating it will shift the battle in our favor.", "High-value structure confirmed in the target zone. Neutralize it before the enemy can react.", "The objective is essential to enemy logistics. Take it out immediately.", "Command wants that site erased. Its loss will deal a severe blow to enemy capability.", "Structure identified as a primary objective. Destroy it and deny enemy use.", "This is a priority strike target. Removing it will disrupt enemy momentum." }, short = "Destroy enemy structure", }, conditions = { difficultyMinimum = 0, eras = {}, }, completionEvent = DCSEx.enums.taskEvent.DESTROY, flags = { DCSEx.enums.taskFlag.ALLOW_JTAC }, minimumDistance = DCSEx.converter.nmToMeters(10.0), safeRadius = 100, surfaceType = land.SurfaceType.LAND, targetCount = { 1, 1 }, targetFamilies = { DCSEx.enums.unitFamily.STATIC_STRUCTURE }, waypointInaccuracy = 0.0 } Library.weaponsDates = { [""] = DCSEx.enums.timePeriod.WORLD_WAR_2, [""] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["BF109K_4_FUEL_TANK"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["BIN_200"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["BRU-42_3*BDU-33"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["BR_250"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["BR_500"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["B_8V20A_CM"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["B_8V20A_OFP2"] = DCSEx.enums.timePeriod.COLD_WAR, ["B_8V20A_OM"] = DCSEx.enums.timePeriod.COLD_WAR, ["CATM-9M"] = DCSEx.enums.timePeriod.COLD_WAR, ["CBLS-200"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["CLB4-PYLON-SAMP250HD"] = DCSEx.enums.timePeriod.COLD_WAR, ["CLB4-PYLON-SAMP400LD"] = DCSEx.enums.timePeriod.COLD_WAR, ["DIS_AKD-10"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_AKG_DLPOD"] = DCSEx.enums.timePeriod.COLD_WAR, ["DIS_BRM1_90"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_C-701IR"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_C-701T"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_C-802AK"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_CM-802AKG"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_DF4A_KD20"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_DF4B_YJ12"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_GB6"] = DCSEx.enums.timePeriod.COLD_WAR, ["DIS_GB6_HE"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_GB6_TSP"] = DCSEx.enums.timePeriod.COLD_WAR, ["DIS_GDJ_KD63"] = DCSEx.enums.timePeriod.COLD_WAR, ["DIS_GDJ_YJ83K"] = DCSEx.enums.timePeriod.MODERN, ["DIS_H6_250_2_N12"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_H6_250_2_N24"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_LAU68_MK5_DUAL_GDJ_II19_L"] = DCSEx.enums.timePeriod.KOREA_WAR, ["DIS_LAU68_MK5_DUAL_GDJ_II19_R"] = DCSEx.enums.timePeriod.KOREA_WAR, ["DIS_LS_6_100_DUAL_L"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_LS_6_100_DUAL_R"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_LS_6_250_DUAL_L"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_LS_6_250_DUAL_R"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_LS_6_500"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_MER6_250_3_N6"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_MK_82S_DUAL_GDJ_II19_L"] = DCSEx.enums.timePeriod.KOREA_WAR, ["DIS_MK_82S_DUAL_GDJ_II19_R"] = DCSEx.enums.timePeriod.KOREA_WAR, ["DIS_PL-5EII"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_PL-8B"] = DCSEx.enums.timePeriod.COLD_WAR, ["DIS_RKT_90_UG"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_SD-10"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_SD-10_DUAL_L"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_SD-10_DUAL_R"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_SPJ_POD"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_TANK1100"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_TANK800"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_TYPE200"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["DIS_TYPE200_DUAL_L"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["DIS_TYPE200_DUAL_R"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["DIS_WMD7"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["ER_4_SC50"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["FAB_100M"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["FAB_50"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["FAS}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["FW109_FUEL_TANK"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["GUV_VOG"] = DCSEx.enums.timePeriod.KOREA_WAR, ["GUV_YakB_GSHP"] = DCSEx.enums.timePeriod.KOREA_WAR, ["I16_DROP_FUEL_TANK"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["I16_FAB_100SV"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["I16_RS_82"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["LAU-105_1*CATM-9M_R"] = DCSEx.enums.timePeriod.COLD_WAR, ["LAU3_HE151"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["LAU3_HE5"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["LAU3_WP61"] = DCSEx.enums.timePeriod.KOREA_WAR, ["LAU_117_CATM_65K"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["LAU_117_TGM_65D"] = DCSEx.enums.timePeriod.KOREA_WAR, ["LAU_117_TGM_65G"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["LAU_117_TGM_65H"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["LAU_131x3_HYDRA_70_M156"] = DCSEx.enums.timePeriod.KOREA_WAR, ["M134_L"] = DCSEx.enums.timePeriod.KOREA_WAR, ["M134_R"] = DCSEx.enums.timePeriod.KOREA_WAR, ["M134_SIDE_L"] = DCSEx.enums.timePeriod.KOREA_WAR, ["M134_SIDE_R"] = DCSEx.enums.timePeriod.KOREA_WAR, ["M260_HYDRA_WP"] = DCSEx.enums.timePeriod.KOREA_WAR, ["OH58D_AGM_114_L"] = DCSEx.enums.timePeriod.MODERN, ["OH58D_AGM_114_R"] = DCSEx.enums.timePeriod.MODERN, ["OH58D_FIM_92_L"] = DCSEx.enums.timePeriod.COLD_WAR, ["OH58D_FIM_92_R"] = DCSEx.enums.timePeriod.COLD_WAR, ["OH58D_M3P_L500"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["PTB-1200-F1"] = DCSEx.enums.timePeriod.COLD_WAR, ["PTB300_MIG15"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["PTB400_MIG15"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["PTB600_MIG15"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["PTB760_MIG19"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["SC_501_SC250"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["SC_501_SC500"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["XM158_MK5"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{00F5DAC4-0466-4122-998F-B1A298E34113}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{0290F5DE-014A-4BB1-9843-D717749B1DED}"] = DCSEx.enums.timePeriod.MODERN, ["{0395076D-2F77-4420-9D33-087A4398130B}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{0511E528-EA28-4caf-A212-00D1408DF10A}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{0519A261-0AB6-11d6-9193-00A0249B6F00}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{0519A262-0AB6-11d6-9193-00A0249B6F00}"] = DCSEx.enums.timePeriod.MODERN, ["{0519A263-0AB6-11d6-9193-00A0249B6F00}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{0519A264-0AB6-11d6-9193-00A0249B6F00}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{05544F1A-C39C-466b-BC37-5BD1D52E57BB}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{08164777-5E9C-4B08-B48E-5AA7AFB246E2}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{0B9ABA77-93B8-45FC-9C63-82AFB2CB50A4}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{0DA03783-61E4-40B2-8FAE-6AEE0A5C5AAE}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{12429ECF-03F0-4DF6-BCBD-5D38B6343DE1}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{1461CD18-429A-42A9-A21F-4C621ECD4573}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{14_3_M2_6xBAP100}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{14_3_M2_6xBAT120}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{16602053-4A12-40A2-B214-AB60D481B20E}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{174C6E6D-0C3D-42ff-BCB3-0853CB371F5C}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{1C2B16EB-8EB0-43de-8788-8EBB2D70B8BC}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{1C97B4A0-AA3B-43A8-8EE7-D11071457185}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{29A828E2-C6BB-11d8-9897-000476191836}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{2AF2EC3F-9065-4de5-93E1-1739C9A71EF7}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{2BEC576B-CDF5-4B7F-961F-B0FA4312B841}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{2x Mk-82 SWA}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{319293F2-392C-4617-8315-7C88C22AF7C4}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{35B698AC-9FEF-4EC4-AD29-484A0085F62B}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{3C612111-C7AD-476E-8A8E-2485812F4E5C}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{3DFB7320-AB0E-11d7-9897-000476191836}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{3DFB7321-AB0E-11d7-9897-000476191836}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{3E35F8C1-052D-11d6-9191-00A0249B6F00}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{3xM8_ROCKETS_IN_TUBES}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{414DA830-B61A-4F9E-B71B-C2F6832E1D7A}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{414E383A-59EB-41BC-8566-2B5E0788ED1F}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{4203753F-8198-4E85-9924-6F8FF679F9FF}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{44EE8698-89F9-48EE-AF36-5FD31896A82A}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{44EE8698-89F9-48EE-AF36-5FD31896A82C}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{44EE8698-89F9-48EE-AF36-5FD31896A82D}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{44EE8698-89F9-48EE-AF36-5FD31896A82F}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{4CD2BB0F-5493-44EF-A927-9760350F7BA1}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{4F977A2A-CD25-44df-90EF-164BFA2AE72F}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{4xAN-M64_on_InvCountedAttachmentPoints}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{53BE25A4-C86C-4571-9BC0-47D668349595}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{57232979-8B0F-4db7-8D9A-55197E06B0F5}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{5A1AC2B4-CA4B-4D09-A1AF-AC52FBC4B60B}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{637334E4-AB5A-47C0-83A6-51B7F1DF3CD5}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{64329ED9-B14C-4c0b-A923-A3C911DA1527}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{65396399-9F5C-4ec3-A7D2-5A8F4C1D90C4}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{696CFFC4-0BDE-42A8-BE4B-0BE3D9DD723C}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{69926055-0DA8-4530-9F2F-C86B157EA9F6}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{6A4B9E69-64FE-439a-9163-3A87FB6A4D81}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{6C0D552F-570B-42ff-9F6D-F10D9C1D4E1C}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{6D778860-7BB8-4ACB-9E95-BA772C6BBC2C}"] = DCSEx.enums.timePeriod.MODERN, ["{7210496B-7B81-4B52-80D6-8529ECF847CD}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{7575BA0B-7294-4844-857B-031A144B2595}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{7AEC222D-C523-425e-B714-719C0D1EB14D}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{7B4B122D-C12C-4DB4-834E-4D8BB4D863A8}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{7B8DCEB4-820B-4015-9B48-1028A4195692}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{7D7EC917-05F6-49D4-8045-61FC587DD019}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{8A0BE8AE-58D4-4572-9263-3144C0D06364}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{8B9E3FD0-F034-4A07-B6CE-C269884CC71B}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{8C3F26A1-FA0F-11d5-9190-00A0249B6F00}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{8C3F26A2-FA0F-11d5-9190-00A0249B6F00}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{90321C8E-7ED1-47D4-A160-E074D5ABD902}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{96A7F676-F956-404A-AD04-F33FB2C74881}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{96A7F676-F956-404A-AD04-F33FB2C74884}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{9M114 Shturm-V-2 Rack}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{9S846_2xIGLA}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{A021F29D-18AB-4d3e-985C-FC9C60E35E9E}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{A5BAEAB7-6FAF-4236-AF72-0FD900F493F9}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{A6FD14D3-6D30-4C85-88A7-8D17BEE120E2}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AB_250_2_SD_10A}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AB_250_2_SD_2}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AB_500_1_SD_10A}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AD5E5863-08FC-4283-B92C-162E2B2BD3FF}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{ADD3FAE1-EBF6-4EF9-8EFC-B36B5DDF1E6B}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{AIM-9M}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{AIS_ASQ_T50}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{AKAN}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{AN-M3}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AN-M64}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AN_APG_78}"] = DCSEx.enums.timePeriod.MODERN, ["{AN_M57}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AN_M65}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{APK_9}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{APU_68_S-24}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{ARAKM70BHE}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{ASO-2}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{AV8BNA_AERO1D}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{AWW-13}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B13_5_S13OF_DUAL_L}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B13_5_S13OF_DUAL_R}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B1EF6B0E-3D91-4047-A7A5-A99E7D8B4A8B}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B83CB620-5BBE-4BEA-910C-EB605A327EF9}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{B8M1_20_S8KOM_DUAL_L}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B8M1_20_S8KOM_DUAL_R}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B8M1_20_S8OFP2_DUAL_L}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B8M1_20_S8OFP2_DUAL_R}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B8M1_20_S8TsM_DUAL_L}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B8M1_20_S8TsM_DUAL_R}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{B919B0F4-7C25-455E-9A02-CEA51DB895E3}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BD289E34-DF84-4C5E-9220-4B14C346E79D}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{BDAD04AA-4D4A-4E51-B958-180A89F963CF}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{BDU-50HD}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{BDU-50LD}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{BDU-50LGB}"] = DCSEx.enums.timePeriod.MODERN, ["{BK90MJ1}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BLG66_AC}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BLG66_BELOUGA_AC}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BLU107B_DURANDAL}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRD_4_250_4xMK76}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU-32 MK-20}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU-32 MK-82AIR}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU-42A_2*GBU-12_SIDE_LEFT}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU-42A_2*GBU-12_SIDE_RIGHT}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU-42_2*MK-20_LEFT}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU-42_2*MK-20_RIGHT}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU-42_2*Mk-82SNAKEYE_LEFT}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU-42_2*Mk-82SNAKEYE_RIGHT}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU-42_3*Mk-82AIR}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU-42_3*Mk-82LD}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU-42_3*Mk-82SNAKEYE}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU3242_2*LAU10 R}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU3242_2*SUU25 R}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU3242_3*BDU33}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{BRU3242_LAU10}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU3242_SUU25}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{BRU33_2*LAU10}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU33_2*LAU61}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU33_2*LAU68_MK5}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU33_2X_CBU-99}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU33_2X_MK-82_Snakeye}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{BRU33_2X_ROCKEYE}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{British_GP_500LB_Bomb_Mk4_Short_on_Handley_Page_Type_B_Cut_Bar}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{British_GP_500LB_Bomb_Mk4_Short}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{British_GP_500LB_Bomb_Mk5}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{British_MC_250LB_Bomb_Mk2_on_Handley_Page_Type_B_Cut_Bar}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{British_MC_500LB_Bomb_Mk1_Short_on_Handley_Page_Type_B_Cut_Bar}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{British_SAP_250LB_Bomb_Mk5_on_Handley_Page_Type_B_Cut_Bar}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{British_SAP_500LB_Bomb_Mk5}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{C-101-DEFA553}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{C0FF4842-FBAC-11d5-9190-00A0249B6F00}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{C42EE4C3-355C-4B83-8B22-B39430B8F4AE}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{CAE48299-A294-4bad-8EE6-89EFC5DCDF00}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CBU-52B}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CE2_SMOKE_WHITE}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_L_BDU50LGB_x_2}"] = DCSEx.enums.timePeriod.MODERN, ["{CFT_L_BLU107_x_6}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_L_CBU_100_x_6}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_L_CBU_87_x_3}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CFT_L_GBU_12_x_4}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_L_GBU_54_x_3}"] = DCSEx.enums.timePeriod.MODERN, ["{CFT_L_MK82AR_x_6}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{CFT_L_MK82LD_x_6}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{CFT_R_BDU50LGB_x_2}"] = DCSEx.enums.timePeriod.MODERN, ["{CFT_R_BLU107_x_6}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_R_CBU_100_x_6}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_R_CBU_87_x_3}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CFT_R_CBU_87_x_6}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CFT_R_CBU_97_x_3}"] = DCSEx.enums.timePeriod.MODERN, ["{CFT_R_GBU_10_x_2}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_R_GBU_12_x_4}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{CFT_R_GBU_54_x_3}"] = DCSEx.enums.timePeriod.MODERN, ["{CFT_R_MK82AR_x_6}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{CFT_R_MK82LD_x_6}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{CLB4_BLU107}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CLB4_SAMP250HD}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CLB4_SAMP250LD}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CLB4_SAMP400HD}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{CLB4_SAMP400LD}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{COLOR-TANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{D22C2D63-E5C9-4247-94FB-5E8F3DE22B71}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{D3F65166-1AB8-490f-AF2F-2FB6E22568B1}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{D3F65166-1AB8-490f-AF2F-2FB6E22568B4}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{D5435F26-F120-4FA3-9867-34ACE562EF1B}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{DAD45FE5-CFF0-4a2b-99D4-5D044D3BC22F}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{DDCE7D70-5313-4181-8977-F11018681662}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{DT75GAL}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{E1AAE713-5FC3-4CAA-9FF5-3FDCFB899E33}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{E1F29B21-F291-4589-9FD8-3272EEC69506}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{E659C4BE-2CD8-4472-8C08-3F28ACB61A8A}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{E8D4652F-FD48-45B7-BA5B-2AE05BB5A9CF}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{E92CBFE5-C153-11d8-9897-000476191836}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{EF124821-F9BB-4314-A153-E0E2FE1162C4}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{EFEC8200-B922-11d7-9897-000476191836}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{EFEC8201-B922-11d7-9897-000476191836}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{EFT_230GAL}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{Eclair}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{F-15E_AAQ-13_LANTIRN}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{F1243568-8EF0-49D4-9CB5-4DA90D92BC1D}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{F14-300gal}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F14-ALQ167}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{F14-ECA}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{F14-TARPS}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{F15E_EXTTANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F376DBEE-4CAE-41BA-ADD9-B2910AC95DEC}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F3EFE0AB-E91A-42D8-9CA2-B63C91ED570A}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{F4920E62-A99A-11d8-9897-000476191836}"] = DCSEx.enums.timePeriod.MODERN, ["{F4_SARGENT_TANK_370_GAL_EMPTY}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F4_SARGENT_TANK_370_GAL_R_EMPTY}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F4_SARGENT_TANK_370_GAL_R}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F4_SARGENT_TANK_370_GAL}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F4_SARGENT_TANK_600_GAL_EMPTY}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F4_SARGENT_TANK_600_GAL}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F72F47E5-C83A-4B85-96ED-D3E46671EE9A}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{F86ANM64}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{F99BEC1A-869D-4AC7-9730-FBA0E3B1F5FC}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FAB-100x2}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FAB_250_DUAL_L}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FAB_250_DUAL_R}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FAB_500_DUAL_L}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FAB_500_DUAL_R}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FAS}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{FB3CE165-BF07-4979-887C-92B87F13276B}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FC23864E-3B80-48E3-9C03-4DA8B1D7497B}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{FC56DF80-9B09-44C5-8976-DCFAFF219062}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{FD21B13E-57F3-4C2A-9F78-C522D0B5BCE1}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{FN_HMP400}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{FPU_8A_FUEL_TANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FUEL-SUBAL_TANK-330}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FUEL-TIP-ELLITTIC-L}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FUEL-TIP-ELLITTIC-R}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FUEL-TIP-TANK-500-L}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FUEL-TIP-TANK-500-R}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FW_190_R4M_LEFT_WING}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{FW_190_R4M_RGHT_WING}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{GAU_12_Equalizer}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{GBU_8_B}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{GIAT_M621_APHE}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_ALE_40_0_0}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_ALE_40_30_60}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_ALQ-131_ON_ADAPTER_IN_AERO7}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{HB_F4E_BLU-107B_3x_SWA}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_BLU-107B_3x}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_BLU-107B_6x}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_CBU-1A_MER_1x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-1A_MER_2x_Left}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-1A_MER_2x_Right}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-2A_MER_1x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-2A_MER_2x_Left}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-2A_MER_2x_Right}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-2BA_MER_1x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-2BA_MER_2x_Left}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-2BA_MER_2x_Right}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_CBU-52B_2x_SWA}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_CBU-52B_2x}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_CBU-52B_MER_3x_Left}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_CBU-52B_MER_3x_Right}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_CBU-87_2x_SWA}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{HB_F4E_CBU-87_MER_3x_Left}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{HB_F4E_CBU-87_MER_3x_Right}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{HB_F4E_CBU-87_MER_4x}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{HB_F4E_GBU-12_2x_SWA}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_LAU-3_MK5_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_LAU-3_MK5_MER_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_LAU-3_WP156_MER_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_LAU-68_MK5_1x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_LAU-68_MK5_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_LAU-68_WP156_1x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_M117_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_M117_MER_3x_Left}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_M117_MER_3x_Right}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_M117_MER_5x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-82_2x_SWA}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-82_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-82_6x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-82_Snakeye_2x_SWA}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-82_Snakeye_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-82_Snakeye_6x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-83_3x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-83_MER_2x}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_MK-83_MER_3x_Ripple}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{HB_F4E_ROCKEYE_2x_SWA}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_ROCKEYE_3x}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_F4E_ROCKEYE_6x}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HB_PAVE_SPIKE_FAST_ON_ADAPTER_IN_AERO7}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HOT3_L1_M}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HOT3_L2_M}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HOT3_L2}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HOT3_R1_M}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HOT3_R2_M}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HOT3_R2}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{HVAR_SMOKE_GENERATOR}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{HVAR_USN_Mk28_Mod4_Corsair}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{HVARx2}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{HVAR}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{IAFS_ComboPak_100}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{INV-SMOKE-BLUE}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{INV-SMOKE-RED}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{INV-SMOKE-WHITE}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{IR_Deflector}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{KB}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{LAU-131x3 - 7 AGR-20 M282}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{LAU3_FFAR_MK5HEAT}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{LAU3_FFAR_WP156}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{LR25_ARF8M3_API}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{LR25_ARF8M3_HEI}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{LYSBOMB_S7H}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{LYSBOMB_S7V}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{LYSBOMB_V7H}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{LYSBOMB_V7V}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{M260_APKWS_M151}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{M260_A_M151_B_M257}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{M260_M151}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{M260_M229}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{M261_INBOARD_DE_M151_C_M257}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{M261_INBOARD_DE_M151_C_M274}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{M261_OUTBOARD_AB_M151_E_M257}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{M261_OUTBOARD_AB_M151_E_M274}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{M299_4xAGM_114L}"] = DCSEx.enums.timePeriod.MODERN, ["{M2KC_02_RPL541}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{M2KC_08_RPL541}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{M2KC_BAP100_18_RACK}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{M2KC_RPL_522}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{M71BOMBD}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{M71BOMB}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MAK79_BDU33 3L}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MAK79_BDU33 3R}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MAK79_BDU33 4}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MAK79_MK20 2L}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MAK79_MK20 2R}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MAK79_MK81 3L}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MAK79_MK81 3R}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MAK79_MK81 4}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MAK79_MK82 3L}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MAK79_MK82 3R}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MAK79_MK82 4}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MATRA_F1_SNEBT253}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MATRA_F1_SNEBT256}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MATRA_F4_SNEBT251}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MATRA_F4_SNEBT253}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MATRA_F4_SNEBT256}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MB339_ANM3_L}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{MB339_ANM3_R}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{MB339_DEFA553_L}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{MB339_DEFA553_R}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{MB339_TRAVELPOD}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{MB339_VINTEN}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{MBD3_U6_3*FAB-250_fwd}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MBD3_U6_5*FAB-250}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MBDA_MistralD}"] = DCSEx.enums.timePeriod.MODERN, ["{MBDA_MistralG}"] = DCSEx.enums.timePeriod.MODERN, ["{MER-5E_MK82x5}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MER-5E_Mk82SNAKEYEx5}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{MMagicII}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{MOSQUITO_100GAL_SLIPPER_TANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MOSSIE_2_British_HE_60LBFNo1_3INCHNo1_ON_LEFT_WING_RAILS}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MOSSIE_2_British_HE_60LBFNo1_3INCHNo1_ON_RIGHT_WING_RAILS}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_LEFT_WING_RAILS}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{MOSSIE_4_British_HE_60LBSAPNo2_3INCHNo1_ON_RIGHT_WING_RAILS}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{Matra155RocketPod}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{Matra_S530D}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{Mk82AIR}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{Mk82SNAKEYE}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{ORO57K_S5M_HEFRAG}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{P47_5_HVARS_ON_LEFT_WING_RAILS}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{P47_5_HVARS_ON_RIGHT_WING_RAILS}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PHXBRU3242_2*LAU10 LS}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{PHXBRU3242_2*LAU10 RS}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{PK-3}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{PTB-150GAL}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_120_F86F35}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_150L_L39}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_200_F86F35}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_350L_L39}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_450}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_490C_MIG21}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_490_MIG21}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{PTB_800_MIG21}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{R530F_EM}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{R530F_IR}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{R550_Magic_1}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{RB75T}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{RB75}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{RBK_250_275_AO_1SCH}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{RBK_500U_OAB_2_5RT}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{RKL609_L}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{RKL609_R}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{RN-24}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{RN-28}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{Rb04_HB}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{Rb04}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{Rb15_HB}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{Robot05}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{Robot24J}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{Robot24}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{Robot74}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{S25_DUAL_L}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{S25_DUAL_R}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{S530F}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{SA342_Mistral_L1}"] = DCSEx.enums.timePeriod.MODERN, ["{SA342_Mistral_L2}"] = DCSEx.enums.timePeriod.MODERN, ["{SA342_Mistral_R1}"] = DCSEx.enums.timePeriod.MODERN, ["{SA342_Mistral_R2}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{SAMP250HD}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{SAMP400LD}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{SC_250_T1_L2}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{SC_500_L2}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{SD_250_Stg}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{SD_500_A}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{SMOKE-GREEN-MB339}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{SMOKE-RED-AVIOJET}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{SMOKE-RED-MB339}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{SMOKE-SYSTEM-AVIOJET}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{SMOKE-WHITE-MB339}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{SMOKE-YELLOW-AVIOJET}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{SMOKE_WHITE}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{SPS-141-100}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{SUU_23_POD}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TELSON8_SNEBT251}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{TER_9A_2L*MK-82AIR}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TER_9A_2L*MK-82_Snakeye}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TER_9A_2R*MK-82AIR}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TER_9A_2R*MK-82_Snakeye}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TER_9A_3*MK-82AIR}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TER_9A_3*MK-82_Snakeye}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TER_9A_3*MK-82}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{TWIN_B13L_5OF}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{TWIN_B_8M1_S_8KOM}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{TWIN_B_8M1_S_8_OFP2}"] = DCSEx.enums.timePeriod.COLD_WAR, ["{TWIN_S25}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{Tiny_Tim_Corsair}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{U22A}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{U22}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{UB-16-57UMP}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{UB-16_S5M}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{UB-32A-24}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{UB-32_S5M}"] = DCSEx.enums.timePeriod.KOREA_WAR, ["{UPK-23-250 MiG-21}"] = DCSEx.enums.timePeriod.VIETNAM_WAR, ["{US_110GAL_FUEL_TANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{US_150GAL_FUEL_TANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{VIGGEN_X-TANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{WGr21}"] = DCSEx.enums.timePeriod.WORLD_WAR_2, ["{WHITE-TANK}"] = DCSEx.enums.timePeriod.WORLD_WAR_2 } TUM.atc = {} do function TUM.atc.requestNavAssistanceToObjective(index, delayRadioAnswer) local obj = TUM.objectives.getObjective(index) if not obj then return end local msgIDSuffix = "" if obj.preciseCoordinates then msgIDSuffix = "Precise" end local players = coalition.getPlayers(TUM.settings.getPlayerCoalition()) for _,p in ipairs(players) do -- Give BRA to objective local navInfo = "- Fly "..DCSEx.dcs.getBRAA(obj.waypoint3, p:getPoint(), false).."\n" -- Give flight time and ETA local velocity = p:getVelocity() local speed = math.max(1, math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y + velocity.z * velocity.z)) local distance = DCSEx.math.getDistance2D(obj.waypoint2, DCSEx.math.vec3ToVec2(p:getPoint())) local timeInMinutes = math.max(1, math.floor(distance / (speed * 60))) local eta = DCSEx.string.getTimeString(timer.getAbsTime() + timeInMinutes * 60) if timeInMinutes > 600 then navInfo = navInfo.."- More than ten hours of flight time at current airspeed\n" elseif timeInMinutes > 120 then navInfo = navInfo.."- "..tostring(math.floor(timeInMinutes / 60)).." hours of flight time at current airspeed, ETA "..eta.."\n" else navInfo = navInfo.."- "..tostring(timeInMinutes).." minute(s) of flight time at current airspeed, ETA "..eta.."\n" end -- Give objective coordinates if obj.preciseCoordinates then navInfo = navInfo.."\nExact coordinates for objective are:\n" else navInfo = navInfo.."\nNo exact coordinates for objective. Approximate coordinates are:\n" end navInfo = navInfo..DCSEx.world.getCoordinatesAsString(obj.waypoint3, false) TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(p), "commandObjectiveCoordinates"..msgIDSuffix, { obj.name, navInfo }, "Command", delayRadioAnswer) end end function TUM.atc.requireNearestAirbase(delayRadioAnswer) local players = coalition.getPlayers(TUM.settings.getPlayerCoalition()) for _,p in ipairs(players) do local airbaseInfo = "- No airbase available near you at the moment." -- TODO: proper "no airbase" message local validAirbaseTypes = { Airbase.Category.AIRDROME } if p:hasAttribute("Helicopters") then table.insert(validAirbaseTypes, Airbase.Category.HELIPAD) end local pDesc = p:getDesc() if pDesc.LandRWCategories and #pDesc.LandRWCategories > 0 then -- TODO: check player unit description to filter compatible carrier types table.insert(validAirbaseTypes, Airbase.Category.SHIP) end local allAirbases = coalition.getAirbases(TUM.settings.getPlayerCoalition()) if allAirbases and #allAirbases > 0 then allAirbases = DCSEx.dcs.getNearestObjects(DCSEx.math.vec3ToVec2(p:getPoint()), allAirbases) for i=1,#allAirbases do local abDesc = airbaseInfo[i]:getDesc() if DCSEx.table.contains(validAirbaseTypes, abDesc.category) then airbaseInfo = abDesc.displayName break end end end TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(p), "atcRequireNearestAirbase", { airbaseInfo }, "Control", delayRadioAnswer) end end function TUM.atc.requestWeatherUpdate(delayRadioAnswer) local weatherInfo = "- It is currenly "..DCSEx.string.getTimeString() if Library.environment.isItNightTime() then weatherInfo = weatherInfo.." (night, sunrise at "..DCSEx.string.getTimeString(Library.environment.getDayTime(nil, false))..")\n" else weatherInfo = weatherInfo.." (day, sunset at "..DCSEx.string.getTimeString(Library.environment.getDayTime(nil, true))..")\n" end weatherInfo = weatherInfo.."- Average windspeed is "..tostring(DCSEx.floor(Library.environment.getWindAverage())).."m/s\n" local players = coalition.getPlayers(TUM.settings.getPlayerCoalition()) for _,p in ipairs(players) do TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(p), "atcWeatherUpdate", { weatherInfo }, "Control", delayRadioAnswer) end end end -- ==================================================================================== -- TUM.AIRFORCE - HANDLES THE FRIENDLY AND ENEMY COMBAT AIR PATROL -- ==================================================================================== -- ==================================================================================== TUM.airForce = {} do local desiredUnitCount = { 4, 4 } -- Desired max number of aircraft in the air at any single time local fighterGroups = { {}, {} } local playerCenter = nil local function getSkillLevel(side) -- Friendly AI is always excellent if side == TUM.settings.getPlayerCoalition() then return "Excellent" end local airForceLevel = TUM.settings.getValue(TUM.settings.id.ENEMY_AIR_FORCE) - 1 -- if airForceLevel <= 1 then return "Average" -- elseif airForceLevel == 2 then return DCSEx.table.getRandom({"Average", "Good"}) -- elseif airForceLevel == 3 then return DCSEx.table.getRandom({"Good", "High"}) -- else return DCSEx.table.getRandom({"High", "Excellent"}) -- end if airForceLevel <= 2 then return "Average" elseif airForceLevel == 3 then return DCSEx.table.getRandom({"Average", "Good"}) else return DCSEx.table.getRandom({"Good", "High", "Excellent"}) end end local function randomizeDesiredAircraftCount(side) local airForceLevel = 0 if side == TUM.settings.getPlayerCoalition() then if TUM.settings.getValue(TUM.settings.id.AI_CAP) == 1 then airForceLevel = 2 else airForceLevel = 0 end else airForceLevel = TUM.settings.getValue(TUM.settings.id.ENEMY_AIR_FORCE) - 1 end if airForceLevel == 0 then desiredUnitCount[side] = 0 else desiredUnitCount[side] = math.random(airForceLevel, math.ceil(airForceLevel * 1.5)) + 1 end end local function getAirborneUnitCount(side) local count = 0 for _,id in ipairs(fighterGroups[side]) do local g = DCSEx.world.getGroupByID(id) if g then count = count + g:getSize() end end return count end local function launchNewAircraftGroup(side, airbases) local groupSize = DCSEx.table.getRandom({ 1, 2, 2, 2, 2, 3, 3, 4 }) groupSize = math.min(groupSize, desiredUnitCount[side] - getAirborneUnitCount(side)) if groupSize <= 0 then return false end local faction = TUM.settings.getEnemyFaction() if side == TUM.settings.getPlayerCoalition() then faction = TUM.settings.getPlayerFaction() end local units = Library.factions.getUnits(faction, DCSEx.enums.unitFamily.PLANE_FIGHTER, groupSize, true) if not units or #units == 0 then return false end -- No aircraft found local launchAirbase = airbases[DCSEx.math.clamp(math.random(1, math.ceil(math.sqrt(#airbases))), 1, #airbases)] local originPt = DCSEx.math.vec3ToVec2(launchAirbase:getPoint()) local groupInfo = DCSEx.unitGroupMaker.create( side, Group.Category.AIRPLANE, originPt, units, { moveTo = DCSEx.math.randomPointInCircle(TUM.objectives.getCenter(), TUM.objectives.getRadius(), 0), silenced = true, skill = getSkillLevel(side), takeOff = true, taskCAP = true, unlimitedFuel = true }) if not groupInfo then return false end table.insert(fighterGroups[side], groupInfo.groupID) local players = coalition.getPlayers(TUM.settings.getPlayerCoalition()) if side == TUM.settings.getPlayerCoalition() then local newUnit = nil local newGroup = DCSEx.world.getGroupByID(groupInfo.groupID) if newGroup then newUnit = newGroup:getUnit(1) end local callsign = "FRIENDLY CAP" local typeName = "Fighter aircraft" if newUnit then callsign = newUnit:getCallsign() typeName = Library.objectNames.get(newUnit) end for _,p in ipairs(players) do local abInfo = launchAirbase:getName() abInfo = abInfo.." ("..DCSEx.dcs.getBRAA(launchAirbase:getPoint(), p:getPoint(), false, false, true).." from you)" TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(p), "pilotNewFriendlyAircraft", { typeName, abInfo }, callsign) end else for _,p in ipairs(players) do local abInfo = launchAirbase:getName() abInfo = abInfo.." ("..DCSEx.dcs.getBRAA(launchAirbase:getPoint(), p:getPoint(), false, false, true).." from you)" TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(p), "commandNewEnemyAircraft", { DCSEx.string.toStringNumber(groupSize), abInfo }, "Command") end end return true end local function updateAirForce(side) if desiredUnitCount[side] <= 0 then return false end -- No airforce if not TUM.DEBUG_MODE and #DCSEx.world.getPlayersInAir() == 0 then return false end -- No players currently in the air, don't spawn new AI aircraft (except in debug mode) local validAirbases = {} local airbases = coalition.getAirbases(side) for _,ab in pairs(airbases) do if ab:getDesc().category ~= Airbase.Category.SHIP then -- Ignore ships table.insert(validAirbases, ab) end end if not validAirbases or #validAirbases == 0 then return false end -- No airbases found for this coalition, nowhere to take off from if side == TUM.settings.getPlayerCoalition() then validAirbases = { DCSEx.dcs.getNearestObject(playerCenter, validAirbases) } else validAirbases = DCSEx.dcs.getNearestObjects(TUM.objectives.getCenter(), validAirbases) end local airborneUnitCount = getAirborneUnitCount(side) if airborneUnitCount < desiredUnitCount[side] then if math.random(1, 2 + math.ceil(airborneUnitCount / 2)) == 1 then if math.random(1, 4) then randomizeDesiredAircraftCount(side) end -- return launchNewAircraftGroup(side, airbases) return launchNewAircraftGroup(side, validAirbases) end end return false end ---------------------------------------------------------- -- Called on every mission update tick (every 10-20 seconds) -- @param side The side for which air force must be updated -- @return True if something was done this tick, false otherwise ---------------------------------------------------------- function TUM.airForce.onClockTick(side) if TUM.mission.getStatus() == TUM.mission.status.NONE then return false end -- Not currenly in a mission if TUM.objectives.getCount() <= 0 then return false end -- No objectives, nothing to defend for CAP return updateAirForce(side) end function TUM.airForce.create() TUM.airForce.removeAll() TUM.log("Creating friendly and enemy air forces...") for side=1,2 do randomizeDesiredAircraftCount(side) end end function TUM.airForce.removeAll() if #fighterGroups[1] > 0 or #fighterGroups[2] > 0 then TUM.log("Removing all friendly and enemy air force...") end for side=1,2 do for _,id in ipairs(fighterGroups[side]) do DCSEx.world.destroyGroupByID(id) end end fighterGroups = { {}, {} } end function TUM.airForce.onStartUp() playerCenter = DCSEx.envMission.getPlayerGroupsCenterPoint() if not playerCenter then playerCenter = { x = env.mission.map.centerX, y = env.mission.map.centerY } end -- TODO: build list of airbases now instead of of each update() (but what about destroyed airbases?) return true end end -- ==================================================================================== -- TUM.AMBIENTRADIO - HANDLES AMBIENT CHATTER/RADIO MESSAGES REACTING TO A MISSION EVENT -- ==================================================================================== -- (local) doAmbientChatter(stringID, callsign, minimumDelaySinceLastMessage, replacements, centerPoint, maxRadiusInNM) -- (local) onEventDead(event) -- (local) onEventEjection(event) -- (local) onEventHit(event) -- (local) onEventKill(event) -- (local) onEventLand(event) -- (local) onEventLandingAfterEjection(event) -- (local) onEventPlayerEnterUnit(event) -- (local) onEventShootingStart(event) -- (local) onEventShotFriendly(event) -- (local) onEventShotHostile(event) -- (local) onEventShot(event) -- (local) onEventTakeOff(event) -- TUM.ambientRadio.onEvent(event) -- ==================================================================================== TUM.ambientRadio = {} do local lastAmbientChatter = 0 local function getNearestFriendlyAircraft(point2) local units = {} local planeGroups = coalition.getGroups(TUM.settings.getPlayerCoalition(), Group.Category.AIRPLANE) for _,g in ipairs(planeGroups) do local groupUnits = g:getUnits() for _,u in ipairs(groupUnits) do table.insert(units, u) end end local heloGroups = coalition.getGroups(TUM.settings.getPlayerCoalition(), Group.Category.HELICOPTER) for _,g in ipairs(heloGroups) do local groupUnits = g:getUnits() for _,u in ipairs(groupUnits) do table.insert(units, u) end end if #units == 0 then return nil end return DCSEx.dcs.getNearestObject(point2, units) end ------------------------------------- -- Plays an ambient radio message ------------------------------------- -- @param messageID ID of the radio message in scrambe.db.radioMessages -- @param replacements String placeholders ($1, $2...) replacements in the message -- @param callsign (optional) Callsign of the caller unit -- @param minimumDelaySinceLastMessage (optional) If the last message happened less than this number of seconds from the current time, don't play the message -- @param replacements (optional) Table of strings to use as replacement for $1, $2, $3... -- @param centerPoint (optional) Center point used for max radius measurement -- @param maxRadiusInNM (optional) Maximum radius (in nm) beyond which units will not recieve the message ------------------------------------- local function doAmbientChatter(messageID, replacements, callsign, minimumDelaySinceLastMessage, centerPoint, maxRadiusInNM) if not callsign and centerPoint then local nearestAircraft = getNearestFriendlyAircraft(centerPoint) if nearestAircraft then callsign = nearestAircraft:getCallsign() else callsign = "AIRCRAFT" end end -- Check parameters callsign = callsign or "AIRCRAFT" minimumDelaySinceLastMessage = minimumDelaySinceLastMessage or 1 if maxRadiusInNM then maxRadiusInNM = DCSEx.converter.nmToMeters(maxRadiusInNM) end -- Don't play this message if another message was played too recently local currentTime = timer.getAbsTime() if currentTime < lastAmbientChatter + minimumDelaySinceLastMessage then return end lastAmbientChatter = currentTime local players = coalition.getPlayers(TUM.settings.getPlayerCoalition()) if not players or #players == 0 then return end for _,p in pairs(players) do local tooFar = false -- If the message is restricted to a given zone, make sure the player isn't too far if centerPoint and maxRadiusInNM then if DCSEx.math.getDistance2D(centerPoint, p:getPoint()) > maxRadiusInNM then tooFar = true end end if not tooFar then TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(p), messageID, replacements, callsign) end end end ---------------------------------------------- -- Called when a DEAD event happens -- -- @param event Event data ---------------------------------------------- local function onEventDead(event) if not event.initiator then return end -- No initiator if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Initiator isn't an unit if event.initiator:getCoalition() ~= TUM.settings.getPlayerCoalition() then return end -- Not a friendly local unitDesc = event.initiator:getDesc() if unitDesc.category == Unit.Category.AIRPLANE or unitDesc.category == Unit.Category.HELICOPTER then doAmbientChatter("commandFriendlyDown", { event.initiator:getCallsign() }, "COMMAND", 1) end end ---------------------------------------------- -- Called when an EJECTION event happens -- -- @param event Event data ---------------------------------------------- local function onEventEjection(event) if not event.initiator then return end -- No initator if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Initiator isn't an unit if event.initiator:getCoalition() ~= TUM.settings.getPlayerCoalition() then return end -- Initiator isn't a friendly if event.initiator:getPlayerName() then return end -- No "ejecting!" message for players, so it won't cut the "mission failed" music which is played at the same time if TUM.wingmen.getUnitWingmanNumber(event.initiator) then return end -- Wingmen have their own "I'm going down!" messages doAmbientChatter("pilotEjecting", nil, event.initiator:getCallsign(), 1) end ---------------------------------------------- -- Called when a HIT event happens -- -- @param event Event data ---------------------------------------------- local function onEventHit(event) if not event.target then return end -- No target if Object.getCategory(event.target) ~= Object.Category.UNIT then return end -- Target isn't an unit if event.target:getCoalition() ~= TUM.settings.getPlayerCoalition() then return end -- Target isn't a friendly -- Blue on blue event if event.initiator then if Object.getCategory(event.initiator) == Object.Category.UNIT then -- Attacker is an unit if event.initiator:getCoalition() == TUM.settings.getPlayerCoalition() then -- Attacker is a friendly doAmbientChatter("commandBlueOnBlue", nil, "COMMAND", 1) return end end end -- Friendly aircraft hit if event.target:getDesc().category == Unit.Category.AIRPLANE or event.target:getDesc().category == Unit.Category.HELICOPTER then if Object.getCategory(event.initiator) == Object.Category.UNIT then if not event.initiator:getPlayerName() then -- Players don't radio out when they're hit doAmbientChatter("pilotImHit", nil, event.target:getCallsign(), 3) end end end end ---------------------------------------------- -- Called when a KILL event happens -- -- @param event Event data ---------------------------------------------- local function onEventKill(event) if not event.target or not event.initiator then return end -- No event target or initiator if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Killer isn't an unit if event.initiator:getCoalition() ~= TUM.settings.getPlayerCoalition() then return end -- Killer isn't a friendly if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) and event.initiator:getPlayerName() then return end -- No player chatter in MP local targetDesc = event.target:getDesc() local killerName = nil if event.initiator:getCallsign() then killerName = event.initiator:getCallsign() else killerName = event.initiator:getName() end local killMessage = "pilotKillGround" if Object.getCategory(event.target) == Object.Category.SCENERY then if TUM.objectives.getSceneryObjectObjective(event.target) then doAmbientChatter("pilotKillStrike", nil, killerName, 1) else return -- Building was not a scenery target, congratulations you just bombed a random civilian structure lol end elseif Object.getCategory(event.target) == Object.Category.STATIC then killMessage = "pilotKillStrike" doAmbientChatter("pilotKillStrike", nil, killerName, 1) elseif Object.getCategory(event.target) == Object.Category.UNIT then local killUnitType = Library.objectNames.get(event.target) -- Library.objectNames.getGeneric(event.target) local minMessageInterval = 2 if targetDesc.category == Unit.Category.AIRPLANE then killMessage = "pilotKillAir" killUnitType = Library.objectNames.get(event.target) elseif targetDesc.category == Unit.Category.HELICOPTER then killMessage = "pilotKillAir" killUnitType = Library.objectNames.get(event.target) elseif targetDesc.category == Unit.Category.GROUND_UNIT then if event.target:hasAttribute("Infantry") then killMessage = "pilotKillInfantry" minMessageInterval = 4 else killMessage = "pilotKillGround" end elseif targetDesc.category == Unit.Category.SHIP then killMessage = "pilotKillShip" elseif targetDesc.category == Unit.Category.STRUCTURE then killMessage = "pilotKillStrike" end doAmbientChatter(killMessage, killUnitType, killerName, minMessageInterval) end end ---------------------------------------------- -- Called when a LAND event happens -- -- @param event Event data ---------------------------------------------- local function onEventLand(event) if not event.initiator then return end -- No event initiator if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Initiator isn't an unit if event.initiator:getCoalition() ~= TUM.settings.getPlayerCoalition() then return end -- Not a friendly local baseName = "AIRBASE" if event.place then baseName = event.place:getName():upper() end if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) or not event.initiator:getPlayerName() then doAmbientChatter("atcSafeLanding", {event.initiator:getCallsign(), baseName}, baseName.." ATC", 1) end end ---------------------------------------------- -- Called when a LANDING_AFTER_EJECTION event happens -- -- @param event Event data ---------------------------------------------- local function onEventLandingAfterEjection(event) if not event.initiator then return end -- No event initiator if event.initiator:getCoalition() ~= TUM.settings.getPlayerCoalition() then return end -- Not a friendly doAmbientChatter("commandFriendlyPilotOnGround", nil, "COMMAND", 1) end ---------------------------------------------- -- Called when a PLAYER_ENTER_UNIT event happens -- -- @param event Event data ---------------------------------------------- local function onEventPlayerEnterUnit(event) if not event.initiator then return end -- No event initiator -- TODO end ---------------------------------------------- -- Called when a SHOOTING_START event happens -- -- @param event Event data ---------------------------------------------- local function onEventShootingStart(event) if not event.initiator then return end -- No event initiator if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Initiator isn't an unit -- Plane or helicopter if event.initiator:getDesc().category == Unit.Category.AIRPLANE or event.initiator:getDesc().category == Unit.Category.HELICOPTER then if event.initiator:getCoalition() == TUM.settings.getPlayerCoalition() then if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) and event.initiator:getPlayerName() then return end -- No player chatter in MP doAmbientChatter("pilotLaunchGuns", nil, event.initiator:getCallsign(), 2) return end end -- AAA if event.initiator:hasAttribute("AAA") and event.initiator:getCoalition() == TUM.settings.getEnemyCoalition() then doAmbientChatter("pilotWarningAAA", nil, nil, 2, event.initiator:getPoint(), 8) return end end -------------------------------------------------------------- -- Called when a SHOT event happens, with a friendly initiator -- -- @param event Event data -------------------------------------------------------------- local function onEventShotFriendly(event) if not event.initiator then return end -- No event initiator if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Initiator isn't an unit local unitCategory = event.initiator:getDesc().category local weaponDesc = event.weapon:getDesc() if unitCategory == Unit.Category.AIRPLANE or unitCategory == Unit.Category.HELICOPTER then if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) and event.initiator:getPlayerName() then return end -- No player chatter in MP if weaponDesc.category == Weapon.Category.BOMB then doAmbientChatter("pilotLaunchPickle", nil, event.initiator:getCallsign(), 1) elseif weaponDesc.category == Weapon.Category.ROCKET then doAmbientChatter("pilotLaunchRocket", nil, event.initiator:getCallsign(), 1) elseif weaponDesc.category == Weapon.Category.MISSILE then if weaponDesc.missileCategory == Weapon.MissileCategory.AAM then if weaponDesc.guidance == Weapon.GuidanceType.IR then doAmbientChatter("pilotLaunchFox2", nil, event.initiator:getCallsign(), 1) elseif weaponDesc.guidance == Weapon.GuidanceType.RADAR_ACTIVE then doAmbientChatter("pilotLaunchFox3", nil, event.initiator:getCallsign(), 1) elseif weaponDesc.guidance == Weapon.GuidanceType.RADAR_SEMI_ACTIVE then doAmbientChatter("pilotLaunchFox1", nil, event.initiator:getCallsign(), 1) else doAmbientChatter("pilotLaunchRifle", nil, event.initiator:getCallsign(), 1) end elseif weaponDesc.missileCategory == Weapon.MissileCategory.ANTI_SHIP or weaponDesc.typeName == "weapons.missiles.AGM_84D" then doAmbientChatter("pilotLaunchBruiser", nil, event.initiator:getCallsign(), 1) elseif weaponDesc.guidance == Weapon.GuidanceType.RADAR_PASSIVE then doAmbientChatter("pilotLaunchMagnum", nil, event.initiator:getCallsign(), 1) else doAmbientChatter("pilotLaunchRifle", nil, event.initiator:getCallsign(), 1) end end -- elseif unitCategory == Unit.Category.GROUND_UNIT then -- if event.initiator:hasAttribute("MANPADS") then -- -- Do nothing, no message for MANPADS -- elseif event.initiator:hasAttribute("IR Guided SAM") then -- -- doAmbientChatter("Friendly SAM engaging", nil, "Air defense HQ", 2) -- elseif event.initiator:hasAttribute("SAM") then -- -- doAmbientChatter("Friendly SAM engaging", nil, "Air defense HQ", 2) -- end -- elseif unitCategory == Unit.Category.SHIP then -- TODO end end --------------------------------------------------------------------- -- Called when a SHOT event happens, with a hostile or neutral initiator -- -- @param event Event data --------------------------------------------------------------------- local function onEventShotHostile(event) if not event.initiator then return end -- No event initiator if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Initiator isn't an unit if event.initiator:getDesc().category == Unit.Category.AIRPLANE or event.initiator:getDesc().category == Unit.Category.HELICOPTER then -- if weaponDesc.category == Weapon.Category.MISSILE then -- if weaponDesc.missileCategory == Weapon.MissileCategory.AAM then -- doAmbientChatter("Missile!", nil, nil, 2, event.initiator:getPoint(), 8) -- end -- end elseif event.initiator:getDesc().category == Unit.Category.GROUND_UNIT or event.initiator:getDesc().category == Unit.Category.SHIP then if event.initiator:hasAttribute("MANPADS") then doAmbientChatter("pilotWarningMANPADS", nil, nil, 2, event.initiator:getPoint(), 8) elseif event.initiator:hasAttribute("IR Guided SAM") then doAmbientChatter("pilotWarningSAMLaunch", nil, nil, 2, event.initiator:getPoint(), 12) elseif event.initiator:hasAttribute("SAM SR") then doAmbientChatter("pilotWarningSAMLaunch", nil, nil, 2, event.initiator:getPoint(), 16) elseif event.initiator:hasAttribute("SAM") or event.initiator:hasAttribute("SAM LL") or event.initiator:hasAttribute("SAM CC") or event.initiator:hasAttribute("SAM LR") then doAmbientChatter("pilotWarningSAMLaunch", nil, nil, 2, event.initiator:getPoint(), 32) end end end ----------------------------------- -- Called when a SHOT event happens -- -- @param event Event data ----------------------------------- local function onEventShot(event) if not event.initiator then return end -- No event initiator if not event.weapon then return end -- No weapon shot, abort if event.initiator:getCoalition() == TUM.settings.getPlayerCoalition() then onEventShotFriendly(event) else onEventShotHostile(event) end end ---------------------------------------------- -- Called when a TAKEOFF event happens -- -- @param event Event data ---------------------------------------------- local function onEventTakeOff(event) if not event.initiator then return end -- No event initiator if event.initiator:getCoalition() ~= TUM.settings.getPlayerCoalition() then return end -- Not a friendly local airbaseName = "airbase" if event.place then airbaseName = event.place:getName() end local callsign = event.initiator:getCallsign() or "aircraft" doAmbientChatter("Fly safe, "..callsign.."!", nil, airbaseName) -- TODO: proper message end ------------------------------------- -- Called when an event is raised -- @param event The DCS World event ------------------------------------- function TUM.ambientRadio.onEvent(event) if event.id == world.event.S_EVENT_DEAD then onEventDead(event) elseif event.id == world.event.S_EVENT_EJECTION then onEventEjection(event) elseif event.id == world.event.S_EVENT_HIT then onEventHit(event) elseif event.id == world.event.S_EVENT_KILL then onEventKill(event) elseif event.id == world.event.S_EVENT_LAND then onEventLand(event) elseif event.id == world.event.S_EVENT_LANDING_AFTER_EJECTION then onEventLandingAfterEjection(event) -- elseif event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT then -- onEventPlayerEnterUnit(event) elseif event.id == world.event.S_EVENT_SHOOTING_START then onEventShootingStart(event) elseif event.id == world.event.S_EVENT_SHOT then onEventShot(event) -- elseif event.id == world.event.S_EVENT_TAKEOFF then -- onEventTakeOff(event) end end end -- ==================================================================================== -- TUM.AMBIENTWORLD - HANDLES LITTLE DETAILS DESIGNED TO MAKE THE GAME WORLD MORE ALIVE -- ==================================================================================== -- ==================================================================================== TUM.ambientWorld = {} do local groupIDs = {} --------------- -- CONSTANTS -- --------------- local ESCAPING_CREW_ONE_TIME_OUT_OF = 6 -- one time of out this number, crew will flee destroyed vehicles local function doSpawnEscapingCrew(point3) local options = { disableWeapons = true, hidden = true, invisible = true, moveBy = 250, spreadDistance = math.random(2, 3), } local unitTypes = Library.factions.getUnits(TUM.settings.getEnemyFaction(), DCSEx.enums.unitFamily.GROUND_INFANTRY, math.random(1, 3)) if not unitTypes or #unitTypes == 0 then return end local groupInfo = DCSEx.unitGroupMaker.create(TUM.settings.getEnemyCoalition(), Group.Category.GROUND, DCSEx.math.vec3ToVec2(point3), unitTypes, options) if groupInfo then table.insert(groupIDs, groupInfo.groupID) end end -- Called when a unit is destroyed local function onEventDead(event) if not event.initiator then return end -- Nothing was hit -- TODO: spawn from target scenery buildings and static structures if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Target wasn't an unit if event.initiator:getDesc().category ~= Unit.Category.GROUND_UNIT then return end -- Wasn't a ground unit if not event.initiator:hasAttribute("Vehicles") then return end -- Wasn't a vehicle if event.initiator:getCoalition() ~= TUM.settings.getEnemyCoalition() then return end -- Only spawn escaping crew from enemy vehicles if math.random(1, ESCAPING_CREW_ONE_TIME_OUT_OF) ~= 1 then return end -- Do not spawn every time TUM.log("Spawning crew escaping from destroyed unit "..event.initiator:getName()) timer.scheduleFunction( doSpawnEscapingCrew, event.initiator:getPoint(), timer.getTime() + math.random(4, 7) ) end function TUM.ambientWorld.removeAll() for _,id in ipairs(groupIDs) do DCSEx.world.destroyGroupByID(id) end groupIDs = {} end ------------------------------------- -- Called when an event is raised -- @param event The DCS World event ------------------------------------- function TUM.ambientWorld.onEvent(event) if not event then return end -- No event if event.id == world.event.S_EVENT_DEAD then onEventDead(event) end end end -- ==================================================================================== -- TUM.DEBUGMENU - HANDLES THE F10 DEBUG MENU -- ==================================================================================== -- (local) doMarkersBoom() -- TUM.debugMenu.onStartUp() -- ==================================================================================== TUM.debugMenu = {} do local function doMarkersAirBoom() local panels = world.getMarkPanels() local boomCount = 0 for _,p in pairs(panels) do local nearestPoint = nil local nearestDistance = 99999999 if p.text:lower() == "airboom" then for _,c in pairs({ Unit.Category.AIRPLANE, Unit.Category.HELICOPTER}) do for _,u in DCSEx.world.getAllUnits(nil, c) do local distance = DCSEx.math.getDistance3D(p.pos, u:getPoint()) if distance < nearestDistance then nearestDistance = distance nearestPoint = u:getPoint() end end end if nearestPoint then trigger.action.explosion(nearestPoint, 1024) boomCount = boomCount + 1 end end end TUM.log("Detonated "..tostring(boomCount).. " \"airboom\" marker(s).") end local function doMarkersBoom() local panels = world.getMarkPanels() local boomCount = 0 for _,p in pairs(panels) do if p.text:lower() == "boom" then trigger.action.explosion(p.pos, 8192) boomCount = boomCount + 1 end end TUM.log("Detonated "..tostring(boomCount).. " \"boom\" marker(s).") end local function doAwardPointsAndObjectives() TUM.playerScore.award(100, "debug cheat") TUM.playerScore.awardCompletedObjective() end local function doSimulatePlayerTakeOff() local playerUnit = coalition.getPlayers(TUM.settings.getPlayerCoalition())[1] local takeOffEvent = { id = world.event.S_EVENT_TAKEOFF, initiator = playerUnit } TUM.onEvent(takeOffEvent) end local function doSimulatePlayerLanding() local playerUnit = coalition.getPlayers(TUM.settings.getPlayerCoalition())[1] local runwayTouchEvent = { id = world.event.S_EVENT_RUNWAY_TOUCH, initiator = playerUnit } TUM.onEvent(runwayTouchEvent) local landingEvent = { id = world.event.S_EVENT_LAND, initiator = playerUnit } timer.scheduleFunction(TUM.onEvent, landingEvent, timer.getTime() + 1) end local function doSendWingmenToMarker() if TUM.wingmenTasking.commandGoToMapMarker(nil, false) then TUM.log("Wingmen moving to FLIGHT marker") else TUM.log("Failed to move wingmen to FLIGHT marker") end end local function doKillWingman() local wingGroup = TUM.wingmen.getGroup() if not wingGroup then return end local units = wingGroup:getUnits() for _,u in ipairs(units) do trigger.action.explosion(u:getPoint(), 10) return end end function TUM.debugMenu.createMenu() if not TUM.DEBUG_MODE then return end local rootMenu = missionCommands.addSubMenu("[DEBUG]", TUM.getOrCreateRootMenu()) missionCommands.addCommand("Detonate - BOOM map markers", rootMenu, doMarkersBoom, nil) missionCommands.addCommand("Detonate - AIRBOOM map markers", rootMenu, doMarkersAirBoom, nil) missionCommands.addCommand("Wingman - kill", rootMenu, doKillWingman, nil) missionCommands.addCommand("Wingman - go to FLIGHT marker", rootMenu, doSendWingmenToMarker, nil) missionCommands.addCommand("Player - simulate takeoff", rootMenu, doSimulatePlayerTakeOff, nil) missionCommands.addCommand("Player - simulate landing", rootMenu, doSimulatePlayerLanding, nil) missionCommands.addCommand("Scoring - award 100 points and 1 objective", rootMenu, doAwardPointsAndObjectives, nil) missionCommands.addCommand("Scoring - reset flight log", rootMenu, TUM.playerCareer.reset, nil) end end -- ==================================================================================== -- TUM.ENEMYAIRDEFENSE - HANDLES THE OPFOR AIR DEFENSE -- ==================================================================================== -- (local) addSAMCoverage(point2) -- (local) isPointCoveredBySAM(point2) -- (local) createEnemyStrategicAirDefense() -- (local) createEnemyScatteredAirDefense() -- TUM.enemyAirDefense.onStartUp() -- ==================================================================================== TUM.enemyAirDefense = {} do local AIR_DEFENSE_RANGE = { -- in meters [DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS] = 750, [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_STATIC] = 1500, [DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE] = 1500, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR] = 6000, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT] = 8000, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM] = 35000, [DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG] = 70000, } local airDefenseGroups = {} -- Stores info about all air defense groups (groupID, point2, range and unitFamily) local function getPointDefenseFamily(forceSHORAD) local airDefenseLevel = TUM.settings.getValue(TUM.settings.id.ENEMY_AIR_DEFENSE) - 1 if airDefenseLevel > 1 and forceSHORAD then return DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT end if airDefenseLevel <= 1 then return DCSEx.table.getRandom({DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE, DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR}) elseif airDefenseLevel == 2 then return DCSEx.table.getRandom({DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE, DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT}) elseif airDefenseLevel == 3 then return DCSEx.table.getRandom({DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT}) else return DCSEx.table.getRandom({DCSEx.enums.unitFamily.AIRDEFENSE_AAA_MOBILE, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT_IR, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_SHORT}) end end local function getSkillLevel() local airDefenseLevel = TUM.settings.getValue(TUM.settings.id.ENEMY_AIR_DEFENSE) - 1 if airDefenseLevel <= 1 then return "Average" elseif airDefenseLevel == 2 then return DCSEx.table.getRandom({"Average", "Good", "Good", "High"}) elseif airDefenseLevel == 3 then return DCSEx.table.getRandom({"High", "Excellent"}) else return "Excellent" end end local function getEnemyPointUnitsProtectingPoint(point2) local count = 0 for _,adg in ipairs(airDefenseGroups) do if DCSEx.math.getDistance2D(adg.point2, point2) < adg.range then count = count + 1 end end return count end local function addAirDefenseGroup(side, faction, unitFamily, point) if not point then return end -- Make sure no air defense unit is spawned in range of an allied player for _,p in ipairs(coalition.getPlayers(TUM.settings.getPlayerCoalition())) do if DCSEx.math.getDistance2D(point, DCSEx.math.vec3ToVec2(p:getPoint())) < AIR_DEFENSE_RANGE[unitFamily] then return false end end local units = Library.factions.getUnits(faction, unitFamily, 1) if not units or #units == 0 then return false end -- No valid units found local skill = getSkillLevel() if unitFamily == DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS then skill = "Average" end -- MANPADS are too good in DCS, nerf them a little local groupInfo = DCSEx.unitGroupMaker.create(side, Group.Category.GROUND, point, units, { skill = skill }) if not groupInfo then return false end -- Failed to create group local adGroup = { groupID = groupInfo.groupID, point2 = point, range = AIR_DEFENSE_RANGE[unitFamily], unitFamily = unitFamily } table.insert(airDefenseGroups, adGroup) return true end local function createPointAirDefense(airDefenseLevel, side, faction) -- Add point air defense near all objectives for i=1,TUM.objectives.getCount() do local objPoint2 = TUM.objectives.getObjective(i).point2 -- Objective location local desiredCount = math.random(math.floor(airDefenseLevel / 3), math.ceil(airDefenseLevel / 1.5)) -- Number of desired point air defense groups for this objective -- local desiredCount = math.random(math.floor(airDefenseLevel / 2), math.ceil(airDefenseLevel / 1.25)) -- Number of desired point air defense groups for this objective local adCount = desiredCount - getEnemyPointUnitsProtectingPoint(objPoint2) -- Number of point air defense groups already defending this objective local realCount = 0 if adCount > 0 then -- Not enough groups? Create a few to reach the desired number for j=1,adCount do local forceSHORAD = false -- if j == 1 then forceSHORAD = (math.random(1, 2) == 1) end if j == 1 then forceSHORAD = (math.random(1, 5) <= 2) end local unitFamily = getPointDefenseFamily(forceSHORAD) local point = DCSEx.math.randomPointInCircle(objPoint2, AIR_DEFENSE_RANGE[unitFamily], AIR_DEFENSE_RANGE[unitFamily] / 2, land.SurfaceType.LAND) if addAirDefenseGroup(side, faction, unitFamily, point) then realCount = realCount + 1 else TUM.log("Failed to add point air defense group near objective "..TUM.objectives.getObjective(i).name..".", TUM.logLevel.WARNING) end end end TUM.log(string.format("Spawned %d air defense unit(s) near objective %s.", realCount, TUM.objectives.getObjective(i).name)) end end local function createLocalAirDefense(airDefenseLevel, side, faction, objectivesCenter, objectivesRadius) -- local count = math.ceil(math.random(2, 3) * math.max(1, math.sqrt(objectivesRadius) / 200) * math.sqrt(airDefenseLevel)) local count = math.ceil(math.random(2, 3) * math.max(1, math.sqrt(objectivesRadius) / 300) * math.sqrt(airDefenseLevel)) if count <= 0 then return end local realCount = 0 for i=1,count do local forceSHORAD = false -- if i <= math.max(1, count / 4) then forceSHORAD = true end if i <= math.max(1, count / 6) then forceSHORAD = true end local unitFamily = getPointDefenseFamily(forceSHORAD) local point = DCSEx.math.randomPointInCircle(objectivesCenter, objectivesRadius, 0, land.SurfaceType.LAND) if addAirDefenseGroup(side, faction, unitFamily, point) then realCount = realCount + 1 else TUM.log("Failed to add local air defense group.", TUM.logLevel.WARNING) end end TUM.log(string.format("Spawned %d air defense unit(s) around the objectives.", realCount)) end local function createMANPADs(airDefenseLevel, side, faction, objectivesCenter, objectivesRadius) -- local count = math.ceil(math.random(2, 3) * math.max(1, math.sqrt(objectivesRadius) / 120) * math.sqrt(airDefenseLevel)) local count = math.ceil(math.random(2, 3) * math.max(1, math.sqrt(objectivesRadius) / 250) * math.sqrt(airDefenseLevel)) if count <= 0 then return end local realCount = 0 for _=1,count do local point = DCSEx.math.randomPointInCircle(objectivesCenter, objectivesRadius, 0, land.SurfaceType.LAND) if addAirDefenseGroup(side, faction, DCSEx.enums.unitFamily.AIRDEFENSE_MANPADS, point) then realCount = realCount + 1 else TUM.log("Failed to add local MANPADS group.", TUM.logLevel.WARNING) end end TUM.log(string.format("Spawned %d MANPADS around the objectives.", realCount)) end local function addStrategicSAMSite(side, faction, unitFamily, objectivesCenter, objectivesRadius) local point = DCSEx.math.randomPointInCircle(objectivesCenter, objectivesRadius) if point then local zoneCenter = TUM.territories.getRandomPointInTerritory(side, land.SurfaceType.LAND) if not zoneCenter then zoneCenter = TUM.territories.getRandomPointInTerritory(side) end if not zoneCenter then zoneCenter = DCSEx.table.getRandom(TUM.territories.getTerritoryZones(side)) end local vector = { x = zoneCenter.x - point.x, y = zoneCenter.y - point.y } vector = DCSEx.math.normalizeVec2(vector) local distance = math.floor(DCSEx.math.getDistance2D(zoneCenter, point) * 2) local step = math.min(distance / 10, 2500) for __=0,distance,step do point.x = point.x + vector.x * step point.y = point.y + vector.y * step if TUM.territories.getPointOwner(point) == side and land.getSurfaceType(point) == land.SurfaceType.LAND then local distanceToObjectives = DCSEx.math.getDistance2D(objectivesCenter, point) if distanceToObjectives > AIR_DEFENSE_RANGE[unitFamily] * 2 then return false end -- Went too far, no need to spawn a SAM site here, it will never engage the players and only eat up CPU if distanceToObjectives > AIR_DEFENSE_RANGE[unitFamily] / 2 then return addAirDefenseGroup(side, faction, unitFamily, point) end end end end return false end local function createStrategicAirDefense(airDefenseLevel, side, faction, objectivesCenter, objectivesRadius) if airDefenseLevel <= 1 then return end local count = math.random(1, math.ceil(airDefenseLevel / 1.5)) local realCount = 0 local rerollsLeft = 5 for i=1,count do local unitFamily = DCSEx.table.getRandom({DCSEx.enums.unitFamily.AIRDEFENSE_SAM_MEDIUM, DCSEx.enums.unitFamily.AIRDEFENSE_SAM_LONG}) if addStrategicSAMSite(side, faction, unitFamily, objectivesCenter, objectivesRadius) then realCount = realCount + 1 elseif rerollsLeft > 0 then -- Small chance to retry if couldn't spawn the SAM site last time if math.random(1, 3) == 1 then i = i - 1 rerollsLeft = rerollsLeft - 1 end end end TUM.log(string.format("Spawned %d strategic SAM(s) on enemy territory.", realCount)) end function TUM.enemyAirDefense.create() TUM.enemyAirDefense.removeAll() -- Destroy all pre-existing air defense TUM.log("Creating enemy air defense...") if TUM.objectives.getCount() == 0 then return end -- No objectives, no air defense local airDefenseLevel = TUM.settings.getValue(TUM.settings.id.ENEMY_AIR_DEFENSE) - 1 if airDefenseLevel <= 0 then return end -- No surface-to-air defense at all if TUM.settings.getValue(TUM.settings.id.TASKING) == DCSEx.enums.taskFamily.ANTISHIP then return end -- No ground air defense during antiship strikes local side = TUM.settings.getEnemyCoalition() local faction = TUM.settings.getEnemyFaction() local objectivesCenter = TUM.objectives.getCenter() local objectivesRadius = TUM.objectives.getRadius() createPointAirDefense(airDefenseLevel, side, faction) -- Must be created before the other layers, else it may think objective sites are already protected and fail to generate point defense createLocalAirDefense(airDefenseLevel, side, faction, objectivesCenter, objectivesRadius) createMANPADs(airDefenseLevel, side, faction, objectivesCenter, objectivesRadius) createStrategicAirDefense(airDefenseLevel, side, faction, objectivesCenter, objectivesRadius) end function TUM.enemyAirDefense.removeAll() if #airDefenseGroups > 0 then TUM.log("Removing all enemy air defense...") end for _,g in ipairs(airDefenseGroups) do DCSEx.world.destroyGroupByID(g.groupID) end airDefenseGroups = {} end end -- ==================================================================================== -- TUM.INTERMISSION - HANDLES THE MENU DISPLAYED BETWEEN MISSIONS -- ==================================================================================== -- TUM.intermission.createMenu() -- TUM.intermission.onInitialize() -- ==================================================================================== TUM.intermission = {} do local missionZonesMarkers = {} local function doCommandStartMission() local players = DCSEx.world.getAllPlayers() if #players == 0 then trigger.action.outText("No player slots occupied. At least one client slot must be occupied by a player to start the mission.", 5) trigger.action.outSound("UI-Error.ogg") return end if not TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then for _,p in ipairs(players) do if p:inAir() then trigger.action.outText("Cannot start a single player mission while the player is in the air. Please land before starting the mission.", 5) trigger.action.outSound("UI-Error.ogg") return end end end trigger.action.outText("Generating mission and loading assets, this can take some time...", 5) -- Add a little delay for the "Generating mission..." message be printed out. Once generation begins, the main DCS thread will be to busy to output anything. timer.scheduleFunction(TUM.mission.beginMission, false, timer.getTime() + 1) end local function setSetting(args) if not args.id or not args.value then return end TUM.settings.setValue(args.id, args.value, false) TUM.intermission.createMenu() end local function createSubMenu(id, parentMenu) local rootMenu = nil rootMenu = missionCommands.addSubMenu(TUM.settings.getSettingsName(id)..": "..TUM.settings.getValue(id, true), parentMenu) for i,v in ipairs(TUM.settings.getPossibleValues(id)) do local commandText = v if id == TUM.settings.id.TARGET_LOCATION then local playerCenter = DCSEx.world.getUnitsCenter(DCSEx.world.getAllPlayers()) local distance = math.floor(DCSEx.converter.metersToNM(DCSEx.math.getDistance2D(playerCenter, DCSEx.zones.getByName(v)))) commandText = commandText.."(≈"..tostring(distance).." nm)" end missionCommands.addCommand(commandText, rootMenu, setSetting, { id = id, value = i, redrawMenu = true }) end end function TUM.intermission.createMissionZonesMarkers() TUM.intermission.removeMissionZonesMarkers() local missionZones = TUM.territories.getMissionZones() for _,z in ipairs(missionZones) do local zoneOwner = TUM.territories.getPointOwner(z) local color = DCSEx.dcs.getCoalitionColor(zoneOwner) local ids = DCSEx.zones.drawOnMap(z, { color[1], color[2], color[3], 1 }, { color[1], color[2], color[3], .5 }, DCSEx.enums.lineType.SOLID, true, true) if ids then table.insert(missionZonesMarkers, ids[1]) table.insert(missionZonesMarkers, ids[2]) end end end function TUM.intermission.removeMissionZonesMarkers() for _,id in ipairs(missionZonesMarkers) do trigger.action.removeMark(id) end missionZonesMarkers = {} end ------------------------------------- -- Creates the mission briefing menu ------------------------------------- function TUM.intermission.createMenu() local rootMenu = TUM.getOrCreateRootMenu(true) -- Clear the menu local briefingText = "Welcome to The Universal Mission for DCS World, a highly customizable mission available for single-player and PvE.\n\nOpen the communication menu and select the ''F10. Other'' option to access mission settings." DCSEx.envMission.setBriefing(coalition.side.RED, briefingText) DCSEx.envMission.setBriefing(coalition.side.BLUE, briefingText) TUM.intermission.createMissionZonesMarkers() -- Show the available mission zones on the F10 map missionCommands.addCommand("ℹ Display mission settings", rootMenu, TUM.settings.printSettingsSummary, false) local settingsMenu = missionCommands.addSubMenu("✎ Change mission settings", rootMenu) createSubMenu(TUM.settings.id.COALITION_BLUE, settingsMenu) createSubMenu(TUM.settings.id.COALITION_RED, settingsMenu) createSubMenu(TUM.settings.id.TASKING, settingsMenu) createSubMenu(TUM.settings.id.TARGET_LOCATION, settingsMenu) createSubMenu(TUM.settings.id.TARGET_COUNT, settingsMenu) createSubMenu(TUM.settings.id.ENEMY_AIR_DEFENSE, settingsMenu) createSubMenu(TUM.settings.id.ENEMY_AIR_FORCE, settingsMenu) createSubMenu(TUM.settings.id.WINGMEN, settingsMenu) createSubMenu(TUM.settings.id.AI_CAP, settingsMenu) TUM.playerCareer.createMenu() missionCommands.addCommand("➤ Begin mission", rootMenu, doCommandStartMission, nil) TUM.debugMenu.createMenu() -- Append debug menu to other menus (if debug mode enabled) end ------------------------------------- -- Called on mission start up -- @return True if started up properly, false if an error happened ------------------------------------- function TUM.intermission.onStartUp() TUM.intermission.createMenu() -- Create the briefing menu return true end end -- ==================================================================================== -- TUM.MISSION - HANDLES THE MAIN MISSION -- ==================================================================================== -- ==================================================================================== TUM.mission = {} TUM.mission.status = { NONE = 0, IN_PROGRESS = 1, COMPLETED = 2, FAILED = 3, } TUM.mission.endCause = { -- Why did the mission end? ABORTED = 1, COMPLETED = 2, FAILED = 3 } do local OBJECTIVES_REMINDER_INTERVAL = 5 local missionStatus = TUM.mission.status.NONE local objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL function TUM.mission.getStatus() return missionStatus end local function closeMission(removeAllUnits) if removeAllUnits then TUM.wingmen.removeAll() TUM.airForce.removeAll() TUM.ambientWorld.removeAll() TUM.enemyAirDefense.removeAll() TUM.objectives.removeAll() end missionStatus = TUM.mission.status.NONE TUM.intermission.createMenu() end function TUM.mission.checkMissionStatus(silent) silent = silent or false if missionStatus ~= TUM.mission.status.IN_PROGRESS then return end if TUM.objectives.areAllCompleted() then missionStatus = TUM.mission.status.COMPLETED DCSEx.dcs.outPicture("Pic-MissionComplete.png", 5, true, 0, 1, 1, 25, 1) trigger.action.outSound("UI-MissionEnd.ogg") if not silent then TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "commandMissionComplete", nil, "Command", true) end end end function TUM.mission.beginMission(silent) silent = silent or false closeMission(true) TUM.intermission.removeMissionZonesMarkers() for _=1,TUM.settings.getValue(TUM.settings.id.TARGET_COUNT) do TUM.objectives.add() end if TUM.objectives.getCount() == 0 then TUM.log("Couldn't create any objective, mission creation failed.", TUM.logLevel.WARNING) closeMission(true) return end TUM.supportAWACS.create() -- Create the AWACS aircraft if it wasn't airborne already TUM.enemyAirDefense.create() -- Must be called once objectives have been created TUM.airForce.create() -- Must be called once objectives have been created TUM.missionMenu.create() -- Must be called once objectives have been created local briefingOrder = DCSEx.table.shuffle({1, 2, 3, 4, 5}) -- Just to make sure the same description is used twice local briefingText = "" for i=1,TUM.objectives.getCount() do local obj = TUM.objectives.getObjective(i) briefingText = briefingText.."Objective "..obj.name..":\n" local descriptions = Library.tasks[obj.taskID].description.briefing briefingText = briefingText..descriptions[DCSEx.math.clamp(briefingOrder[i], 1, #descriptions)] if i < TUM.objectives.getCount() then briefingText = briefingText.."\n\n" end end DCSEx.envMission.setBriefing(TUM.settings.getPlayerCoalition(), briefingText) DCSEx.envMission.setBriefing(TUM.settings.getEnemyCoalition(), "") missionStatus = TUM.mission.status.IN_PROGRESS if not silent then DCSEx.dcs.outPicture("Pic-MissionStart.png", 5, true, 0, 1, 1, 25, 1) trigger.action.outSound("UI-MissionStart.ogg") end trigger.action.outText("MISSION OBJECTIVES:\n\n"..TUM.mission.getSummaryString(), 10) objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL end function TUM.mission.getPlayerCallsign() local player = world.getPlayer() if player then return player:getCallsign() end return "Flight" end function TUM.mission.getSummaryString(onlyShowIncomplete, doublePercentage) onlyShowIncomplete = onlyShowIncomplete or false if missionStatus == TUM.mission.status.NONE then return "" end local missionSummary = "" local validObjCount = 1 for i=1,TUM.objectives.getCount() do local o = TUM.objectives.getObjective(i) if o then if not o.completed or not onlyShowIncomplete then local bulletCharacter = "⬤" if validObjCount == 1 then bulletCharacter = "❶" elseif validObjCount == 2 then bulletCharacter = "❷" elseif validObjCount == 3 then bulletCharacter = "❸" elseif validObjCount == 4 then bulletCharacter = "❹" elseif validObjCount == 5 then bulletCharacter = "❺" elseif validObjCount == 6 then bulletCharacter = "❻" elseif validObjCount == 7 then bulletCharacter = "❼" elseif validObjCount == 8 then bulletCharacter = "❽" elseif validObjCount == 9 then bulletCharacter = "❾" elseif validObjCount == 10 then bulletCharacter = "❿" end missionSummary = missionSummary..bulletCharacter.." Objective "..o.name..": "..Library.tasks[o.taskID].description.short if not o.completed then missionSummary = missionSummary.." ("..TUM.objectives.getObjectiveProgress(i, doublePercentage)..")" else missionSummary = missionSummary.." [DONE!]" end if i < TUM.objectives.getCount() then missionSummary = missionSummary.."\n" end validObjCount = validObjCount + 1 end end end return missionSummary end function TUM.mission.endMission(endCause) endCause = endCause or TUM.mission.endCause.ABORTED if endCause == TUM.mission.endCause.ABORTED then DCSEx.dcs.outPicture("Pic-MissionAborted.png", 5, true, 0, 1, 1, 25, 1) TUM.playerScore.reset(true, "mission aborted") elseif endCause == TUM.mission.endCause.COMPLETED then DCSEx.dcs.outPicture("Pic-MissionComplete.png", 5, true, 0, 1, 1, 25, 1) elseif endCause == TUM.mission.endCause.FAILED then DCSEx.dcs.outPicture("Pic-MissionFailed.png", 5, true, 0, 1, 1, 25, 1) end trigger.action.outSound("UI-MissionEnd.ogg") closeMission(true) end ---------------------------------------------------------- -- Called on every mission update tick (every 15 seconds) -- @return True if a radio message or other output was triggered, false otherwise ---------------------------------------------------------- function TUM.mission.onClockTick() if TUM.mission.getStatus() == TUM.mission.status.NONE then return false end -- Not currenly in a mission if TUM.objectives.getCount() <= 0 then return false end -- No objectives objectivesReminderIntervalLeft = objectivesReminderIntervalLeft - 1 if objectivesReminderIntervalLeft > 0 then return false end objectivesReminderIntervalLeft = OBJECTIVES_REMINDER_INTERVAL TUM.mission.playMissionSummaryRadioMessage(true, false) return true end ------------------------------------- -- Called when an event is raised -- @param event The DCS World event ------------------------------------- function TUM.mission.onEvent(event) if missionStatus == TUM.mission.status.NONE then return end if not event.initiator then return end if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end if not event.initiator:getPlayerName() then return end -- All objectives complete and all players on the ground? Mission is complete if event.id == world.event.S_EVENT_RUNWAY_TOUCH or event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT or event.id == world.event.S_EVENT_PLAYER_LEAVE_UNIT then if TUM.objectives.areAllCompleted() and #DCSEx.world.getPlayersInAir(TUM.settings.getPlayerCoalition()) == 0 then TUM.mission.endMission(TUM.mission.endCause.COMPLETED) end end if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- When player dies in single-player, fail the mission if event.id == world.event.S_EVENT_CRASH or event.id == world.event.S_EVENT_EJECTION or event.id == world.event.S_EVENT_PILOT_DEAD then TUM.mission.endMission(TUM.mission.endCause.FAILED) end end function TUM.mission.playMissionSummaryRadioMessage(onlyShowIncomplete, delayed) onlyShowIncomplete = onlyShowIncomplete or false delayed = delayed or false local incompleteObjectives = TUM.objectives.getCount() - TUM.objectives.getCompletedCount() local messageID = "commandMissionComplete" if incompleteObjectives > 1 then messageID = "commandObjectivesManyLeft" elseif incompleteObjectives == 1 then messageID = "commandObjectivesOneLeft" end TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), messageID, { TUM.mission.getSummaryString(onlyShowIncomplete, true) }, "COMMAND", delayed) end end -- ==================================================================================== -- TUM.MISSION - HANDLES THE F10 MENU DISPLAYED DURING A MISSION -- ==================================================================================== -- ==================================================================================== TUM.missionMenu = {} do local function doCommandAbortMission() TUM.mission.endMission(TUM.mission.endCause.ABORTED) end local function doCommandMissionStatus() TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "playerCommandMissionStatus", nil, TUM.mission.getPlayerCallsign(), false) TUM.mission.playMissionSummaryRadioMessage(false, true) end local function doCommandNearestAirbase() TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "playerATCRequireNearestAirbase", nil, TUM.mission.getPlayerCallsign(), false) TUM.atc.requestNavAssistanceToAirbase(false) end local function doCommandObjectiveLocation(index) local obj = TUM.objectives.getObjective(index) if not obj then return end TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "playerCommandRequireObjectives", { obj.name }, TUM.mission.getPlayerCallsign(), false) TUM.atc.requestNavAssistanceToObjective(index, true) end local function doCommandWeatherUpdate() TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "playerATCWeatherUpdate", nil, TUM.mission.getPlayerCallsign(), false) TUM.atc.requestWeatherUpdate(false) end function TUM.missionMenu.create() local rootMenu = TUM.getOrCreateRootMenu(true) -- Clear the menu missionCommands.addCommand("☱ Mission status", rootMenu, doCommandMissionStatus, nil) local objectivesMenuRoot = missionCommands.addSubMenu("❖ Objectives", rootMenu) local navigationMenuRoot = missionCommands.addSubMenu("➽ Navigation", rootMenu) -- missionCommands.addCommand("Nav to nearest airbase", navigationMenuRoot, doCommandNearestAirbase, nil) for i=1,TUM.objectives.getCount() do local obj = TUM.objectives.getObjective(i) if obj then local objNameAndDescription = obj.name.." ("..Library.tasks[obj.taskID].description.short..")" local objRoot = missionCommands.addSubMenu("Objective "..objNameAndDescription, objectivesMenuRoot) TUM.supportJTAC.setupJTACOnObjective(i, objRoot) missionCommands.addCommand("Nav to objective "..objNameAndDescription, navigationMenuRoot, doCommandObjectiveLocation, i) end end -- missionCommands.addCommand("Weather update", navigationMenuRoot, doCommandWeatherUpdate, nil) TUM.wingmenMenu.create() TUM.supportAWACS.createMenu() if not TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then -- If not multiplayer, add "show mission score" command missionCommands.addCommand("★ Display mission score", rootMenu, TUM.playerScore.showScore, nil) end local abortRoot = missionCommands.addSubMenu("⬣ Abort mission", rootMenu) if not TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) and DCSEx.io.canReadAndWrite() then missionCommands.addCommand("✓ Confirm (all xp since last landing will be lost!)", abortRoot, doCommandAbortMission, nil) else missionCommands.addCommand("✓ Confirm", abortRoot, doCommandAbortMission, nil) end missionCommands.addCommand("✕ Cancel", abortRoot, DCSEx.dcs.doNothing, nil) TUM.debugMenu.createMenu() -- Append debug menu to other menus (if debug mode enabled) end end -- ==================================================================================== -- TUM.MIZCLEANER - REMOVED UNWANTED UNIT GROUPS FROM THE MIZ FILE -- ==================================================================================== -- (local) removeAIAircraftOnLandEvent(event) -- (local) removeAIWingmen() -- TUM.mizCleaner.onStartUp() -- TUM.mizCleaner.onEvent(event) -- ==================================================================================== TUM.mizCleaner = {} do ------------------------------------- -- If event is an AI aircraft land event, remove it so it "frees room" (e.g. don't occupy an "air force unit" slot) for new aircraft -- @param event A DCS World event, possibly a S_EVENT_LAND event ------------------------------------- local function removeAIAircraftOnLandEvent(event) if event.id ~= world.event.S_EVENT_LAND then return end if not event.initiator then return end if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end -- Not an unit if event.initiator:getPlayerName() then return end -- Don't remove player aircraft, that would cause horrendous bugs event.initiator:destroy() end ------------------------------------- -- Removes all AI wingmen units ------------------------------------- local function removeAIWingmen() local groups = DCSEx.envMission.getGroups(TUM.settings.getPlayerCoalition()) local aiWingMenToRemove = {} for _,g in ipairs(groups) do if g.units then local isPlayerGroup = false for _,u in ipairs(g.units) do if u.skill == "Player" or u.skill == "Client" then isPlayerGroup = true end end if isPlayerGroup then for _,u in ipairs(g.units) do if u.skill ~= "Player" and u.skill ~= "Client" then table.insert(aiWingMenToRemove, u.unitId) end end end end end if #aiWingMenToRemove > 0 then for _,id in ipairs(aiWingMenToRemove) do local u = DCSEx.world.getUnitByID(id) if u then u:destroy() end end TUM.log("Removed "..tostring(#aiWingMenToRemove).." AI wingmen from the mission.\nPlease do not add AI wingmen to the mission, The Universal Mission uses its own wingman system.", TUM.logLevel.WARNING) end end ------------------------------------- -- Called on mission start up -- @return True if started up properly, false if an error happened ------------------------------------- function TUM.mizCleaner.onStartUp() removeAIWingmen() return true end ------------------------------------- -- Called when an event is raised -- @param event The DCS World event ------------------------------------- function TUM.mizCleaner.onEvent(event) removeAIAircraftOnLandEvent(event) end end -- ==================================================================================== -- TUM.OBJECTIVES - HANDLES THE MISSION OBJECTIVES -- ==================================================================================== -- ==================================================================================== TUM.objectives = {} do local objectives = {} local function updateObjectiveText(index) if index < 1 or index > #objectives then return end local taskDB = Library.tasks[objectives[index].taskID] local suffix = "" if DCSEx.table.contains(taskDB.flags, DCSEx.enums.taskFlag.MOVING) then suffix = "\n(last position known to intel, target is moving)" end local text = "Objective "..objectives[index].name..":\n"..taskDB.description.short.." ("..TUM.objectives.getObjectiveProgress(index)..")"..suffix trigger.action.setMarkupText(objectives[index].markerTextID, text) end function TUM.objectives.add() local objective = TUM.objectivesMaker.create() if not objective then TUM.log("Failed to spawn a group for objective #"..tostring(#objectives + 1)..".", TUM.logLevel.WARNING) return false end table.insert(objectives, objective) updateObjectiveText(#objectives) return true end function TUM.objectives.getCount() return #objectives end function TUM.objectives.getCompletedCount() if #objectives == 0 then return 0 end local count = 0 for i=1,#objectives do if objectives[i].completed then count = count + 1 end end return count end function TUM.objectives.getCenter() local point2 = { x = 0, y = 0 } if #objectives == 0 then return point2 end for _,o in ipairs(objectives) do point2.x = point2.x + o.point2.x point2.y = point2.y + o.point2.y end point2.x = point2.x / #objectives point2.y = point2.y / #objectives return point2 end function TUM.objectives.getRadius() if #objectives < 2 then return 10000 end -- Default to a 10km radius if no objectives or a single objective local center = TUM.objectives.getCenter() local radius = 0 for _,o in ipairs(objectives) do local dist = DCSEx.math.getDistance2D(center, o.point2) if dist > radius then radius = dist end end return radius end function TUM.objectives.getObjective(index) if index < 1 or index > #objectives then return nil end return DCSEx.table.deepCopy(objectives[index]) end function TUM.objectives.getObjectiveProgress(index, doublePercentage) doublePercentage = doublePercentage or false if index < 1 or index > #objectives then return "" end if TUM.DEBUG_MODE then return tostring(#objectives[index].completedUnitsID).."/"..tostring(math.max(1, #objectives[index].unitsID)) else local percentage = 0 if #objectives[index].unitsID > 0 then percentage = math.floor((#objectives[index].completedUnitsID / math.max(1, #objectives[index].unitsID)) * 100.0) end if doublePercentage then return tostring(percentage).."%%" else return tostring(percentage).."%" end end end function TUM.objectives.removeAll() TUM.log("Removing all objectives...") for _,o in ipairs(objectives) do if o.groupID then local g = DCSEx.world.getGroupByID(o.groupID) if g then g:destroy() end elseif o.unitsID then -- Some objects (such as static object) do not belong to a group, must be removed one by one for _,id in ipairs(o.unitsID) do local u = DCSEx.world.getUnitByID(id) if u then u:destroy() else local s = DCSEx.world.getStaticObjectByID(id) if s then s:destroy() end end end end trigger.action.removeMark(o.markerID) trigger.action.removeMark(o.markerTextID) end objectives = {} end function TUM.objectives.areAllCompleted() if #objectives == 0 then return false end return TUM.objectives.getCompletedCount() == TUM.objectives.getCount() end function TUM.objectives.getSceneryObjectObjective(sceneryObject) if #objectives == 0 then return nil end if not sceneryObject then return nil end if Object.getCategory(sceneryObject) ~= Object.Category.SCENERY then return nil end for i=1,#objectives do if DCSEx.math.isSamePoint(sceneryObject:getPoint(), objectives[i].point3) then return i end end return nil end local function markObjectiveAsComplete(index) if index < 1 or index > #objectives then return end -- Out of bounds if objectives[index].completed then return end -- Objective already completed objectives[index].completed = true TUM.playerScore.awardCompletedObjective() if TUM.objectives.areAllCompleted() then TUM.mission.checkMissionStatus() else TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "commandObjectiveComplete", { objectives[index].name }, "Command", true) end DCSEx.dcs.outPicture("Pic-ObjectiveComplete.png", 5, true, 0, 1, 1, 25, 1) trigger.action.outSound("UI-MissionEnd.ogg") end local function onObjectiveEvent(index, event) if index < 1 or index > #objectives then return end -- Out of bounds if objectives[index].completed then return end -- Objective already completed if event.id ~= world.event.S_EVENT_DEAD and event.id ~= world.event.S_EVENT_UNIT_LOST then return end if not event.initiator then return end if objectives[index].isSceneryTarget then if Object.getCategory(event.initiator) == Object.Category.SCENERY then if DCSEx.math.isSamePoint(event.initiator:getPoint(), objectives[index].point3) then timer.scheduleFunction(markObjectiveAsComplete, index, timer.getTime() + 3) end end else if Object.getCategory(event.initiator) == Object.Category.UNIT or Object.getCategory(event.initiator) == Object.Category.STATIC then local unitID = DCSEx.dcs.getObjectIDAsNumber(event.initiator) if DCSEx.table.contains(objectives[index].completedUnitsID, unitID) then return end if not DCSEx.table.contains(objectives[index].unitsID, unitID) then return end table.insert(objectives[index].completedUnitsID, unitID) if #objectives[index].completedUnitsID == #objectives[index].unitsID then timer.scheduleFunction(markObjectiveAsComplete, index, timer.getTime() + 3) end end end updateObjectiveText(index) end function TUM.objectives.onEvent(event) for i,_ in ipairs(objectives) do onObjectiveEvent(i, event) end end end -- ==================================================================================== -- TUM.OBJECTIVESMAKER - CREATE MISSION OBJECTIVES -- ==================================================================================== -- ==================================================================================== TUM.objectivesMaker = {} do local function pickRandomTask() local taskFamily = TUM.settings.getValue(TUM.settings.id.TASKING) local validTaskIDs = {} for k,t in pairs(Library.tasks) do if t.taskFamily == taskFamily then table.insert(validTaskIDs, k) end end if #validTaskIDs == 0 then return nil end return DCSEx.table.getRandom(validTaskIDs) end local function pickWaterPoint(nearThisPoint) local waterZones = TUM.territories.getWaterZones() if not waterZones or #waterZones == 0 then return nil end -- No "water" zones on this map local possiblePoints = {} for _=1,24 do local point = DCSEx.zones.getRandomPointInside(DCSEx.table.getRandom(waterZones), land.SurfaceType.WATER) if point then table.insert(possiblePoints, point) end end if #possiblePoints == 0 then return nil end possiblePoints = DCSEx.dcs.getNearestPoints(nearThisPoint, possiblePoints, 1) return possiblePoints[1] end function TUM.objectivesMaker.create() local zone = DCSEx.zones.getByName(TUM.settings.getValue(TUM.settings.id.TARGET_LOCATION, true)) local taskID = pickRandomTask() if not taskID then TUM.log("Failed to find a valid task.", TUM.logLevel.WARNING) return nil end local objectiveDB = Library.tasks[taskID] local spawnPoint2 = nil local spawnPoint3 = nil local isSceneryTarget = false if DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.SCENERY_TARGET) then local validSceneries = DCSEx.world.getSceneriesInZone(zone, DCSEx.zones.getRadius(zone), 250) if not validSceneries or #validSceneries == 0 then TUM.log("Failed to find a valid scenery object to use as target.", TUM.logLevel.WARNING) return nil end local pickedScenery = DCSEx.table.getRandom(validSceneries) spawnPoint3 = DCSEx.table.deepCopy(pickedScenery:getPoint()) spawnPoint2 = DCSEx.math.vec3ToVec2(spawnPoint3) isSceneryTarget = true elseif objectiveDB.surfaceType == land.SurfaceType.WATER then spawnPoint2 = pickWaterPoint(zone) if not spawnPoint2 then spawnPoint2 = DCSEx.world.getSpawnPoint(zone, objectiveDB.surfaceType, objectiveDB.safeRadius) end else spawnPoint2 = DCSEx.world.getSpawnPoint(zone, objectiveDB.surfaceType, objectiveDB.safeRadius) end if not spawnPoint2 then TUM.log("Failed to find a spawn point for objective.", TUM.logLevel.WARNING) return nil end if not spawnPoint3 then spawnPoint3 = DCSEx.math.vec2ToVec3(spawnPoint2, "land") end if DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.ON_ROADS) then spawnPoint2 = DCSEx.world.getClosestPointOnRoadsVec2(spawnPoint2) end local objective = { completed = false, completedUnitsID = {}, isSceneryTarget = isSceneryTarget, markerID = DCSEx.world.getNextMarkerID(), markerTextID = DCSEx.world.getNextMarkerID(), name = Library.objectiveNames.get():upper(), point2 = DCSEx.table.deepCopy(spawnPoint2), point3 = DCSEx.table.deepCopy(spawnPoint3), preciseCoordinates = objectiveDB.waypointInaccuracy <= 0, taskID = taskID, unitsID = {} } if objectiveDB.waypointInaccuracy <= 0 then -- Exact coordinates are available objective.waypoint2 = DCSEx.table.deepCopy(objective.point2) objective.waypoint3 = DCSEx.table.deepCopy(objective.point3) else -- No exact coordinates available, create the waypoint near the target objective.waypoint2 = DCSEx.math.randomPointInCircle(objective.point2, objectiveDB.waypointInaccuracy) objective.waypoint3 = DCSEx.math.vec2ToVec3(objective.waypoint2, "land") end if not DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.SCENERY_TARGET) then -- Check group options local groupOptions = {} if DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.MOVING) then local destPoint = DCSEx.math.randomPointInCircle(objective.point2, 5000, 2500, land.SurfaceType.LAND) if destPoint then groupOptions.isMoving = true if DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.ON_ROADS) then groupOptions.onRoad = true destPoint = DCSEx.world.getClosestPointOnRoadsVec2(destPoint) end groupOptions.moveTo = destPoint end end local units = Library.factions.getUnits(TUM.settings.getEnemyFaction(), objectiveDB.targetFamilies, math.random(objectiveDB.targetCount[1], objectiveDB.targetCount[2])) local groupInfo = nil if objectiveDB.targetFamilies[1] == DCSEx.enums.unitFamily.STATIC_STRUCTURE then if units and #units >= 1 then groupInfo = {} groupInfo.unitsID = { DCSEx.unitGroupMaker.createStatic(TUM.settings.getEnemyCoalition(), objective.point2, units[1], "") } end else groupInfo = DCSEx.unitGroupMaker.create(TUM.settings.getEnemyCoalition(), DCSEx.dcs.getUnitTypeFromFamily(objectiveDB.targetFamilies[1]), objective.point2, units, groupOptions) end if not groupInfo then TUM.log("Failed to spawn a group for objective.", TUM.logLevel.WARNING) return nil end objective.groupID = groupInfo.groupID if DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.DESTROY_TRACK_RADARS_ONLY) then objective.unitsID = {} for i=1,#groupInfo.unitTypeNames do if Unit.getDescByName(groupInfo.unitTypeNames[i]).attributes["SAM TR"] then table.insert(objective.unitsID, groupInfo.unitsID[i]) end end if #objective.unitsID == 0 then objective.unitsID = DCSEx.table.deepCopy(groupInfo.unitsID) end else objective.unitsID = DCSEx.table.deepCopy(groupInfo.unitsID) end end --------------------------------------------------------------------- -- Create dot marker (accurate WPs) or circle marker (inaccurate WPs) --------------------------------------------------------------------- if objectiveDB.waypointInaccuracy <= 0 then trigger.action.markToAll(objective.markerID, "Objective "..objective.name.."\n\n"..DCSEx.world.getCoordinatesAsString(objective.point3, false), objective.point3, true) else local circleRadius = math.max(objectiveDB.waypointInaccuracy, 1000) trigger.action.circleToAll( -1, objective.markerID, objective.waypoint3, circleRadius, { 1, 1, 1, 1 }, { 1, 0, 0, 0.25 } , 2, true) end --------------------- -- Create text marker --------------------- local textPoint3 = DCSEx.table.deepCopy(objective.waypoint3) textPoint3.x = textPoint3.x + 224 textPoint3.z = textPoint3.z + 224 -- Text marker is created with an empty string, its content will be updated by TUM.MissionObjectives when it's added trigger.action.textToAll(-1, objective.markerTextID, textPoint3, { 1, 1, 1, 1 }, { 0, 0, 0, .5 }, 12, true, "") return objective end end -- ==================================================================================== -- TUM.PLAYERCAREER - HANDLES THE PERSISTENT PILOT CAREER IN SINGLE-PLAYER MISSIONS -- ==================================================================================== -- (local const) MAX_RIBBONS -- (local const) MEDAL_BOX_DISPLAY_TIME -- (local const) OBJECTIVES_PER_RIBBON -- (local const) MEDALS -- (local const) RANKS -- (local table) careerStats -- (local) fixIncompleteStats() -- (local) getHighestMedal() -- (local) getRibbonCount() -- TUM.playerCareer.awardScore(score, objectives) -- TUM.playerCareer.createMenu() -- TUM.playerCareer.displayMedalBox(printSummary) -- TUM.playerCareer.getCareerSummary() -- TUM.playerCareer.load() -- TUM.playerCareer.onStartUp() -- TUM.playerCareer.reset() -- TUM.playerCareer.save() -- ==================================================================================== TUM.playerCareer = {} do local MAX_RIBBONS = 40 -- Maximum number of ribbons local MEDAL_BOX_DISPLAY_TIME = 15 -- in seconds local OBJECTIVES_PER_RIBBON = 4 -- How many completed objectives to gain a new ribbon? local MEDALS = { { "Air medal", 150 }, { "Bronze star", 225 }, { "Airman's medal", 300 }, { "Distinguished Flying Cross", 375 }, { "Silver Star for Valor", 450 }, { "Air Force Cross", 525 }, { "Congressional Medal of Honor", 600 }, } local RANKS = { { "2d Lt.", "Second lieutenant", 0 }, { "1st Lt.", "First lieutenant", 400 }, { "Capt.", "Captain", 1600 }, { "Maj.", "Major", 6400 }, { "Lt Col.", "Lieutenant colonel", 16000 }, { "Col.", "Colonel", 32000 }, } local careerStats = {} ------------------------------------- -- Adds missing fields, if any, to the careerStats table ------------------------------------- local function fixIncompleteStats() if not careerStats then careerStats = { } end if not careerStats.bestSortie then careerStats.bestSortie = 0 end if not careerStats.completedObjectives then careerStats.completedObjectives = 0 end if not careerStats.completedSorties then careerStats.completedSorties = 0 end if not careerStats.medals then careerStats.medals = 0 end if not careerStats.medalWounded then careerStats.medalWounded = false end if not careerStats.rank then careerStats.rank = 1 end if not careerStats.score then careerStats.score = 0 end careerStats.version = TUM.VERSION_NUMBER end ------------------------------------- -- Returns the highest medal a player has obtained for scoring a high number of points during a single sortie -- @return A number (index in the MEDALS table) ------------------------------------- local function getHighestMedal() local medal = 0 for i=1,#MEDALS do if careerStats.bestSortie >= MEDALS[i][2] then medal = i end end return medal end ------------------------------------- -- Returns the current number a ribbons a player was awarded for completing objectives -- @return A number ------------------------------------- local function getRibbonCount() return DCSEx.math.clamp(math.floor(careerStats.completedObjectives / OBJECTIVES_PER_RIBBON), 0, MAX_RIBBONS) end ------------------------------------- -- Awards career points. Only works in single-player missions -- @param score Number of career points to award -- @param objectives Number of completed objectives to award -- @return True if a ribbon, medal or promotion was awarded, false otherwise ------------------------------------- function TUM.playerCareer.awardScore(score, objectives) if not DCSEx.io.canReadAndWrite() then return false end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No career in multiplayer score = math.max(0, math.floor(score or 0)) fixIncompleteStats() local oldRibbonCount = getRibbonCount() careerStats.bestSortie = math.max(careerStats.bestSortie, score) careerStats.score = careerStats.score + score careerStats.completedObjectives = careerStats.completedObjectives + objectives trigger.action.outText(DCSEx.string.toStringThousandsSeparator(score).." xp and "..tostring(objectives).." completed objective(s) were registered in your flight log.", 5) local newRibbonCount = getRibbonCount() local somethingWasAwarded = false -- Check for promotions if careerStats.rank < #RANKS and careerStats.score >= RANKS[careerStats.rank + 1][3] then careerStats.rank = careerStats.rank + 1 somethingWasAwarded = true trigger.action.outText("✪ You have been promoted to the rank of "..RANKS[careerStats.rank][2]..".", MEDAL_BOX_DISPLAY_TIME) end -- Check for medals for i=1,#MEDALS do if i > careerStats.medals and score >= MEDALS[i][2] then trigger.action.outText("✪ You have been awarded the "..MEDALS[i][1]..".", MEDAL_BOX_DISPLAY_TIME) careerStats.medals = i somethingWasAwarded = true break end end -- Check for ribbons if newRibbonCount > oldRibbonCount then trigger.action.outText("✪ You have been awarded a battle ribbon.", MEDAL_BOX_DISPLAY_TIME) somethingWasAwarded = true end TUM.playerCareer.save() if somethingWasAwarded then TUM.playerCareer.displayMedalBox(false) end TUM.playerScore.reset(false) return somethingWasAwarded end ------------------------------------- -- Appends the career menu to the F10 menu. Only works in single-player missions ------------------------------------- function TUM.playerCareer.createMenu() local rootMenu = TUM.getOrCreateRootMenu() if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No career in multiplayer missionCommands.addCommand("✪ View pilot career stats", rootMenu, TUM.playerCareer.displayMedalBox, true) end ------------------------------------- -- Displays the player's medal box and carrer summary. Only works in single-player missions ------------------------------------- function TUM.playerCareer.displayMedalBox(printSummary) if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No career in multiplayer fixIncompleteStats() if printSummary then trigger.action.outText(TUM.playerCareer.getCareerSummary(), MEDAL_BOX_DISPLAY_TIME, true) end DCSEx.dcs.outPicture("Pic-MedalBox.png", MEDAL_BOX_DISPLAY_TIME, true, 0, 2, 2, 50, 1) DCSEx.dcs.outPicture("Pic-Rank"..tostring(careerStats.rank)..".png", MEDAL_BOX_DISPLAY_TIME, false, 0, 2, 2, 50, 1) local ribbonCount = getRibbonCount() for i=1,ribbonCount do DCSEx.dcs.outPicture("Pic-Ribbon"..tostring(i)..".png", MEDAL_BOX_DISPLAY_TIME, false, 0, 2, 2, 50, 1) end for i=1,careerStats.medals do DCSEx.dcs.outPicture("Pic-Medal"..tostring(i)..".png", MEDAL_BOX_DISPLAY_TIME, false, 0, 2, 2, 50, 1) end trigger.action.outSound("UI-Career.ogg") end ------------------------------------- -- Returns the player career summary as a string. Only works in single-player missions -- @return A string ------------------------------------- function TUM.playerCareer.getCareerSummary() if not DCSEx.io.canReadAndWrite() then return "" end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return "" end -- No career in multiplayer fixIncompleteStats() local playerName = "Player" local players = DCSEx.world.getAllPlayers() if #players > 0 then playerName = players[1]:getPlayerName() end local summary = "" summary = summary.."CAREER STATS FOR "..RANKS[careerStats.rank][1]:upper().." "..playerName:upper()..":\n" summary = summary.."=======================\n" summary = summary.."- Rank: "..RANKS[careerStats.rank][2].."\n" summary = summary.."- Best sortie XP: "..DCSEx.string.toStringThousandsSeparator(careerStats.bestSortie).."\n" summary = summary.."- Total career XP: "..DCSEx.string.toStringThousandsSeparator(careerStats.score).."\n" summary = summary.."- Completed objectives: "..tostring(careerStats.completedObjectives).."\n" if careerStats.medals == 0 then summary = summary.."- Medals: None" else summary = summary.."- Medals:" for i=1,careerStats.medals do summary = summary.."\n - "..MEDALS[i][1] end end local ribbonCount = getRibbonCount() if ribbonCount < MAX_RIBBONS or careerStats.rank < #RANKS or careerStats.medals < #MEDALS then summary = summary.."\n" if careerStats.rank < #RANKS then summary = summary.."\n- Next promotion: "..DCSEx.string.toStringThousandsSeparator(RANKS[careerStats.rank + 1][3]).." xp" end if ribbonCount < MAX_RIBBONS then summary = summary.."\n- Next ribbon: "..tostring((ribbonCount + 1) * OBJECTIVES_PER_RIBBON).." objectives" end if careerStats.medals < #MEDALS then summary = summary.."\n- Next medal: "..DCSEx.string.toStringThousandsSeparator(MEDALS[careerStats.medals + 1][2]).." xp in a single flight" end end return summary end ------------------------------------- -- Loads the player career from the disk. Only works in single-player missions -- @return True if everything worked (or disabled because of MP), false if an error happened ------------------------------------- function TUM.playerCareer.load() if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return true end -- No career in multiplayer if not DCSEx.io.canReadAndWrite() then return false end local jsonString = DCSEx.io.load("TheUniversalMission.sav") if jsonString then -- TODO: what if Json is malformed? careerStats = net.json2lua(jsonString) if not careerStats then careerStats = {} fixIncompleteStats() TUM.log("Failed to load player career data, career data reset.") else TUM.log("Player career data loaded successfully.") end else fixIncompleteStats() return false end fixIncompleteStats() end ------------------------------------- -- Called on mission start up -- @return True if started up properly, false if an error happened ------------------------------------- function TUM.playerCareer.onStartUp() fixIncompleteStats() if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return true end -- No career in multiplayer if DCSEx.io.canReadAndWrite() then TUM.log("Lua IO module available, can read and write.") TUM.playerCareer.load() else local msg = "IO module is disabled, CANNOT read and write persistant data. Player progress will NOT be saved.\n" msg = msg.."To enable the IO module, comment or remove the \"sanitizeModule('io')\" line in \n" msg = msg.."[DCSWorld installation directory]\\Scripts\\MissionScripting.lua and restart the game." TUM.log(msg, TUM.logLevel.WARNING) end return true end ------------------------------------- -- Resets the player career stats and save them. Only works in single-player missions ------------------------------------- function TUM.playerCareer.reset() if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No career in multiplayer careerStats = nil fixIncompleteStats() TUM.playerCareer.save() end ------------------------------------- -- Save the player career to the disk. Only works in single-player missions -- @return True if everything worked (or disabled), false if an error happened ------------------------------------- function TUM.playerCareer.save() if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return true end -- No career in multiplayer if not DCSEx.io.canReadAndWrite() then return true end -- IO disabled, career and scoring disabled fixIncompleteStats() if DCSEx.io.save("TheUniversalMission.sav", net.lua2json(careerStats)) then return true else return false end end end -- ==================================================================================== -- TUM.PLAYERSCORE - HANDLES ALL SCORING DURING SINGLE-PLAYER MISSIONS -- ==================================================================================== -- (const) SKILL_MULTIPLIER_BONUS -- (const) SCORE_REMINDER_INTERVAL -- (local) getKillValue(killedObject) -- (local) onKillEvent(event) -- (local) onLandEvent(event) -- (local) onResetEvent(event) -- (local) printReminder() -- TUM.playerScore.award(amount, message, silent) -- TUM.playerScore.getCompletedObjectives() -- TUM.playerScore.getScore() -- TUM.playerScore.getScoreMultiplier(settingID, settingValue) -- TUM.playerScore.getTotalScoreMultiplier() -- TUM.playerScore.onClockTick(clockTick) -- TUM.playerScore.onEvent(event) -- TUM.playerScore.reset(showMessage, reason) -- TUM.playerScore.showScore() -- ==================================================================================== TUM.playerScore = {} do local ENEMY_DEFENSE_MULTIPLIER_BONUS = { -0.1, 0.1, 0.3, 0.5, 0.7 } local SCORE_REMINDER_INTERVAL = 5 -- in minutes local completedObjectives = 0 local score = 0 local scoreReminderIntervalLeft = SCORE_REMINDER_INTERVAL local function getKillValue(killedObject) if not killedObject then return 0 end if Object.getCategory(killedObject) == Object.Category.BASE then return 60 end if Object.getCategory(killedObject) == Object.Category.STATIC then return 60 end if Object.getCategory(killedObject) == Object.Category.SCENERY then for i=1,TUM.objectives.getCount() do local obj = TUM.objectives.getObjective(i) if obj then if obj.isSceneryTarget then if DCSEx.math.isSamePoint(killedObject:getPoint(), obj.point3) then return 60 end end end end return 0 end if Object.getCategory(killedObject) ~= Object.Category.UNIT then return 0 end local objectDesc = killedObject:getDesc() if not objectDesc or not objectDesc.attributes then return 10 end -- No description, assume a default value of 10 points local groundMultiplier = 1 if not killedObject:inAir() then groundMultiplier = 0.5 end -- Aircraft killed on the ground are worth less points -- Misc if objectDesc.attributes["Missiles"] then return 10 end if objectDesc.attributes["UAVs"] then return math.floor(15 * groundMultiplier) end -- Fixed wing if objectDesc.attributes["Fighters"] then return math.floor(40 * groundMultiplier) end if objectDesc.attributes["Interceptors"] then return math.floor(40 * groundMultiplier) end if objectDesc.attributes["Interceptors"] then return math.floor(40 * groundMultiplier) end if objectDesc.attributes["Planes"] then return math.floor(25 * groundMultiplier) end -- Rotary wing if objectDesc.attributes["Attack helicopters"] then return math.floor(30 * groundMultiplier) end if objectDesc.attributes["Helicopters"] then return math.floor(25 * groundMultiplier) end -- Default air if objectDesc.attributes["Air"] then return math.floor(20 * groundMultiplier) end -- Ships if objectDesc.attributes["Aircraft Carriers"] then return 300 end if objectDesc.attributes["Cruisers"] then return 250 end if objectDesc.attributes["Destroyers"] then return 150 end if objectDesc.attributes["Frigates"] then return 150 end if objectDesc.attributes["Corvettes"] then return 100 end if objectDesc.attributes["Heavy armed ships"] then return 75 end if objectDesc.attributes["Ships"] then return 25 end -- Air defense if objectDesc.attributes["MANPADS AUX"] then return 5 end if objectDesc.attributes["MANPADS"] then return 10 end if objectDesc.attributes["SR SAM"] then return 20 end if objectDesc.attributes["IR Guided SAM"] then return 15 end if objectDesc.attributes["SAM TR"] then return 25 end if objectDesc.attributes["SAM SR"] then return 15 end if objectDesc.attributes["Armed Air Defence"] then return 10 end if objectDesc.attributes["SAM elements"] then return 5 end if objectDesc.attributes["SAM related"] then return 5 end -- Ground vehicles if objectDesc.attributes["Modern Tanks"] then return 20 end if objectDesc.attributes["Tanks"] then return 15 end if objectDesc.attributes["Modern Tanks"] then return 25 end if objectDesc.attributes["HeavyArmoredUnits"] then return 20 end if objectDesc.attributes["LightArmoredUnits"] then return 15 end if objectDesc.attributes["NonArmoredUnits"] then return 10 end if objectDesc.attributes["Unarmed vehicles"] then return 10 end -- Infantry if objectDesc.attributes["Infantry"] then return 3 end return 10 -- Don't know what this thing is, assume a default value of 10 points end ------------------------------------- -- Called by TUM.playerScore.onEvent when a KILL event is triggered -- @param event The DCS World event ------------------------------------- local function onKillEvent(event) if not event.target then return end if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end if not event.initiator:getPlayerName() then return end local killValue = getKillValue(event.target) if killValue <= 0 then return end -- Higher reward for higher threat levels local scoreMultiplier = TUM.playerScore.getTotalScoreMultiplier() killValue = math.max(1, math.floor(killValue * scoreMultiplier)) -- Penalty for destroying friendly or civilian units local prefix = "" if Object.getCategory(event.target) == Object.Category.UNIT then if event.initiator:getCoalition() == event.target:getCoalition() then prefix = "friendly " killValue = killValue * -5.0 elseif event.target:getCoalition() == coalition.side.NEUTRAL then prefix = "neutral " killValue = killValue * -2.0 end end TUM.playerScore.award(killValue, "destroyed "..prefix..Library.objectNames.get(event.target)) end ------------------------------------- -- Called by TUM.playerScore.onEvent when a LAND event is triggered -- @param event The DCS World event ------------------------------------- local function onLandEvent(event) if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end if not event.initiator:getPlayerName() then return end local muteRadioMessage = false if score > 0 or completedObjectives > 0 then muteRadioMessage = TUM.playerCareer.awardScore(score, completedObjectives) end -- Single-player landing radio message is handled here instead of in AmbientRadio to avoid -- "conflicts" with the "awardScore" message if both the medal case and the radio message are -- triggered at the same time (delaying the radio message wouldn't be a solution as this would -- interrupt the medal case music very quickly) if not muteRadioMessage then local baseName = "AIRBASE" if event.place then baseName = event.place:getName():upper() end TUM.radio.playForAll("atcSafeLandingPlayer", {event.initiator:getCallsign(), baseName}, baseName.." ATC") end end ------------------------------------- -- Called by TUM.playerScore.onEvent when any event causing a score reset (crash, ejection, slot change...) is triggered -- @param event The DCS World event ------------------------------------- local function onResetEvent(event) if not event.initiator:getPlayerName() then return end local reason = nil if event.id == world.event.S_EVENT_CRASH then reason = "you crashed" elseif event.id == world.event.S_EVENT_PILOT_DEAD then reason = "you were killed" elseif event.id == world.event.S_EVENT_EJECTION then reason = "you ejected" elseif event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT then reason = "you've taken control of a new aircraft" end TUM.playerScore.reset(true, reason) end ------------------------------------- -- Print a reminder that the player has to land for their current score and completed objectives to be added to their flight profile -- @return True if a reminded was printed, false if it was not needed (no score to award, etc) ------------------------------------- local function printReminder() if score <= 0 and completedObjectives <= 0 then return false end -- Nothing to remind the player of local msg = "" if score > 0 and completedObjectives > 0 then msg = string.format("You've been awarded %s point(s) and have completed %d objective(s).", DCSEx.string.toStringThousandsSeparator(score), completedObjectives) elseif score > 0 then msg = string.format("You've been awarded %s point(s).", DCSEx.string.toStringThousandsSeparator(score)) else msg = string.format("You have completed %d objective(s).", completedObjectives) end trigger.action.outText("[REMINDER] "..msg.." All progress will be recorded to your flight log upon landing.", 5) trigger.action.outSound("UI-Ok.ogg") return true end ------------------------------------- -- Awards points to the player. Only works in single-player missions -- @param amount Number of points to award -- @param message Message to display (why are these points awarded?). If missing, no message will be displayed. ------------------------------------- function TUM.playerScore.award(amount, message) if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No scoring in multiplayer score = score + amount if message then TUM.log("Awarded "..DCSEx.string.toStringThousandsSeparator(amount).." points ("..message..").") end end ------------------------------------- -- Awards a new completed objective to the player. Only works in single-player missions ------------------------------------- function TUM.playerScore.awardCompletedObjective() if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No scoring in multiplayer completedObjectives = completedObjectives + 1 end ------------------------------------- -- Returns the current number of completed objectives. Only works in single-player missions -- @return A number ------------------------------------- function TUM.playerScore.getCompletedObjectives() if not DCSEx.io.canReadAndWrite() then return 0 end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return 0 end -- No scoring in multiplayer return completedObjectives end ------------------------------------- -- Returns the current player score. Only works in single-player missions -- @return A number ------------------------------------- function TUM.playerScore.getScore() if not DCSEx.io.canReadAndWrite() then return 0 end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return 0 end -- No scoring in multiplayer return score end ------------------------------------- -- Returns the value to add to the global score multiplier according to a given setting -- @param settingID ID of the setting (from the TUM.settings.id enum) -- @param settingValue The setting value, or nil to use the current value -- @return A number in the -1.0 to +1.0 range, or nil if this setting has no effect on XP gains ------------------------------------- function TUM.playerScore.getScoreMultiplier(settingID, settingValue) if not DCSEx.io.canReadAndWrite() then return 0 end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return 0 end -- No scoring in multiplayer settingValue = TUM.settings.getValue(settingID) if settingID == TUM.settings.id.ENEMY_AIR_DEFENSE or settingID == TUM.settings.id.ENEMY_AIR_FORCE then return ENEMY_DEFENSE_MULTIPLIER_BONUS[settingValue] elseif settingID == TUM.settings.id.WINGMEN then return 0 - 0.10 * (settingValue - 1) elseif settingID == TUM.settings.id.TARGET_LOCATION then local zoneName = TUM.settings.getValue(TUM.settings.id.TARGET_LOCATION, true) local tgtZone = DCSEx.zones.getByName(zoneName) if not tgtZone then return 0 end if TUM.territories.getPointOwner(tgtZone) == TUM.settings.getEnemyCoalition() then return 0.3 end return 0 elseif settingID == TUM.settings.id.AI_CAP then if settingValue == 2 and TUM.settings.getValue(TUM.settings.id.ENEMY_AIR_FORCE) > 1 then return 0.15 end return 0 end return nil end ------------------------------------- -- Returns the global score multiplier according the current settings -- @return A number (where 1.0 means default value, 0.5 is -50%, etc) ------------------------------------- function TUM.playerScore.getTotalScoreMultiplier() if not DCSEx.io.canReadAndWrite() then return 1.0 end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return 1.0 end -- No scoring in multiplayer local scoreMultiplier = 1.0 for _,v in pairs(TUM.settings.id) do scoreMultiplier = scoreMultiplier + (TUM.playerScore.getScoreMultiplier(v) or 0.0) end return math.max(0.0, scoreMultiplier) end ---------------------------------------------------------- -- Called on every mission update tick (every 10-20 seconds) -- @return True if something was done this tick, false otherwise ---------------------------------------------------------- function TUM.playerScore.onClockTick() if not DCSEx.io.canReadAndWrite() then return false end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No scoring in multiplayer if score == 0 and completedObjectives == 0 then return false end -- Nothing to remind the player of scoreReminderIntervalLeft = scoreReminderIntervalLeft - 1 if scoreReminderIntervalLeft == 0 then scoreReminderIntervalLeft = SCORE_REMINDER_INTERVAL return printReminder() end return false end ------------------------------------- -- Called when an event is raised -- @param event The DCS World event ------------------------------------- function TUM.playerScore.onEvent(event) if not event.initiator then return end if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No scoring in multiplayer if event.id == world.event.S_EVENT_KILL then onKillEvent(event) return end if event.id == world.event.S_EVENT_LAND then onLandEvent(event) return end if event.id == world.event.S_EVENT_CRASH or event.id == world.event.S_EVENT_PILOT_DEAD or event.id == world.event.S_EVENT_PLAYER_ENTER_UNIT or event.id == world.event.S_EVENT_EJECTION then onResetEvent(event) return end end ------------------------------------- -- Resets the player score to 0 -- @param showMessage Should a message be displayed (if any points are lost)? -- @param reason The reason for the point loss, displayed in the message ------------------------------------- function TUM.playerScore.reset(showMessage, reason) if completedObjectives == 0 and score == 0 then return end if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No scoring in multiplayer if showMessage then local msg = "" if reason then msg = "Unstowed progress lost because "..reason.."." else msg = "Unstowed progress lost." end msg = msg.." You lost "..DCSEx.string.toStringThousandsSeparator(score).." xp and "..tostring(completedObjectives).." completed objective(s)." trigger.action.outText(msg, 5) trigger.action.outSound("UI-Error.ogg") else TUM.log("Mission score reset.") end completedObjectives = 0 score = 0 end ------------------------------------- -- Shows the current mission score ------------------------------------- function TUM.playerScore.showScore() if not DCSEx.io.canReadAndWrite() then return end -- IO disabled, career and scoring disabled if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No scoring in multiplayer local scoreMsg = "CURRENT PROGRESS (will be awarded to your career profile on landing):\n" scoreMsg = scoreMsg.."XP: "..DCSEx.string.toStringThousandsSeparator(score).."\n" scoreMsg = scoreMsg.."Completed objectives: "..tostring(completedObjectives) trigger.action.outText(scoreMsg, 5) trigger.action.outSound("UI-Ok.ogg") end end -- ==================================================================================== -- TUM.RADIO - HANDLES FUNCTIONS TO PLAY RADIO MESSAGES -- ==================================================================================== -- (const, local) ANSWER_DELAY -- (local) function doRadioMessage(args, time) -- TUM.radio.playForAll(messageID, replacements, callsign, delayed, functionToRun, functionParameters) -- TUM.radio.playForCoalition(coalitionID, messageID, replacements, callsign, delayed, functionToRun, functionParameters) -- TUM.radio.playForGroup(groupID, messageID, replacements, callsign, delayed, functionToRun, functionParameters) -- TUM.radio.playForUnit(unitID, messageID, replacements, callsign, delayed, functionToRun, functionParameters) -- ==================================================================================== TUM.radio = {} do -- Min/max time to get a answer to a radio message, in seconds local ANSWER_DELAY = { 3.0, 5.0 } ------------------------------------- -- Executes a radio message -- @param args Message parameters -- @param time Game time at the moment the message is played ------------------------------------- local function doRadioMessage(args, time) if not args or not args.messageID then return nil end local callsign = args.callsign if not callsign then local unit = DCSEx.world.getUnitByID(args.unitID) if not unit then callsign = "Flight" else callsign = unit:getCallsign() end end local message = "" local oggFile = args.messageID if type(Library.radioMessages[args.messageID]) == "table" then local index = DCSEx.table.getRandomIndex(Library.radioMessages[args.messageID]) oggFile = oggFile..tostring(index) message = Library.radioMessages[args.messageID][index] else message = Library.radioMessages[args.messageID] end if args.replacements then for i,r in ipairs(args.replacements) do message = message:gsub("$"..tostring(i), tostring(r)) end end message = DCSEx.string.firstToUpper(message) local duration = DCSEx.string.getReadingTime(message) -- Print message trigger.action.outTextForUnit(args.unitID, callsign:upper()..": "..message, duration, false) -- Play sound trigger.action.outSoundForUnit(args.unitID, "Radio-"..oggFile..".ogg") if args.functionToRun then -- a function was provided, run it args.functionToRun(args.functionParameters) end return nil -- disable scheduling, if any end ------------------------------------- -- Plays a message to all players in a coalition -- @param messageID ID of the radio message in scrambe.db.radioMessages -- @param replacements String placeholders ($1, $2...) replacements in the message -- @param callsign Name of the person speaking or nil to use unitID's callsign -- @param delayed Should the message be delayed (used for message answers) -- @param functionToRun Function to run when the message is played -- @param functionParameters Parameters for the function to run when the message is played ------------------------------------- function TUM.radio.playForAll(messageID, replacements, callsign, delayed, functionToRun, functionParameters) local players = DCSEx.world.getAllPlayers() for _, unit in pairs(players) do TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(unit), messageID, replacements, callsign, delayed, functionToRun, functionParameters) end end ------------------------------------- -- Plays a message to all players in a given coalition -- @param coalitionID ID of the coalition (coalition.side.XXX) -- @param messageID ID of the radio message in scrambe.db.radioMessages -- @param replacements String placeholders ($1, $2...) replacements in the message -- @param callsign Name of the person speaking or nil to use unitID's callsign -- @param delayed Should the message be delayed (used for message answers) -- @param functionToRun Function to run when the message is played -- @param functionParameters Parameters for the function to run when the message is played ------------------------------------- function TUM.radio.playForCoalition(coalitionID, messageID, replacements, callsign, delayed, functionToRun, functionParameters) local players = coalition.getPlayers(coalitionID) for _,u in pairs(players) do TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(u), messageID, replacements, callsign, delayed, functionToRun, functionParameters) end end ------------------------------------- -- Plays a message to players from a certain group -- @param groupID ID of the group sending/receiving the message -- @param messageID ID of the radio message in scrambe.db.radioMessages -- @param replacements String placeholders ($1, $2...) replacements in the message -- @param callsign Name of the person speaking or nil to use unitID's callsign -- @param delayed Should the message be delayed (used for message answers) -- @param functionToRun Function to run when the message is played -- @param functionParameters Parameters for the function to run when the message is played ------------------------------------- function TUM.radio.playForGroup(groupID, messageID, replacements, callsign, delayed, functionToRun, functionParameters) local group = DCSEx.world.getGroupByID(groupID) if not group then return end -- group does not exist for _,u in pairs(group:getUnits()) do TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(u), messageID, replacements, callsign, delayed, functionToRun, functionParameters) end end ------------------------------------- -- Plays a message for a given unit only -- @param unitID ID of the unit receiving the message -- @param messageID ID of the radio message in scrambe.db.radioMessages -- @param replacements String placeholders ($1, $2...) replacements in the message -- @param callsign Name of the person speaking or nil to use unitID's callsign -- @param replacements Table of two tables used for string replacements. E.g. { {"UNIT_NAME", "TIME"}, {"Enfield11", "12:30"}} -- @param delayed Should the message be delayed (used for message answers) -- @param functionToRun Function to run when the message is played -- @param functionParameters Parameters for the function to run when the message is played ------------------------------------- function TUM.radio.playForUnit(unitID, messageID, replacements, callsign, delayed, functionToRun, functionParameters) if not messageID then return end if not Library.radioMessages[messageID] then return end delayed = delayed or false if replacements and type(replacements) ~= "table" then replacements = { replacements } end local radioArgs = { callsign = callsign, functionToRun = functionToRun, functionParameters = functionParameters, messageID = messageID, replacements = replacements, unitID = unitID } if delayed then -- message is delayed, schedule it timer.scheduleFunction( doRadioMessage, radioArgs, timer.getTime() + DCSEx.math.randomFloat(ANSWER_DELAY[1], ANSWER_DELAY[2]) ) else -- no delay, play the message at once doRadioMessage(radioArgs, nil) end end end -- ==================================================================================== -- TUM.SETTINGS - HANDLES THE MISSION SETTINGS -- ==================================================================================== -- (enum) TUM.settings.id -- TUM.settings.getName(id) -- TUM.settings.getValue(id, returnAsString) -- TUM.settings.setAllToDefaults() -- TUM.settings.setValue(id, value, updateMenu) -- ==================================================================================== TUM.settings = {} TUM.settings.id = { AI_CAP = 1, COALITION_BLUE = 2, COALITION_RED = 3, ENEMY_AIR_DEFENSE = 4, ENEMY_AIR_FORCE = 5, MULTIPLAYER = 6, PLAYER_COALITION = 7, TARGET_COUNT = 8, TARGET_LOCATION = 9, TASKING = 10, TIME_PERIOD = 11, WINGMEN = 12, } do local settings = {} local SETTING_NAMES = { [TUM.settings.id.AI_CAP] = "Friendly AI CAP", [TUM.settings.id.COALITION_BLUE] = "Blue coalition", [TUM.settings.id.COALITION_RED] = "Red coalition", [TUM.settings.id.ENEMY_AIR_DEFENSE] = "Enemy air defense", [TUM.settings.id.ENEMY_AIR_FORCE] = "Enemy air force", [TUM.settings.id.MULTIPLAYER] = "Multiplayer", [TUM.settings.id.PLAYER_COALITION] = "Player coalition", [TUM.settings.id.TARGET_COUNT] = "Target count", [TUM.settings.id.TARGET_LOCATION] = "Target location", [TUM.settings.id.TASKING] = "Mission type", [TUM.settings.id.TIME_PERIOD] = "Time period", [TUM.settings.id.WINGMEN] = "Wingmen count" } local SETTING_VALUES = { [TUM.settings.id.AI_CAP] = { "Enabled", "Disabled" }, [TUM.settings.id.COALITION_BLUE] = { }, [TUM.settings.id.COALITION_RED] = { }, [TUM.settings.id.ENEMY_AIR_DEFENSE] = { "None", "Green", "Regular", "Veteran", "Elite" }, [TUM.settings.id.ENEMY_AIR_FORCE] = { "None", "Green", "Regular", "Veteran", "Elite" }, [TUM.settings.id.PLAYER_COALITION] = { "Red", "Blue" }, -- Must match values in the coalition.side enum [TUM.settings.id.TARGET_COUNT] = { "1", "2", "3", "4" }, [TUM.settings.id.TARGET_LOCATION] = { }, [TUM.settings.id.TASKING] = { "Antiship strike", "Ground attack", "Interception", "SEAD", "Strike" }, -- Must match values in the DCSEx.enums.taskFamily enum [TUM.settings.id.TIME_PERIOD] = { "World War 2", "Korea War", "Vietnam War", "Late Cold War", "Modern" }, -- Must match values in the DCSEx.enums.timePeriod enum [TUM.settings.id.WINGMEN] = { "None", "1", "2", "3" } } local targetLocation local function getFaction(side) if side == coalition.side.BLUE then return TUM.settings.getValue(TUM.settings.id.COALITION_BLUE, true) else return TUM.settings.getValue(TUM.settings.id.COALITION_RED, true) end end local function setAllToDefaults(coreSettings) settings = { [TUM.settings.id.AI_CAP] = 1, -- Enabled [TUM.settings.id.COALITION_BLUE] = 1, [TUM.settings.id.COALITION_RED] = 2, [TUM.settings.id.ENEMY_AIR_DEFENSE] = 3, [TUM.settings.id.ENEMY_AIR_FORCE] = 2, [TUM.settings.id.MULTIPLAYER] = coreSettings.multiplayer, [TUM.settings.id.PLAYER_COALITION] = coalition.side.BLUE, [TUM.settings.id.TARGET_COUNT] = 2, [TUM.settings.id.TARGET_LOCATION] = 1, [TUM.settings.id.TASKING] = DCSEx.enums.taskFamily.GROUND_ATTACK, [TUM.settings.id.TIME_PERIOD] = DCSEx.enums.timePeriod.MODERN, [TUM.settings.id.WINGMEN] = 2 } -- TODO: set default time period according to mission year -- if env.mission.date.Year <= 1945 then -- settings[TUM.settings.id.TIME_PERIOD] = DCSEx.enums.timePeriod.WORLD_WAR_2 -- elseif env.mission.date.Year < 1960 then -- settings[TUM.settings.id.TIME_PERIOD] = DCSEx.enums.timePeriod.KOREA_WAR -- elseif env.mission.date.Year < 1975 then -- settings[TUM.settings.id.TIME_PERIOD] = DCSEx.enums.timePeriod.VIETNAM_WAR -- elseif env.mission.date.Year < 1990 then -- settings[TUM.settings.id.TIME_PERIOD] = DCSEx.enums.timePeriod.COLD_WAR -- else -- settings[TUM.settings.id.TIME_PERIOD] = DCSEx.enums.timePeriod.MODERN -- end for i,id in pairs(SETTING_VALUES[TUM.settings.id.COALITION_BLUE]) do if id == Library.factions.defaults[coalition.side.BLUE] then settings[TUM.settings.id.COALITION_BLUE] = i end if id == Library.factions.defaults[coalition.side.RED] then settings[TUM.settings.id.COALITION_RED] = i end end if #DCSEx.envMission.getPlayerGroups(coalition.side.RED) > 0 then settings[TUM.settings.id.PLAYER_COALITION] = coalition.side.RED end end function TUM.settings.getSettingsName(id) return SETTING_NAMES[id] end function TUM.settings.getPossibleValues(id) return SETTING_VALUES[id]; end function TUM.settings.getValue(id, returnAsString) returnAsString = returnAsString or false if returnAsString then return SETTING_VALUES[id][settings[id]] end return settings[id] end function TUM.settings.getPlayerCoalition() return settings[TUM.settings.id.PLAYER_COALITION] end function TUM.settings.getEnemyCoalition() return DCSEx.dcs.getOppositeCoalition(settings[TUM.settings.id.PLAYER_COALITION]) end function TUM.settings.getPlayerFaction() return getFaction(TUM.settings.getPlayerCoalition()) end function TUM.settings.getEnemyFaction() return getFaction(TUM.settings.getEnemyCoalition()) end function TUM.settings.getSettingsSummary() local showScoreMultiplier = true if not DCSEx.io.canReadAndWrite() or TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then showScoreMultiplier = false end local settingsOrder = { TUM.settings.id.PLAYER_COALITION, TUM.settings.id.MULTIPLAYER, -1, TUM.settings.id.TIME_PERIOD, TUM.settings.id.COALITION_BLUE, TUM.settings.id.COALITION_RED, -1, TUM.settings.id.TASKING, TUM.settings.id.TARGET_LOCATION, TUM.settings.id.TARGET_COUNT, -1, TUM.settings.id.ENEMY_AIR_DEFENSE, TUM.settings.id.ENEMY_AIR_FORCE, -1, TUM.settings.id.WINGMEN, TUM.settings.id.AI_CAP, } local summary = "" for _,v in pairs(settingsOrder) do if v < 0 then summary = summary.."\n" else summary = summary.."\n"..SETTING_NAMES[v]:upper()..": " if type(settings[v]) == "boolean" then if settings[v] then summary = summary.."Enabled" else summary = summary.."Disabled" end else summary = summary..SETTING_VALUES[v][settings[v]] end if showScoreMultiplier then local settingMultiplier = TUM.playerScore.getScoreMultiplier(v, settings[v]) if settingMultiplier ~= nil then -- Must add "~= nil" because can be 0 summary = summary.." (" if settingMultiplier >= 0 then summary = summary.."+" end summary = summary..tostring(math.ceil(settingMultiplier * 100)).."% xp)" end end end end if showScoreMultiplier then summary = summary.."\n\nTotal XP modifier: "..tostring(math.ceil(TUM.playerScore.getTotalScoreMultiplier() * 100)).."%" end return summary end function TUM.settings.printSettingsSummary(clearView) trigger.action.outText("MISSION SETTINGS\n"..TUM.settings.getSettingsSummary(), 15, clearView or false) trigger.action.outSound("UI-Ok.ogg") end function TUM.settings.setValue(id, value, silent) silent = silent or false settings[id] = value if not silent then TUM.settings.printSettingsSummary(true) trigger.action.outSound("UI-Ok.ogg") end end function TUM.settings.onStartUp(coreSettings) -- Load mission zones SETTING_VALUES[TUM.settings.id.TARGET_LOCATION] = {} local missionZones = TUM.territories.getMissionZones() for _,m in ipairs(missionZones) do table.insert(SETTING_VALUES[TUM.settings.id.TARGET_LOCATION], m.name) end -- Load available coalitions SETTING_VALUES[TUM.settings.id.COALITION_BLUE] = { } SETTING_VALUES[TUM.settings.id.COALITION_RED] = { } for k,faction in pairs(Library.factions.tables) do if not faction.theaters or #faction.theaters == 0 or DCSEx.table.contains(faction.theaters, env.mission.theatre) then table.insert(SETTING_VALUES[TUM.settings.id.COALITION_BLUE], k) table.insert(SETTING_VALUES[TUM.settings.id.COALITION_RED], k) end end setAllToDefaults(coreSettings) TUM.settings.printSettingsSummary() return true end end -- ==================================================================================== -- TUM.SUPPORTAWACS - HANDLES THE FRIENDLY AWACS -- ==================================================================================== -- ==================================================================================== TUM.supportAWACS = {} do local awacsGroupID = nil local awacsCallsign = "AWACS" local function doAwacsPicture(bogeyDope, delayAnswer) delayAnswer = delayAnswer or false if not awacsGroupID then return end local awacsGroup = DCSEx.world.getGroupByID(awacsGroupID) if not awacsGroup then return end local awacsUnit = awacsGroup:getUnits()[1] if not awacsGroup then return end local awacsController = awacsUnit:getController() if not awacsController then return end local detectedAircraft = {} -- "REALISTIC" AWACS - gets unit list from the list of aircraft the AWACS actually detects -- local detectedUnits = awacsController:getDetectedTargets() -- for _,u in pairs(detectedUnits) do -- if u.object and u.distance and Object.getCategory(u.object) == Object.Category.UNIT and u.object:inAir() then -- if u.object:getCoalition() ~= TUM.settings.getPlayerCoalition() then -- table.insert(detectedAircraft, u.object) -- end -- end -- end -- "UNREALISTIC" AWACS - gets unit list straight from unit data, no matter what the AWACS can or cannot detect local detectedGroups = coalition.getGroups(TUM.settings.getEnemyCoalition(), Group.Category.AIRPLANE) for _,g in pairs(detectedGroups) do local units = g:getUnits() for _,u in pairs(units) do if u:inAir() then table.insert(detectedAircraft, u) end end end -- No aircraft on picture if #detectedAircraft == 0 then TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "awacsPictureClear", { awacsCallsign }, "Overlord", delayAnswer) return end for _,p in pairs(coalition.getPlayers(TUM.settings.getPlayerCoalition())) do local pVec3 = p:getPoint() local maxCount = 5 if bogeyDope then maxCount = 1 end -- TODO: Only report the nearest FIGHTER (not transport, awacs, etc) local sortedThreats = DCSEx.dcs.getNearestObjects(pVec3, detectedAircraft, maxCount) local pictureMsg = "" for ___,u in pairs(sortedThreats) do local typeName = Library.objectNames.get(u) pictureMsg = pictureMsg.."\n- "..typeName..", "..DCSEx.dcs.getBRAA(u:getPoint(), pVec3, true) end TUM.radio.playForUnit(DCSEx.dcs.getObjectIDAsNumber(p), "awacsPicture", { awacsCallsign, pictureMsg }, "Overlord", delayAnswer) end end local function doCommandPicture() TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "playerAwacsPicture", { awacsCallsign }, TUM.mission.getPlayerCallsign(), false) doAwacsPicture(false, true) end local function doCommandBogeyDope() TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "playerAwacsBogeyDope", { awacsCallsign }, TUM.mission.getPlayerCallsign(), false) doAwacsPicture(true, true) end ---------------------------------------------------------- -- Called on every mission update tick (every 15 seconds) -- @return True if something was done this tick, false otherwise ---------------------------------------------------------- function TUM.supportAWACS.onClockTick() if not awacsGroupID then return false end -- No awacs aircraft if TUM.mission.getStatus() == TUM.mission.status.NONE then return false end -- Not in a mission doAwacsPicture(false, false) return true end function TUM.supportAWACS.createMenu() if not awacsGroupID then return end -- No AWACS local rootMenu = TUM.getOrCreateRootMenu() local rootPath = missionCommands.addSubMenu("⌾ Awacs", rootMenu) missionCommands.addCommand("Bogey dope", rootPath, doCommandBogeyDope, nil) missionCommands.addCommand("Picture", rootPath, doCommandPicture, nil) end function TUM.supportAWACS.create() if awacsGroupID then return end -- Already spawned local awacsUnits = Library.factions.getUnits(TUM.settings.getPlayerFaction(), DCSEx.enums.unitFamily.PLANE_AWACS, 1) awacsCallsign = "AWACS" local awacsSpawnPoint = DCSEx.envMission.getPlayerGroupsCenterPoint(TUM.settings.getPlayerCoalition()) if awacsSpawnPoint then awacsSpawnPoint = DCSEx.math.randomPointInCircle(awacsSpawnPoint, DCSEx.converter.nmToMeters(10), DCSEx.converter.nmToMeters(5)) else awacsSpawnPoint = TUM.territories.getTerritoryCenter(TUM.settings.getPlayerCoalition()) end if awacsUnits and #awacsUnits > 0 then local groupInfo = DCSEx.unitGroupMaker.create( TUM.settings.getPlayerCoalition(), Group.Category.AIRPLANE, awacsSpawnPoint, { DCSEx.table.getRandom(awacsUnits) }, { immortal = true, invisible = true, silenced = true, taskAwacs = true, unlimitedFuel = true }) if groupInfo then awacsGroupID = groupInfo.groupID if groupInfo.callsign then awacsCallsign = groupInfo.callsign.name:sub(1, #groupInfo.callsign.name - 1) end TUM.log("Spawned AWACS aircraft") else TUM.log("Failed to create AWACS aircraft", TUM.logLevel.WARNING) end else TUM.log("No AWACS aircraft available") end end end -- ==================================================================================== -- TUM.SUPPORTJTAC - HANDLES FRIENDLY JTAC SMOKE MARKERS AND LASING -- ==================================================================================== -- ==================================================================================== TUM.supportJTAC = {} do local JTAC_CALLSIGNS = { "Anvil", "Axeman", "Badger", "Darknight", "Deathstar", "Eyeball", "Ferret", "Finger", "Firefly", "Hammer", "Jaguar", "Mantis", "Moonbeam", "Pinpoint", "Playboy", "Pointer", "Shaba", "Warrior", "Whiplash", } local SMOKE_DURATION = 300 -- in seconds local SMOKE_MARKER_PENALTY = -25 local jtacName = {} local lastSmoke = {} local function spawnSmoke(args) trigger.action.smoke(args.point3, args.smokeColor) end local function doCommandSmoke(index) local obj = TUM.objectives.getObjective(index) if not obj then return end -- Pick a smoke color local smokeColor = DCSEx.table.getRandom({ trigger.smokeColor.Red, trigger.smokeColor.Orange }) -- TODO: green or blue smoke when marking friendlies local smokeColorName = "red" if smokeColor == trigger.smokeColor.Orange then smokeColorName = "orange" end TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "playerJTACSmoke", { jtacName[index], obj.name }, TUM.mission.getPlayerCallsign(), false) if not lastSmoke[index] then lastSmoke[index] = -3600 end if lastSmoke[index] + SMOKE_DURATION > timer.getAbsTime() then TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "jtacSmokeAlreadyOut", { jtacName[index], obj.name }, jtacName[index], true) return end if obj.completed then TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "jtacSmokeNoTarget", { jtacName[index] }, jtacName[index], true) return end if obj.isSceneryTarget then TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "jtacSmokeOK", { jtacName[index], smokeColorName }, jtacName[index], true, spawnSmoke, { point3 = obj.point3, smokeColor = smokeColor }) else for _,id in ipairs(obj.unitsID) do if not DCSEx.table.contains(obj.completedUnitsID, id) then local unit = DCSEx.world.getUnitByID(id) if unit and unit:isActive() and unit:getLife() > 0 then TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "jtacSmokeOK", { jtacName[index], smokeColorName }, jtacName[index], true, spawnSmoke, { point3 = unit:getPoint(), smokeColor = smokeColor }) lastSmoke[index] = timer.getAbsTime() TUM.playerScore.award(SMOKE_MARKER_PENALTY, "called for smoke marker") return end end end end TUM.radio.playForCoalition(TUM.settings.getPlayerCoalition(), "jtacSmokeNoTarget", { jtacName[index] }, jtacName[index], true) end function TUM.supportJTAC.setupJTACOnObjective(index, menuRoot) local obj = TUM.objectives.getObjective(index) if not obj then return end jtacName[index] = DCSEx.table.getRandom(JTAC_CALLSIGNS) lastSmoke[index] = -3600 local objectiveDB = Library.tasks[obj.taskID] if not DCSEx.table.contains(objectiveDB.flags, DCSEx.enums.taskFlag.ALLOW_JTAC) then return end -- No JTAC for this objective missionCommands.addCommand("Smoke marker on target ("..tostring(SMOKE_MARKER_PENALTY).."xp)", menuRoot, doCommandSmoke, index) end end -- ==================================================================================== -- TUM.TERRITORIES - HANDLES THE MISSION SPECIAL ZONES (COALITION TERRITORIES, WATER AND BATTLE ZONES) -- ==================================================================================== -- (local) assignTerritoryToZone(coalitionID, zone) -- TUM.territories.getCenter(side) -- TUM.territories.getPointOwner(point) -- TUM.territories.getRandomPoint(side, surfaceType) -- TUM.territories.getSurfaceArea(side) -- TUM.territories.onInitialize() -- ==================================================================================== TUM.territories = {} do local coalitionZones = { {}, {} } local missionZones = {} local waterZones = {} local function addZoneToCoalition(zone, side) table.insert(coalitionZones[side], zone) local airbases = world.getAirbases() for _,ab in pairs(airbases) do local airbasePoint2 = DCSEx.math.vec3ToVec2(ab:getPoint()) if DCSEx.zones.isPointInside(zone, airbasePoint2) then if ab:getDesc().category ~= Airbase.Category.SHIP then -- Ignore ships ab:setCoalition(side) end end end end function TUM.territories.getMissionZones() return DCSEx.table.deepCopy(missionZones) end function TUM.territories.getWaterZones() return DCSEx.table.deepCopy(waterZones) end ------------------------------------- -- Returns the coalition to which belong a given point on the map. -- Return coalition.side.NEUTRAL if the point isn't in any coalition territory. -- @param point A vec2 or vec3 -- @return A value from the coalition.side enum ------------------------------------- function TUM.territories.getPointOwner(point) for side=1,2 do for _,z in ipairs(coalitionZones[side]) do if DCSEx.zones.isPointInside(z, point) then return side end end end return coalition.side.NEUTRAL end function TUM.territories.getTerritoryZones(side) return DCSEx.table.deepCopy(coalitionZones[side]) end function TUM.territories.getTerritoryCenter(side) local center = { x = 0, y = 0 } if #coalitionZones[side] == 0 then return center end for _,z in ipairs(coalitionZones[side]) do center.x = center.x + z.x center.y = center.y + z.y end -- TODO: bigger zones should skew the center in their favor center.x = center.x / #coalitionZones[side] center.y = center.y / #coalitionZones[side] return center end -- function TUM.territories.getCenter(side) -- return DCSEx.zones.getCenter(zones[side]) -- end -- function TUM.territories.getSurfaceArea(side) -- return DCSEx.zones.getSurfaceArea(zones[side]) -- end -- function TUM.territories.getZone(side) -- return DCSEx.table.deepCopy(zones[side]) -- end function TUM.territories.getRandomPointInTerritory(side, surfaceType) if #coalitionZones[side] == 0 then return nil end local zone = DCSEx.table.getRandom(coalitionZones[side]) -- TODO: bigger zones should be selected more often return DCSEx.zones.getRandomPointInside(zone, surfaceType) end ------------------------------------- -- Called on mission start up -- @return True if started up properly, false if an error happened ------------------------------------- function TUM.territories.onStartUp() coalitionZones = { {}, {} } missionZones = {} waterZones = {} -- Disable autocapture for all bases and give them to the neutral coalition for _,ab in pairs(world.getAirbases()) do ab:autoCapture(false) if ab:getDesc().category ~= Airbase.Category.SHIP then -- Ignore ships ab:setCoalition(coalition.side.NEUTRAL) end end local zones = DCSEx.zones.getAll() for _,z in ipairs(zones) do if DCSEx.string.startsWith(z.name:lower(), "blufor") then addZoneToCoalition(z, coalition.side.BLUE) elseif DCSEx.string.startsWith(z.name:lower(), "redfor") then addZoneToCoalition(z, coalition.side.RED) elseif DCSEx.string.startsWith(z.name:lower(), "water") then table.insert(waterZones, z) else local onlyZonesStartingWith = TUM.administrativeSettings.getValue(TUM.administrativeSettings.ONLY_ZONES_STARTINGWITH) if onlyZonesStartingWith and #onlyZonesStartingWith > 0 then if type(onlyZonesStartingWith) ~= "table" then onlyZonesStartingWith = { onlyZonesStartingWith } end for _, zonePrefix in ipairs(onlyZonesStartingWith) do if DCSEx.string.startsWith(z.name:lower(), zonePrefix:lower()) then table.insert(missionZones, z) break end end else local ignoreZonesStartingWith = TUM.administrativeSettings.getValue(TUM.administrativeSettings.IGNORE_ZONES_STARTINGWITH) if ignoreZonesStartingWith then if not DCSEx.string.startsWith(z.name:lower(), ignoreZonesStartingWith:lower()) then table.insert(missionZones, z) end else table.insert(missionZones, z) end end end end for side=1,2 do if #coalitionZones[side] == 0 or #coalition.getAirbases(side) == 0 then local name = DCSEx.dcs.getCoalitionAsString(side) local zoneName = "BLUFOR" if side == 1 then zoneName = "REDFOR" end TUM.log("Coalition "..name.." has no territory zones and/or controls no airfields. Please add zone with a name starting with "..zoneName.." in the mission editor and make sure at least one contains an airbase.", TUM.logLevel.ERROR) return false end end if #missionZones == 0 then TUM.log("No mission zones found. Create at least one mission zone in the mission editor.", TUM.logLevel.ERROR) return false end if #missionZones > 10 then TUM.log("Too many mission zones, extra zones removed.", TUM.logLevel.WARNING) while #missionZones > 10 do table.remove(missionZones, 11) end end -- zones = {} -- zones[coalition.side.BLUE] = DCSEx.zones.getByName("BLUFOR") -- zones[coalition.side.RED] = DCSEx.zones.getByName("REDFOR") -- if not zones[coalition.side.BLUE] then -- TUM.log("BLUFOR zone not found.", TUM.logLevel.ERROR) -- return false -- elseif not zones[coalition.side.RED] then -- TUM.log("REDFOR zone not found.", TUM.logLevel.ERROR) -- return false -- end -- -- TODO: square kilometers if "metric system" enabled? -- for side=1,2 do -- TUM.log( -- "Coalition "..DCSEx.dcs.getCoalitionAsString(side):upper().."'s territory is ".. -- DCSEx.string.toStringThousandsSeparator(math.floor(TUM.territories.getSurfaceArea(side) / 2589988.110336)).." squared miles.") -- end return true end end -- ==================================================================================== -- TUM.WINGMEN - HANDLES THE PLAYER'S WINGMEN -- ==================================================================================== -- ==================================================================================== TUM.wingmen = {} do local DEFAULT_PAYLOAD = "attack" -- Default payload local wingmenGroupID = nil local wingmenUnitID = {} local function getWingmanPayloadForMission() if TUM.mission.getStatus() == TUM.mission.status.NONE then return DEFAULT_PAYLOAD end local taskingID = TUM.settings.getValue(TUM.settings.id.TASKING) if taskingID == DCSEx.enums.taskFamily.ANTISHIP then return "antiship" -- elseif taskingID == DCSEx.enums.taskFamily.CAP = 2 then -- elseif taskingID == DCSEx.enums.taskFamily.CAS = 3 then elseif taskingID == DCSEx.enums.taskFamily.GROUND_ATTACK then return "attack" -- elseif taskingID == DCSEx.enums.taskFamily.HELICOPTER then -- elseif taskingID == DCSEx.enums.taskFamily.HELO_HUN then elseif taskingID == DCSEx.enums.taskFamily.INTERCEPTION then return "cap" -- elseif taskingID == DCSEx.enums.taskFamily.OCA then elseif taskingID == DCSEx.enums.taskFamily.SEAD then return "sead" -- elseif taskingID == DCSEx.enums.taskFamily.STRIKE then -- return "strike" end return DEFAULT_PAYLOAD end function TUM.wingmen.create() TUM.wingmen.removeAll() -- Destroy all pre-existing wingmen if TUM.settings.getValue(TUM.settings.id.WINGMEN) <= 1 then return end -- No wingmen TUM.log("Creating wingmen...") local player = world:getPlayer() if not player then return end -- Retrive player unit type local playerTypeName = player:getTypeName() if not Library.aircraft[playerTypeName] then TUM.log("Cannot spawn AI wingmen, aircraft \""..playerTypeName.."\" not found in the database.", TUM.logLevel.WARNING) return end local playerCategory = Group.Category.AIRPLANE if player:hasAttribute("Helicopters") then playerCategory = Group.Category.HELICOPTER end -- Player is a helicopter -- Generate wingman callsign local wingmanCallsign = DCSEx.envMission.getPlayerGroups()[1].units[1].callsign if type(wingmanCallsign) == "table" then wingmanCallsign[3] = nil wingmanCallsign["name"] = wingmanCallsign["name"]:sub(1, #wingmanCallsign["name"] - 1) if wingmanCallsign[4] then wingmanCallsign[4] = wingmanCallsign["name"] end else wingmanCallsign = DCSEx.unitCallsignMaker.getCallsign(playerTypeName) end local unitCount = TUM.settings.getValue(TUM.settings.id.WINGMEN) - 1 local unitList = {} for _=1,unitCount do table.insert(unitList, playerTypeName) end -- Select proper payload for mission local groupInfo = DCSEx.unitGroupMaker.create( TUM.settings.getPlayerCoalition(), playerCategory, DCSEx.math.randomPointInCircle(DCSEx.math.vec3ToVec2(player:getPoint()), 500, 250), unitList, { altitude = math.min(player:getPoint().y + 1524, 3048), -- spawn at player altitude + 5,000ft, up to a max of 10,000ft (to avoid crashes into nearby hills) callsign = wingmanCallsign, callsignOffset = 1, payload = getWingmanPayloadForMission(), prohibitJettison = true, silenced = true, skill = "Excellent", taskFollow = DCSEx.dcs.getObjectIDAsNumber(player:getGroup()), unlimitedFuel = true } ) if not groupInfo then TUM.log("Failed to spawn AI wingmen", TUM.logLevel.WARNING) return end wingmenGroupID = groupInfo.groupID wingmenUnitID = DCSEx.table.deepCopy(groupInfo.unitsID) -- Reinitialize list of known contacts and contact report interval TUM.wingmenContacts.clearKnownContacts() TUM.wingmenTasking.resetTaskingParameters() TUM.log("Spawned AI wingmen") TUM.radio.playForAll("pilotWingmanTakeOff", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), true) TUM.wingmenTasking.commandRejoin(nil, true, true) -- Task the new wingmen to rejoin end function TUM.wingmen.getController() local wingmenGroup = TUM.wingmen.getGroup() if not wingmenGroup then return nil end return wingmenGroup:getController() end function TUM.wingmen.getFirstWingmanCallsign() for i=1,#wingmenUnitID do local wingmanUnit = DCSEx.world.getUnitByID(wingmenUnitID[i]) if wingmanUnit then return wingmanUnit:getCallsign() end end return "Flight" end function TUM.wingmen.getFirstWingmanUnit() for i=1,#wingmenUnitID do local wingmanUnit = DCSEx.world.getUnitByID(wingmenUnitID[i]) if wingmanUnit then return wingmanUnit end end return nil end function TUM.wingmen.getFirstWingmanNumber() for i=1,#wingmenUnitID do local wingmanUnit = DCSEx.world.getUnitByID(wingmenUnitID[i]) if wingmanUnit then return DCSEx.string.toStringNumber(i + 1, true) end end return "Flight" end function TUM.wingmen.getGroup() if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return nil end -- No wingmen in multiplayer if not wingmenGroupID then return nil end local wingmenGroup = DCSEx.world.getGroupByID(wingmenGroupID) if not wingmenGroup then return nil end -- if #wingmenGroup:getUnits() <= 0 then return nil end if wingmenGroup:getSize() <= 0 then return nil end return wingmenGroup end function TUM.wingmen.removeAll() if not wingmenGroupID then return end TUM.log("Removing all wingmen...") DCSEx.world.destroyGroupByID(wingmenGroupID) wingmenGroupID = nil wingmenUnitID = {} end ------------------------------------- -- Called when an event is raised -- @param event The DCS World event ------------------------------------- function TUM.wingmen.onEvent(event) if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No wingmen in multiplayer if not event.initiator then return end if Object.getCategory(event.initiator) ~= Object.Category.UNIT then return end if event.id == world.event.S_EVENT_UNIT_LOST then local unitWingmenNumber = TUM.wingmen.getUnitWingmanNumber(event.initiator) if unitWingmenNumber then TUM.radio.playForAll("pilotWingmanDown", { DCSEx.string.toStringNumber(unitWingmenNumber, true) }, event.initiator:getCallsign(), false) return end elseif event.id == world.event.S_EVENT_TAKEOFF then -- Create wingmen on player takeoff if not event.initiator:getPlayerName() then return end if TUM.mission.getStatus() == TUM.mission.status.NONE then return end -- Mission not in progress, no wingman needed TUM.wingmen.create() elseif event.id == world.event.S_EVENT_LAND then -- Remove wingmen on player landing if not event.initiator:getPlayerName() then return end TUM.wingmen.removeAll() end end function TUM.wingmen.getUnitWingmanNumber(unit) if not unit then return nil end local unitID = DCSEx.dcs.getObjectIDAsNumber(unit) for i,id in ipairs(wingmenUnitID) do if unitID == id then return i + 1 end end return nil end end -- ==================================================================================== -- TUM.WINGMEN - HANDLES THE WINGMEN'S CONTACTS -- ==================================================================================== -- ==================================================================================== TUM.wingmenContacts = {} do local CONTACT_REPORT_INTERVAL = 8 -- Called AT MOST every 15 seconds, so 6 means "AT MOST every two minutes" local knownGroupsID = {} local newGroupsID = {} local ticksLeftBeforeContactReport = CONTACT_REPORT_INTERVAL local function getGroupDetectionRange(grp) if not grp then return 0.0 end local gCateg = Group.getCategory(grp) -- Take into account better sensors (radars, TGPs...) in later periods local detectionRangeMultiplier = 1.0 if TUM.settings.getValue(TUM.settings.id.TIME_PERIOD) == DCSEx.enums.timePeriod.MODERN then detectionRangeMultiplier = 2.0 elseif TUM.settings.getValue(TUM.settings.id.TIME_PERIOD) == DCSEx.enums.timePeriod.COLD_WAR then detectionRangeMultiplier = 1.5 elseif TUM.settings.getValue(TUM.settings.id.TIME_PERIOD) == DCSEx.enums.timePeriod.VIETNAM_WAR then detectionRangeMultiplier = 1.25 end local detectionRange = DCSEx.converter.nmToMeters(15 * detectionRangeMultiplier) if gCateg == Group.Category.AIRPLANE then detectionRange = DCSEx.converter.nmToMeters(35 * detectionRangeMultiplier) elseif gCateg == Group.Category.SHIP then detectionRange = DCSEx.converter.nmToMeters(25 * detectionRangeMultiplier) local onlySpeedboats = true for _,u in ipairs(grp:getUnits()) do if u:getTypeName() ~= "speedboat" then onlySpeedboats = false end end if onlySpeedboats then detectionRange = detectionRange / 8 end -- Speedboats are HARD to spot elseif gCateg == Group.Category.GROUND then local onlyInfantry = true for _,u in ipairs(grp:getUnits()) do if not u:hasAttribute("Infantry") then onlyInfantry = false end end if onlyInfantry then detectionRange = detectionRange / 8 end -- Infantry is HARD to spot end return detectionRange end function TUM.wingmenContacts.clearKnownContacts() knownGroupsID = {} newGroupsID = {} ticksLeftBeforeContactReport = CONTACT_REPORT_INTERVAL end function TUM.wingmenContacts.getContacts(groupCategory) if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return {} end -- No wingmen in multiplayer if TUM.mission.getStatus() == TUM.mission.status.NONE then return {} end local wingmenGroup = TUM.wingmen.getGroup() if not wingmenGroup then return {} end local searchPoint = DCSEx.world.getGroupCenter(wingmenGroup) local detectedTargets = {} local allGroups = coalition.getGroups(TUM.settings.getEnemyCoalition(), groupCategory) for _,g in ipairs(allGroups) do local gID = g:getID() if g:isExist() and g:getSize() > 0 then local gPos = DCSEx.world.getGroupCenter(g) local gCateg = Group.getCategory(g) local detectionRange = getGroupDetectionRange(g) local distanceToGroup = DCSEx.math.getDistance2D(gPos, searchPoint) if distanceToGroup <= detectionRange then -- Check if wingman group is in detection range if not DCSEx.table.contains(knownGroupsID, gID) then table.insert(knownGroupsID, gID) table.insert(newGroupsID, gID) end local groupInfo = { id = gID, point2 = gPos, size = g:getSize(), type = "contact" } if gCateg == Group.Category.AIRPLANE or gCateg == Group.Category.HELICOPTER then -- if distanceToGroup < detectionRange / 2 then groupInfo.type = Library.objectNames.get(g:getUnit(1)) -- else -- groupInfo.type = Library.objectNames.getGenericGroup(g) -- end else groupInfo.type = Library.objectNames.getGenericGroup(g) end table.insert(detectedTargets, groupInfo) end end end return detectedTargets end function TUM.wingmenContacts.getContactsAsReportString(groupCategory, giveRelativePosition, newContactsOnly) giveRelativePosition = giveRelativePosition or false newContactsOnly = newContactsOnly or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return nil end -- No wingmen in multiplayer local contacts = TUM.wingmenContacts.getContacts(groupCategory) if not contacts or #contacts == 0 then return nil end local refPoint = DCSEx.world.getGroupCenter(TUM.wingmen.getGroup()) local reportText = "" for _,t in ipairs(contacts) do if not newContactsOnly or DCSEx.table.contains(newGroupsID, t.id) then reportText = reportText.."\n - "..tostring(t.size).."x "..t.type if refPoint and giveRelativePosition then reportText = reportText..", "..DCSEx.dcs.getBRAA(t.point2, refPoint, false, false, false) end end end return reportText end ---------------------------------------------------------- -- Called on every mission update tick (every 10-20 seconds) -- @return True if something was done this tick, false otherwise ---------------------------------------------------------- function TUM.wingmenContacts.onClockTick() if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer if TUM.mission.getStatus() == TUM.mission.status.NONE then return false end TUM.wingmenContacts.getContacts() -- Check for new contacts, just in case if #newGroupsID > 0 then -- New contacts found, alert the player! local newContactsReportString = TUM.wingmenContacts.getContactsAsReportString(nil, true, true) TUM.radio.playForAll("pilotWingmanReportContactsNew", { TUM.wingmen.getFirstWingmanNumber(), newContactsReportString }, TUM.wingmen.getFirstWingmanCallsign(), false) newGroupsID = {} if ticksLeftBeforeContactReport < math.floor(CONTACT_REPORT_INTERVAL / 2) then ticksLeftBeforeContactReport = math.floor(CONTACT_REPORT_INTERVAL / 2) end return true end ticksLeftBeforeContactReport = ticksLeftBeforeContactReport - 1 if ticksLeftBeforeContactReport > 0 then return false end ticksLeftBeforeContactReport = CONTACT_REPORT_INTERVAL return TUM.wingmenTasking.commandReportContacts(nil, true, false) end end -- ==================================================================================== -- TUM.WINGMENMENU - HANDLES THE WINGMEN'S F10 MENU -- ==================================================================================== -- ==================================================================================== TUM.wingmenMenu = {} do local function radioCommandChangeAltitude(args) local player = world:getPlayer() if not player then return end TUM.radio.playForAll("playerWingmanChangeAltitude", { args.altitudeText }, player:getCallsign(), false) TUM.wingmenTasking.commandChangeAltitude(args.altitudeFraction, true) end local function radioCommandCoverMe() local player = world:getPlayer() if not player then return end TUM.radio.playForAll("playerWingmanCoverMe", nil, player:getCallsign(), false) TUM.wingmenTasking.commandEngage(Group.Category.AIRPLANE, { "Fighters", "Interceptors", "Multirole fighters" } , true) end local function radioCommandEngage(args) local player = world:getPlayer() if not player then return end args.radioTargetName = args.radioTargetName or "hostile" TUM.radio.playForAll("playerWingmanEngage"..args.radioMessageSuffix, { args.radioTargetName }, player:getCallsign(), false) TUM.wingmenTasking.commandEngage(args.category, args.attributes, true) end -- local function radioCommandGoToMapMarker() -- local player = world:getPlayer() -- if not player then return end -- TUM.radio.playForAll("playerWingmanGoToMarker", nil, player:getCallsign(), false) -- TUM.wingmenTasking.commandGoToMapMarker(TUM.wingmenTasking.DEFAULT_MARKER_TEXT, true) -- end local function radioCommandOrbit() local player = world:getPlayer() if not player then return end TUM.radio.playForAll("playerWingmanOrbit", nil, player:getCallsign(), false) TUM.wingmenTasking.commandOrbit(true) end local function radioCommandRejoin() local player = world:getPlayer() if not player then return end TUM.radio.playForAll("playerWingmanRejoin", nil, player:getCallsign(), false) TUM.wingmenTasking.commandRejoin(nil, true) end local function radioCommandReportContacts() local player = world:getPlayer() if not player then return false end TUM.radio.playForAll("playerWingmanReportContacts", nil, player:getCallsign(), false) TUM.wingmenTasking.commandReportContacts(nil, false, true) end local function radioCommandReportStatus() local player = world:getPlayer() if not player then return end TUM.radio.playForAll("playerWingmanReportStatus", nil, player:getCallsign(), false) TUM.wingmenTasking.commandReportStatus(true) end function TUM.wingmenMenu.create() local rootMenu = TUM.getOrCreateRootMenu() if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return end -- No wingmen in multiplayer if TUM.settings.getValue(TUM.settings.id.WINGMEN) <= 1 then return end -- No wingmen local isWW2 = (TUM.settings.getValue(TUM.settings) == DCSEx.enums.timePeriod.WORLD_WAR_2) -- Some options are different when time period is WW2 local rootPath = missionCommands.addSubMenu("✈ Flight", rootMenu) missionCommands.addCommand("Cover me!", rootPath, radioCommandCoverMe, nil) ------------------------------------------------------ -- "Engage targets" submenu ------------------------------------------------------ local engagePath = missionCommands.addSubMenu("Engage", rootPath) local engageSubPath = nil -- Aircraft -- (radioTargetName must be plural) engageSubPath = missionCommands.addSubMenu("Aircraft", engagePath) missionCommands.addCommand("Any aircraft", engageSubPath, radioCommandEngage, { attributes = nil, category = Group.Category.AIRPLANE, radioMessageSuffix = "Bandits", radioTargetName = "bandits" }) missionCommands.addCommand("Fighters", engageSubPath, radioCommandEngage, { attributes = { "Fighters", "Interceptors", "Multirole fighters" }, category = Group.Category.AIRPLANE, radioMessageSuffix = "Bandits", radioTargetName = "fighters" }) missionCommands.addCommand("Bombers and transports", engageSubPath, radioCommandEngage, { attributes = { "Bombers", "Transports", "AWACS" }, category = Group.Category.AIRPLANE, radioMessageSuffix = "Bandits", radioTargetName = "strategic aircraft" }) if not isWW2 then missionCommands.addCommand("Helicopters", engageSubPath, radioCommandEngage, { attributes = nil, category = Group.Category.HELICOPTER, radioMessageSuffix = "Bandits", radioTargetName = "helos" }) end -- Ground -- (radioTargetName must be singular) engageSubPath = missionCommands.addSubMenu("Ground", engagePath) missionCommands.addCommand("Any ground vehicles", engageSubPath, radioCommandEngage, { attributes = {"Tanks", "Trucks", "Artillery", "IFV", "APC"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "ground" }) missionCommands.addCommand("Armor", engageSubPath, radioCommandEngage, { attributes = {"Tanks", "IFV", "APC"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "armor" }) missionCommands.addCommand("Armor (APCs only)", engageSubPath, radioCommandEngage, { attributes = {"IFV", "APC"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "armor" }) missionCommands.addCommand("Armor (tanks only)", engageSubPath, radioCommandEngage, { attributes = {"Tanks"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "armor" }) missionCommands.addCommand("Artillery", engageSubPath, radioCommandEngage, { attributes = {"Artillery"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "artillery" }) missionCommands.addCommand("Infantry", engageSubPath, radioCommandEngage, { attributes = {"Infantry"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "infantry" }) missionCommands.addCommand("Trucks", engageSubPath, radioCommandEngage, { attributes = {"Trucks"}, category = Group.Category.GROUND, radioMessageSuffix = "Ground", radioTargetName = "truck" }) -- Air defense -- (radioTargetName must be singular) engageSubPath = missionCommands.addSubMenu("Air defense", engagePath) missionCommands.addCommand("Any air defense", engageSubPath, radioCommandEngage, { attributes = { "Air Defence" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "air defense" }) missionCommands.addCommand("AAA", engageSubPath, radioCommandEngage, { attributes = { "AAA" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "AAA" }) if not isWW2 then missionCommands.addCommand("MANPADS", engageSubPath, radioCommandEngage, { attributes = { "MANPADS" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "MANPADS" }) missionCommands.addCommand("Short range SAMs", engageSubPath, radioCommandEngage, { attributes = { "SR SAM", "IR Guided SAM" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "short-range SAM" }) missionCommands.addCommand("Short range SAMs (IR only)", engageSubPath, radioCommandEngage, { attributes = { "IR Guided SAM" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "IR SAM" }) missionCommands.addCommand("Short range SAMs (radar only)", engageSubPath, radioCommandEngage, { attributes = { "SR SAM" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "SHORAD" }) missionCommands.addCommand("Long-range SAMs", engageSubPath, radioCommandEngage, { attributes = { "LR SAM", "MR SAM" }, category = Group.Category.GROUND, radioMessageSuffix = "AirDefense", radioTargetName = "long-range SAM" }) end -- Ships -- (radioTargetName must be plural) engageSubPath = missionCommands.addSubMenu("Ships", engagePath) missionCommands.addCommand("Any ship", engageSubPath, radioCommandEngage, { attributes = nil, category = Group.Category.SHIP, radioMessageSuffix = "Ships", radioTargetName = "ships" }) missionCommands.addCommand("Armed ships", engageSubPath, radioCommandEngage, { attributes = { "Armed ships" }, category = Group.Category.SHIP, radioMessageSuffix = "Ships", radioTargetName = "armed ships" }) missionCommands.addCommand("Cargo ships", engageSubPath, radioCommandEngage, { attributes = { "Unarmed ships" }, category = Group.Category.SHIP, radioMessageSuffix = "Ships", radioTargetName = "cargo ships" }) -- Structures missionCommands.addCommand("Structures", engagePath, radioCommandEngage, { attributes = nil, category = "strike", radioMessageSuffix = "Strike", radioTargetName = "building" }) ------------------------------------------------------ -- missionCommands.addCommand("Go to map marker "..TUM.wingmenTasking.DEFAULT_MARKER_TEXT:upper(), rootPath, radioCommandGoToMapMarker, nil) missionCommands.addCommand("Report contacts", rootPath, radioCommandReportContacts, nil) missionCommands.addCommand("Hold position", rootPath, radioCommandOrbit, nil) ------------------------------------------------------ -- "Change altitude" submenu ------------------------------------------------------ local altitudePath = missionCommands.addSubMenu("Change altitude", rootPath) local baseAltitude = DCSEx.converter.metersToFeet(Library.aircraft[world.getPlayer():getTypeName()].altitude) local altitudeFactions = { 0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5 } for _,f in ipairs(altitudeFactions) do local altText = DCSEx.string.toStringThousandsSeparator(math.floor((baseAltitude * f) / 100) * 100).."ft" if f == 0 then altText = "nap-of-the-earth" end missionCommands.addCommand(DCSEx.string.firstToUpper(altText), altitudePath, radioCommandChangeAltitude, { altitudeFraction = f, altitudeText = altText }) end missionCommands.addCommand("Status report", rootPath, radioCommandReportStatus, nil) missionCommands.addCommand("Rejoin", rootPath, radioCommandRejoin, nil) end end -- ==================================================================================== -- TUM.WINGMENTASKING - HANDLES THE WINGMEN'S TASKING -- ==================================================================================== -- ==================================================================================== TUM.wingmenTasking = {} do TUM.wingmenTasking.DEFAULT_MARKER_TEXT = "flight" local MAX_STRUCTURE_ENGAGEMENT_RANGE = DCSEx.converter.nmToMeters(25) local mapMarkerMissingWarningAlreadyDisplayed = false -- Was the "map marker missing" warning already displayed during the mission? local targetPointMapMarker = nil local currentTargetIDorPoint = nil -- ID for groups/statics, point2 for scenery objects local currentTargetType = nil local cruiseAltitudeFraction = 1.0 -- Fraction of the default aircraft cruise altitude local wingmenTick = 0 -- Number of clockticks with active wingmen local function allowWeaponUse(wingmenCtrl, allowAA, allowAG) allowAA = allowAA or false allowAG = allowAG or false wingmenCtrl:setOption(AI.Option.Air.id.REACTION_ON_THREAT, AI.Option.Air.val.REACTION_ON_THREAT.EVADE_FIRE) wingmenCtrl:setOption(AI.Option.Air.id.PROHIBIT_AA, not allowAA) wingmenCtrl:setOption(AI.Option.Air.id.PROHIBIT_AG, not allowAG) end local function getAltitude() local player = world.getPlayer() if not player then return 600 end -- Don't care about altitude if player's dead anyway local altitude = Library.aircraft[player:getTypeName()].altitude * cruiseAltitudeFraction return altitude end local function setWingmenAltitude(altitude) local wingmenCtrl = TUM.wingmen.getController() if not wingmenCtrl then return nil end altitude = altitude or getAltitude() altitude = math.max(50, altitude) altitude = altitude * DCSEx.math.randomFloat(0.98, 1.02) -- add a slight variation wingmenCtrl:setAltitude(altitude, true, AI.Task.AltitudeType.BARO) end local function doCommandEngageStrikeTargets() -- Not a strike mission, so no strike targets if TUM.settings.getValue(TUM.settings.id.TASKING) ~= DCSEx.enums.taskFamily.STRIKE then return nil end local wingmenCtrl = TUM.wingmen.getController() if not wingmenCtrl then return nil end local wingmenPosition = DCSEx.world.getGroupCenter(TUM.wingmen.getGroup()) -- Look for nearest strike target local nearestDistance = 9999999999 local nearestTarget = nil local nearestTargetType = nil for i=1,TUM.objectives.getCount() do local obj = TUM.objectives.getObjective(i) if obj and not obj.completed then local objectiveDB = Library.tasks[obj.taskID] if objectiveDB.targetFamilies and #objectiveDB.targetFamilies > 0 then local distanceFromTarget = DCSEx.math.getDistance2D(wingmenPosition, obj.point2) if distanceFromTarget < nearestDistance and distanceFromTarget < MAX_STRUCTURE_ENGAGEMENT_RANGE then if objectiveDB.targetFamilies[1] == DCSEx.enums.unitFamily.STATIC_SCENERY then nearestDistance = distanceFromTarget nearestTargetType = "scenery" nearestTarget = obj.point2 elseif obj.unitsID and #obj.unitsID >= 1 then nearestDistance = distanceFromTarget nearestTargetType = "static" nearestTarget = obj.unitsID[1] end end end end end if not nearestTarget or not nearestTargetType then return nil end if nearestTargetType == "static" then currentTargetType = nearestTargetType currentTargetIDorPoint = nearestTarget local taskTable = { id = "AttackUnit", params = { groupAttack = true, unitId = nearestTarget, } } allowWeaponUse(wingmenCtrl, false, true) setWingmenAltitude() wingmenCtrl:setTask(taskTable) return DCSEx.world.getStaticObjectByID(nearestTarget):getPoint() elseif nearestTargetType == "scenery" then currentTargetType = nearestTargetType currentTargetIDorPoint = nearestTarget local taskTable = { id = "AttackMapObject", params = { groupAttack = true, point = nearestTarget, } } allowWeaponUse(wingmenCtrl, false, true) setWingmenAltitude() wingmenCtrl:setTask(taskTable) return DCSEx.math.vec2ToVec3(nearestTarget, "land") end return nil end local function getOrbitTaskTable(point2) return { id = "Orbit", params = { altitude = getAltitude(), pattern = "Circle", point = point2, width = DCSEx.converter.nmToMeters(1.0) } } end local function getRejoinTaskTable(formationDistance) formationDistance = formationDistance or 800 return { id = "Follow", params = { groupId = DCSEx.dcs.getObjectIDAsNumber(world.getPlayer():getGroup()), lastWptIndexFlag = false, lastWptIndex = -1, pos = { x = -formationDistance, y = 0, z = -formationDistance } } } end function TUM.wingmenTasking.commandChangeAltitude(altFraction, delayRadioAnswer) cruiseAltitudeFraction = DCSEx.math.clamp(altFraction or 1.0, 0.0, 2.0) local newAlt = getAltitude() local newAltStr = "nap-of-the-earth" if altFraction > 0 then newAltStr = DCSEx.string.toStringThousandsSeparator(math.floor(DCSEx.converter.metersToFeet(newAlt) / 100) * 100).."ft" end setWingmenAltitude() TUM.radio.playForAll("pilotWingmanChangeAltitude", { TUM.wingmen.getFirstWingmanNumber(), newAltStr }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return true end function TUM.wingmenTasking.commandEngage(groupCategory, targetAttributes, delayRadioAnswer) delayRadioAnswer = delayRadioAnswer or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer local wingmenCtrl = TUM.wingmen.getController() if not wingmenCtrl then return false end -- Strike targets are handled differently if groupCategory == "strike" then local targetPoint3 = doCommandEngageStrikeTargets() if targetPoint3 then TUM.radio.playForAll("pilotWingmanEngageStrike", { TUM.wingmen.getFirstWingmanNumber(), DCSEx.dcs.getBRAA(targetPoint3, DCSEx.world.getGroupCenter(TUM.wingmen.getGroup()), false) }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return true else TUM.radio.playForAll("pilotWingmanEngageNoTarget", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return false end end local detectedContacts = TUM.wingmenContacts.getContacts(groupCategory) local validTargets = {} for _,c in ipairs(detectedContacts) do local g = DCSEx.world.getGroupByID(c.id) if g then local gUnits = g:getUnits() for _,u in ipairs(gUnits) do local isValid = false if not targetAttributes or #targetAttributes == 0 then isValid = true else for _,a in ipairs(targetAttributes) do if u:hasAttribute(a) then isValid = true break end end end if isValid then table.insert(validTargets, u) end end end end if #validTargets == 0 then TUM.radio.playForAll("pilotWingmanEngageNoTarget", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return false end local wingmenPosition = DCSEx.world.getGroupCenter(TUM.wingmen.getGroup()) validTargets = DCSEx.dcs.getNearestObjects(wingmenPosition, validTargets, 1) local target = validTargets[1] currentTargetIDorPoint = DCSEx.dcs.getGroupIDAsNumber(target:getGroup()) currentTargetType = "group" -- If target is tough, make everyone attack it. Else, only one aircraft attack to save ammo local allWingmenShouldAttack = false if target:hasAttribute("Heavy armed ships") then allWingmenShouldAttack = true elseif (target:hasAttribute("MR SAM") or target:hasAttribute("MR SAM")) and target:hasAttribute("SAM TR") then allWingmenShouldAttack = true end local taskTable = { id = "AttackGroup", params = { groupAttack = allWingmenShouldAttack, groupId = currentTargetIDorPoint, } } local targetInAir = target:inAir() allowWeaponUse(wingmenCtrl, targetInAir, not targetInAir) setWingmenAltitude() wingmenCtrl:setTask(taskTable) local targetBRAA = "distance unknown" local targetInfo = nil local messageSuffix = nil if targetInAir then messageSuffix = "Air" targetInfo = Library.objectNames.get(target) targetBRAA = DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, true) else messageSuffix = "Surface" targetInfo = Library.objectNames.getGeneric(target) targetBRAA = DCSEx.dcs.getBRAA(target:getPoint(), wingmenPosition, false) end -- Mark the last targeted point in debug mode if TUM.DEBUG_MODE then if targetPointMapMarker then trigger.action.removeMark(targetPointMapMarker) targetPointMapMarker = nil end targetPointMapMarker = DCSEx.world.getNextMarkerID() trigger.action.markToAll(targetPointMapMarker, "Last wingmen attack point", target:getPoint(), true) end TUM.radio.playForAll("pilotWingmanEngage"..messageSuffix, { TUM.wingmen.getFirstWingmanNumber(), targetInfo, targetBRAA }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return true end function TUM.wingmenTasking.commandGoToMapMarker(markerText, delayRadioAnswer) markerText = markerText or TUM.wingmenTasking.DEFAULT_MARKER_TEXT delayRadioAnswer = delayRadioAnswer or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer local mapMarker = DCSEx.world.getMarkerByText(markerText) if not mapMarker and not mapMarkerMissingWarningAlreadyDisplayed then trigger.action.outText("Map marker missing.\nYou must create a marker on the F10 map and set it text to \""..markerText:upper().."\" (without quotes) to communicate coordinates to your wingmen.", 10) mapMarkerMissingWarningAlreadyDisplayed = true end local wingmenCtrl = TUM.wingmen.getController() if not wingmenCtrl then return false end if not mapMarker then -- TUM.radio.playForAll("pilotWingmanGoToMarkerNoMarker", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return false end currentTargetIDorPoint = nil allowWeaponUse(wingmenCtrl, false, false) setWingmenAltitude() wingmenCtrl:setTask(getOrbitTaskTable(DCSEx.math.vec3ToVec2(mapMarker.pos))) -- TUM.radio.playForAll("pilotWingmanGoToMarker", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return true end function TUM.wingmenTasking.commandOrbit(delayRadioAnswer) delayRadioAnswer = delayRadioAnswer or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer local wingmenCtrl = TUM.wingmen.getController() if not wingmenCtrl then return false end allowWeaponUse(wingmenCtrl, false, false) currentTargetIDorPoint = nil setWingmenAltitude() wingmenCtrl:setTask(getOrbitTaskTable(DCSEx.world.getGroupCenter(TUM.wingmen.getGroup()))) TUM.radio.playForAll("pilotWingmanOrbit", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return true end function TUM.wingmenTasking.commandRejoin(formationDistance, delayRadioAnswer, silent, taskingComplete) delayRadioAnswer = delayRadioAnswer or false silent = silent or false taskingComplete = taskingComplete or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer local player = world:getPlayer() if not player then return false end local wingmenCtrl = TUM.wingmen.getController() if not wingmenCtrl then return false end currentTargetIDorPoint = nil allowWeaponUse(wingmenCtrl, false, false) -- setWingmenAltitude(player:getPoint().y) setWingmenAltitude() wingmenCtrl:setTask(getRejoinTaskTable(formationDistance)) if not silent then local msgID = "pilotWingmanRejoin" if taskingComplete then msgID = "pilotWingmanRejoinTaskComplete" end TUM.radio.playForAll(msgID, { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) end return true end function TUM.wingmenTasking.commandReportContacts(groupCategory, noReportIfNoContacts, delayRadioAnswer) noReportIfNoContacts = noReportIfNoContacts or false delayRadioAnswer = delayRadioAnswer or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer local reportString = TUM.wingmenContacts.getContactsAsReportString(groupCategory, true) if not reportString then if noReportIfNoContacts then return false end TUM.radio.playForAll("pilotWingmanReportContactsNoJoy", { TUM.wingmen.getFirstWingmanNumber() }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) else TUM.radio.playForAll("pilotWingmanReportContacts", { TUM.wingmen.getFirstWingmanNumber(), reportString }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) end return true end function TUM.wingmenTasking.commandReportStatus(delayRadioAnswer) delayRadioAnswer = delayRadioAnswer or false if TUM.settings.getValue(TUM.settings.id.MULTIPLAYER) then return false end -- No wingmen in multiplayer local wingmenGroup = TUM.wingmen.getGroup() if not wingmenGroup then return false end local groupUnits = wingmenGroup:getUnits() local statusMsg = "" for i,u in ipairs(groupUnits) do statusMsg = statusMsg..u:getCallsign():upper().."\n" if u:getLife() >= u:getLife0() then statusMsg = statusMsg.."- No damage sustained, fuel green" else statusMsg = statusMsg.."- Aircraft suffered damage, fuel green" end statusMsg = statusMsg.."\n- BRAA from you: "..DCSEx.dcs.getBRAA(u:getPoint(), DCSEx.math.vec3ToVec2(world:getPlayer():getPoint()), true) statusMsg = statusMsg.."\n- Armament: " local ammo = u:getAmmo() if #ammo == 0 then statusMsg = statusMsg.."None" else for j,a in ipairs(ammo) do if a.count and a.desc and (a.desc.displayName or a.desc.typeName) then local ammoName = a.desc.displayName or a.desc.typeName if j > 1 then statusMsg = statusMsg..", " end statusMsg = statusMsg..tostring(a.count).."x "..ammoName end end end if i < #groupUnits then statusMsg = statusMsg.."\n\n" end end TUM.radio.playForAll("pilotWingmanReportStatus", { TUM.wingmen.getFirstWingmanNumber(), statusMsg }, TUM.wingmen.getFirstWingmanCallsign(), delayRadioAnswer) return true end ---------------------------------------------------------- -- Called on every mission update tick (every 10-20 seconds) ---------------------------------------------------------- function TUM.wingmenTasking.onClockTick() local wingmenCtrl = TUM.wingmen:getController() if not wingmenCtrl then return end -- Wingmen are invincible 1/3 of the time to compensate for DCS's "special" AI, while still not making them completely indestructible wingmenTick = wingmenTick + 1 wingmenCtrl:setCommand({ id = 'SetImmortal', params = { value = (wingmenTick % 3 == 0) } }) -- No tasking? Rejoin leader if not wingmenCtrl:hasTask() then TUM.wingmenTasking.commandRejoin(nil, false, false, true) return end if not currentTargetIDorPoint then return end -- Targeted object is dead? Rejoin leader if currentTargetType == "group" then local tgtGroup = DCSEx.world.getGroupByID(currentTargetIDorPoint) if not tgtGroup or tgtGroup:getSize() == 0 then TUM.wingmenTasking.commandRejoin(nil, false, false, true) end elseif currentTargetType == "static" then local tgtStatic = DCSEx.world.getStaticObjectByID(currentTargetIDorPoint) if not tgtStatic then TUM.wingmenTasking.commandRejoin(nil, false, false, true) end elseif currentTargetType == "scenery" then local sceneriesInZone = DCSEx.world.getSceneriesInZone(currentTargetIDorPoint, 5) if not sceneriesInZone or #sceneriesInZone == 0 or sceneriesInZone[1]:getLife() < 1 then TUM.wingmenTasking.commandRejoin(nil, false, false, true) end end end function TUM.wingmenTasking.resetTaskingParameters() cruiseAltitudeFraction = 1.0 end end -------------------- -- Module startup -- -------------------- function TUM.initialize() do -- load the administrative settings TUM.administrativeSettings.initializeSettings() local function startUpMission() TUM.hasStarted = false local coreSettings = { multiplayer = false } if not net or not net.dostring_in then TUM.log("Mission failed to execute. Please copy the provided \"autoexec.cfg\" file to the [Saved Games]\\DCS\\Config directory.\nThe file can be downloaded from github.com/akaAgar/the-universal-mission-for-dcs-world", TUM.logLevel.ERROR) return nil end if #DCSEx.envMission.getPlayerGroups() == 0 then TUM.log("No \"Player\" or \"Client\" aircraft slots have been found. Please fix this problem in the mission editor.", TUM.logLevel.ERROR) return nil end if world:getPlayer() then coreSettings.multiplayer = false if #DCSEx.envMission.getPlayerGroups() > 1 then TUM.log("Multiple players slots have been found in addition to the single-player \"Player\" aircraft. Please fix this problem in the mission editor.", TUM.logLevel.ERROR) return nil end else coreSettings.multiplayer = true if #DCSEx.envMission.getPlayerGroups(coalition.side.BLUE) == 0 and #DCSEx.envMission.getPlayerGroups(coalition.side.RED) == 0 then TUM.log("Neither BLUE nor RED coalitions have player slots. Please make sure one coalition has player slots in the mission editor.", TUM.logLevel.ERROR) return nil end --[[ VEAF SPECIFIC ]] --if #DCSEx.envMission.getPlayerGroups(coalition.side.BLUE) > 0 and #DCSEx.envMission.getPlayerGroups(coalition.side.RED) > 0 then -- TUM.log("Both coalitions have player slots. The Universal Mission is a purely singleplayer/PvE experience and does not support PvP. Please make sure only one coalition has player slots in the mission editor.", TUM.logLevel.ERROR) -- return nil --end end if not TUM.territories.onStartUp() then return nil end if not TUM.settings.onStartUp(coreSettings) then return nil end -- Must be called after TUM.territories.onStartUp() if not TUM.playerCareer.onStartUp() then return nil end if not TUM.intermission.onStartUp() then return nil end if not TUM.airForce.onStartUp() then return nil end if not TUM.mizCleaner.onStartUp() then return nil end -- Must be called after TUM.settings.onStartUp() TUM.hasStarted = true return coreSettings end if not startUpMission() then trigger.action.outText("A critical error has happened, cannot start the mission.", 3600) end end ------------------- -- Event handler -- ------------------- do local eventHandler = {} function eventHandler:onEvent(event) if not event then return end -- No event TUM.ambientRadio.onEvent(event) -- Must be first so other (more important) radio messages will interrupt the "ambient" ones TUM.ambientWorld.onEvent(event) TUM.objectives.onEvent(event) TUM.playerScore.onEvent(event) TUM.mission.onEvent(event) TUM.wingmen.onEvent(event) TUM.mizCleaner.onEvent(event) -- Must be last, can remove units which could cause bugs in other onEvent methods end function TUM.onEvent(event) eventHandler:onEvent(event) end if TUM.hasStarted then world.addEventHandler(eventHandler) end end -------------------------------------------- -- Game clock, called every 10-20 seconds -- -------------------------------------------- do local clockTick = -1 function TUM.onClockTick(arg, time) local nextTickTime = time + math.random(10, 20) clockTick = clockTick + 1 TUM.wingmenTasking.onClockTick() -- No need to check the function return, it's just here to check if wingmen target is still alive if clockTick % 4 == 0 then if TUM.playerScore.onClockTick() then return nextTickTime end if TUM.mission.onClockTick() then return nextTickTime end elseif clockTick % 4 == 1 then if TUM.airForce.onClockTick(TUM.settings.getPlayerCoalition()) then return nextTickTime end elseif clockTick % 4 == 2 then if TUM.supportAWACS.onClockTick() then return nextTickTime end else if TUM.airForce.onClockTick(TUM.settings.getEnemyCoalition()) then return nextTickTime end end if TUM.wingmenContacts.onClockTick() then return nextTickTime end -- Called every tick if no other action has taken place return nextTickTime end if TUM.hasStarted then timer.scheduleFunction(TUM.onClockTick, nil, timer.getTime() + math.random(10, 15)) end end end if TUM.administrativeSettings.getValue(TUM.administrativeSettings.INITIALIZE_AUTOMATICALLY) then TUM.initialize() else TUM.log("TUM has been loaded, but not initialized. Call TUM.initialize() to start the mission.", TUM.logLevel.INFO) end