----------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------- -- Title: Dynamic Carrier Script -- Orig. Author: Turbine "Turbs" -- Version: 3.2 -- Initial Date: 2024-06-22 -- Description: This is a dynamic carrier script. It will search for all active naval groups within the mission editor. For any -- that it finds that have a carrier it will apply the TACG standards to it. it will also create the necessary tanker, -- rescue helo and awacs functios, as well as allow the boat to turn into the wind. -- To Use: Simply run this script after running moose. -- -- Changelog: Version | Date | Author | Description -- 1.0 | 2024-06-22 | Turbine | Initial Release -- 1.1 | 2024-07-22 | Turbine | Updated recovery tanker frequencies -- 2.0 | 2024-08-08 | Turbine | Revamped some of the script. Removed the bug where if the carrier was the only -- part of the group it'd get stuck in an infinite loop and crash DCS. -- 3.0 | 2024-09-09 | Turbine | Switched recovery tanker spawning to ONLY occur in the air. We've experienced -- it getting stuck on the deck. -- 3.1 | 2024-09-15 | Turbine | Revised script a little bit to provide better Debugging logging. -- 3.2 | 2024-11-23 | Turbine | Changed the lighting flags from number values to verbage -- 3.3 | 2024-12-01 | Turbine | Revised the calculations for displaying the into the wind functions. -- 3.4 | 2024-12-03 | Turbine | Revised the rescue helo type logic to add the ability to use a UH-60A and UH-60L. -- Also added the current hill ships as available landing zones for the rescue helo. -- ----------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------- -- Define Local Variables ----------------------------------------------------------------------------------------------------------------------------------- local DEBUGGING = false -- This will draw circles where the trigger zones should be located and turn on log messaging. local SRS_PATH = "C:\\Program Files\\DCS-SimpleRadio-Standalone\\" -- Set this as the path to your local SRS installation. local SERVER_NAME = "" -- Placeholder for storing name of server local SRS_PORT = 0000 -- Set the default port! If you have one server, this will be your port. local ACTIVE_CARRIER_GROUPS = {} -- DON'T TOUCH THIS! This is the table that will store the active carrier groups in the mission ----------------------------------------------------------------------------------------------------------------------------------- -- Debugging Functions, DO NOT TOUCH! ----------------------------------------------------------------------------------------------------------------------------------- --Print string debug local function DebugLogger(message) if DEBUGGING then env.info("DYNAMIC CARRIER SCRIPT: " .. message) trigger.action.outText("DYNAMIC CARRIER SCRIPT: " .. message, 20) end end --Add debugging information DebugLogger("DYNAMIC CARRIER SCRIPT Ver: 3.2") --Print Table debug function DebugTable(_table, _indentstring) if DEBUGGING then env.info(tostring(_table) .. " = {") _indentstring = _indentstring or "" for k, v in pairs(_table) do if type(v) == "table" then env.info(_indentstring .. tostring(k) .. " = {") DebugTable(v, _indentstring .. " ") env.info(_indentstring .. "},") else env.info(_indentstring .. tostring(k) .. " = " .. tostring(v) ..",") end end env.info("}") end end --Add debugging information DebugLogger("DEBUGGING SCRIPTS LOADED") ----------------------------------------------------------------------------------------------------------------------------------- -- Define Servers Information -- -- Template: -- { -- SERVER_NAME = "Name", -- SRS_PORT = "5002" -- } ----------------------------------------------------------------------------------------------------------------------------------- local SERVER_INFO = SERVER_MASTER_LIST --DebugTable(SERVER_INFO) DebugLogger("SEVER LIST LOADED") ----------------------------------------------------------------------------------------------------------------------------------- -- DEFINE CARRIER INFORMATION -- Note on carrier names carrierTypeName (its a little weird): Forrestal, CVN_71, CVN_72, CVN_73, Stennis, CVN_75, LHA_Tarawa ----------------------------------------------------------------------------------------------------------------------------------- local CARRIER_MASTER_LIST = { ["CVN_72"] = { displayName = "CVN-72 ABRAHAM LINCOLN", callsign = "UNION", typeName = "CVN_72", lightingFlag = "CVN72Lighting", aiFrequency = 128.6, liveFrequency = 306.1, tacan = 72, tacanID = "ABE", ICLS = 10, link4 = 306.2, windOffset = 0, recoveryTankerTypeName = "A6E", recoveryTankerCallsign = {5,1}, recoveryTankerTakeoff = "cold", recoveryTankerAltitude = 10000, recoveryTankerSpeed = 309, recoveryTankerRadio = 255.1, recoveryTankerModulation = "AM", recoveryTankerModex = 700, recoveryTankerTacan = 71, recoveryTankerTacanID = "ML1", recoveryTankerFuel = "unlimited", awacsTypeName = "E-2C", awacsCallsign = {"Wizard",1}, awacsTakeoff = "air", awacsAltitude = 25000, awacsSpeed = 356, awacsRadio = 265, awacsModulation = "AM", awacsFuel = "unlimited", rescueHeloTypeName = {"MH-60R","UH-60A"}, rescueHeloPortTypes = {"USS_Arleigh_Burke_IIa", "PERRY", "TICONDEROG", "Ship_Tilde_Supply", "CH_Ticonderoga_CMP", "CH_Arleigh_Burke_IIA", "CH_Arleigh_Burke_III", "CH_Constellation", "CH_Ticonderoga"}, rescueHeloModex = 600, rescueTakeoff = "cold", rescueHeloAltitude = 91, rescueHeloOffsetX = 300, rescueHeloOffsetZ = 400, rescueHeloRescueZone = 10, rescueHeloDuration = 5, }, ["LHA_Tarawa"] = { displayName = "LHA-1 TARAWA", callsign = "PROUD EAGLE", typeName = "LHA_Tarawa", lightingFlag = "LHA1Lighting", aiFrequency = 129.6, liveFrequency = 307.1, tacan = 1, tacanID = "TAR", ICLS = 11, link4 = nil, windOffset = 0, recoveryTankerTypeName = "S-3B Tanker", recoveryTankerCallsign = {5,2}, recoveryTankerTakeoff = "air", recoveryTankerAltitude = 10000, recoveryTankerSpeed = 309, recoveryTankerRadio = 255.2, recoveryTankerModulation = "AM", recoveryTankerModex = 701, recoveryTankerTacan = 72, recoveryTankerTacanID = "ML2", recoveryTankerFuel = "unlimited", awacsTypeName = "E-2C", awacsCallsign = {"Wizard",2}, awacsTakeoff = "air", awacsAltitude = 25000, awacsSpeed = 356, awacsRadio = 265.1, awacsModulation = "AM", awacsFuel = "unlimited", rescueHeloTypeName = {"MH-60R","UH-60A"}, rescueHeloPortTypes = {"USS_Arleigh_Burke_IIa", "PERRY", "TICONDEROG", "Ship_Tilde_Supply", "CH_Ticonderoga_CMP", "CH_Arleigh_Burke_IIA", "CH_Arleigh_Burke_III", "CH_Constellation", "CH_Ticonderoga"}, rescueHeloModex = 601, rescueTakeoff = "cold", rescueHeloAltitude = 91, rescueHeloOffsetX = 300, rescueHeloOffsetZ = 400, rescueHeloRescueZone = 10, rescueHeloDuration = 5, }, } DebugLogger("MASTER CARRIER LIST LOADED") ----------------------------------------------------------------------------------------------------------------------------------- -- DEFINE TANKER ALTITUDE VS SPPED TABLE ----------------------------------------------------------------------------------------------------------------------------------- local TANKER_SPEED_TABLE = { ["BOOM"] = {321, 327, 331, 337, 341, 346, 350, 356, 362, 370, 376, 379, 387, 393, 399, 407, 411, 418, 424, 432, 442, 448, 455, 465, 473, 481, 490, 545, 545, 545}, ["MPRS"] = {280, 284, 290, 294, 298, 302, 306, 309, 315, 319, 325, 330, 335, 342, 346, 354, 358, 366, 370, 378, 385, 389, 399, 405, 411, 416, 424, 436, 444, 450}, ["KC130"] = {336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336}, } DebugLogger("TANKER SPEED TABLE LOADED") ----------------------------------------------------------------------------------------------------------------------------------- -- Find Server Name and Set Port According to Server List. If not in list default to 5002. ----------------------------------------------------------------------------------------------------------------------------------- --Loop through each server instance. If it matches running server set port accordingly for i, v in ipairs(SERVER_INFO) do if v.SERVER_NAME == BASE.ServerName then -- Set Name and Port SERVER_NAME = v.SERVER_NAME SRS_PORT = v.SRS_PORT end end --Check if port was not set, If true apply default of 5002 if SRS_PORT == 0000 then SRS_PORT = 5002 DebugLogger("!!!! ERROR !!!! COULD NOT FIND SERVER NAME, SETTING PORT TO : " .. SRS_PORT) else DebugLogger("SERVER [" .. SERVER_NAME .. "] FOUND. SETTING PORT TO: " .. SRS_PORT) end DebugLogger("SRS SERVER SCRIPT LOADED") ----------------------------------------------------------------------------------------------------------------------------------- --Register all carrier groups --Grab all naval groups, find which ones have carriers in them, and add them to the active carrier groups list ----------------------------------------------------------------------------------------------------------------------------------- local navyGroupCount = 0 local navalGroups = SET_GROUP:New():FilterCategoryShip():FilterOnce() -- This will grab every group that exists within the ME that is a ship, and will only filteronce. navalGroups:ForEachGroup( function(Group) local unitTable = Group:GetDCSUnits() -- This will return a table of units within the group for _, v in pairs(unitTable) do -- We will now check whether any units within the group is a carrier local mooseUnitObject = UNIT:Find(v) local unitType = mooseUnitObject:GetTypeName() -- This grabs each unit's type to be able to check whether it is a carrier local unitName = mooseUnitObject:GetName() --Grab the unit's name DebugLogger(unitType) --Loop through each carrier in the master list for _, carrier in pairs(CARRIER_MASTER_LIST) do --Check if unit type found is a carrier type. If true then create the next active group. if carrier.typeName == unitType then --Apply the carrier group object to the ACTIVE_CARRIER_GROUPS table, with the carrierTypeName as the index ACTIVE_CARRIER_GROUPS[carrier.typeName] = { NavyGroupObj = NAVYGROUP:New(Group), --Create the carrier group object carrierUnitObj = mooseUnitObject, --Create the carrier unit object carrierUnitName = unitName, --Set the carrier unit name carrierDisplayName = carrier.displayName, --Set the display name carrierTypeName = carrier.typeName, --Set the type name carrierCallsign = carrier.callsign, --Set the callsign carrierAIFrequency = carrier.aiFrequency, --Set the ai frequency carrierLiveFrequency = carrier.liveFrequency, --Set the live frequency carrierTacan = carrier.tacan, --Set the tacan carrierTacanID = carrier.tacanID, --Set the tacan ID carrierICLS = carrier.ICLS, --Set the ICLS carrierLink4 = carrier.link4, --Set the link4 carrierWindOffset = carrier.windOffset, --Set the wind offset carrierLightingUserFlag = USERFLAG:New(carrier.lightingFlag), --Set Lighting flag carrierZoneUnit = ZONE_UNIT:New(unitType, mooseUnitObject, 1000), --Create zone around unit rescueHeloPortTypes = carrier.rescueHeloPortTypes --Create the list for the acceptable rescueHelo ports } --Increment and add debug information navyGroupCount = navyGroupCount + 1 DebugLogger(carrier.typeName .. " FOUND AND REGISTERED!") --If Debugging, output drawzones to F10 Map. if DEBUGGING then ACTIVE_CARRIER_GROUPS[carrier.typeName].carrierZoneUnit:DrawZone(-1, {0,0,1}, 1, {0,0,1}, 0.15, 1, true) end break end end end end ) --Add debug information if navyGroupCount == 0 then DebugLogger("WARNING - THERE ARE NO CARRIERS WITHIN THIS MISSION!") elseif navyGroupCount > 0 then DebugLogger(navyGroupCount .. " CARRIER(S) FOUND!") end ----------------------------------------------------------------------------------------------------------------------------------- --Grab all the aircraft groups, find which ones are based on the recovery tanker type listed in the master list, and add them to the active carrier groups list ----------------------------------------------------------------------------------------------------------------------------------- local recoveryTankerGroupCount = 0 local tankerGroups = SET_GROUP:New():FilterCategoryAirplane():FilterOnce() tankerGroups:ForEachGroup( function(Group) local unitTable = Group:GetDCSUnits() -- This will return a table of units within the group --Iterate through each Unit for _, v in pairs(unitTable) do local mooseUnitObject = UNIT:Find(v) --Find the unit local unitType = mooseUnitObject:GetTypeName() -- Grab the units Type Name local unitName = mooseUnitObject:GetName() --Grab the unit's name --Iterate through each active carrier for _, carrier in pairs(ACTIVE_CARRIER_GROUPS) do --Check to see if unit type is a rescue helo within the active carrier groups list if CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerTypeName == unitType then --Check to see if unit is within zone of the carrier assigned if carrier.carrierZoneUnit:IsVec2InZone(mooseUnitObject:GetVec2()) then --Check to see if unit is intended to be a recovery tanker for the tanker script if string.find(string.upper(unitName),"RECOVERY") then --Add the recovery tanker to the ACTIVE_CARRIER_GROUPS table carrier.recoveryTankerObj = RECOVERYTANKER:New(carrier.carrierUnitObj, Group:GetName()) --Create the recovery tanker object carrier.recoveryTankerName = unitName --Create the recovery tanker unit name carrier.recoveryTankerModex = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerModex --Set the recovery tanker Modex carrier.recoveryTankerCallsign = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerCallsign --Set the recovery tanker callsign carrier.recoveryTankerRadio = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerRadio --Set the recovery tanker radio frequency carrier.recoveryTankerModulation = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerModulation --Set the recovery tanker radio modulation carrier.recoveryTankerTacan = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerTacan --Set the recovery tanker tacan channel carrier.recoveryTankerTacanID = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerTacanID --Set the recovery tanker tacan ID carrier.recoveryTankerInitialAlt = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerAltitude --Set the recovery tanker initial altitude carrier.recoveryTankerInitialSpeed = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerSpeed --Set the recovery tanker initial speed carrier.recoveryTankerCurrentAlt = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerAltitude --Set the recovery tanker current altitude carrier.recoveryTankerCurrentSpeed = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerSpeed --Set the recovery tanker current speed --Increment and add debug information recoveryTankerGroupCount = recoveryTankerGroupCount + 1 DebugLogger("UNIT: " .. unitName .. " FOUND AND REGISTERED AS PART OF CARRIER " .. carrier.carrierTypeName) end end end end end end ) --Add debug information if recoveryTankerGroupCount == 0 then DebugLogger("WARNING - THERE ARE NO RECOVERY TANKERS WITHIN THIS MISSION!") elseif recoveryTankerGroupCount > 0 then DebugLogger(recoveryTankerGroupCount .. " RECOVERY TANKER(S) FOUND!") end ------------------------------------------------------------------------------------------------------------------------------------- ----Grab all the aircraft groups, find which ones are based on the AWACS type listed in the master list, and add them to the active carrier groups list ------------------------------------------------------------------------------------------------------------------------------------- local awacsGroupCount = 0 local awacsGroups = SET_GROUP:New():FilterCategoryAirplane():FilterOnce() tankerGroups:ForEachGroup( function(Group) local unitTable = Group:GetDCSUnits() -- This will return a table of units within the group --Iterate through each Unit for _, v in pairs(unitTable) do local mooseUnitObject = UNIT:Find(v) --Find the unit local unitType = mooseUnitObject:GetTypeName() -- Grab the units Type Name local unitName = mooseUnitObject:GetName() --Grab the unit's name --Iterate through each active carrier for _, carrier in pairs(ACTIVE_CARRIER_GROUPS) do --Check to see if unit type is a rescue helo within the active carrier groups list if CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsTypeName == unitType then --Check to see if unit is within zone of the carrier assigned if carrier.carrierZoneUnit:IsVec2InZone(mooseUnitObject:GetVec2()) then --Check to see if unit is intended to be a recovery tanker for the tanker script if string.find(string.upper(unitName),"AWACS") then --Add the recovery tanker to the ACTIVE_CARRIER_GROUPS table carrier.awacsObj = RECOVERYTANKER:New(carrier.carrierUnitObj, Group:GetName()) --Create the AWACS object carrier.awacsUnitObj = UNIT:FindByName(carrier.awacsName) --Create the AWACS unit object carrier.awacsName = unitName --Create the AWACS unit name --carrier.awacsModex = CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerModex --Set the AWACS Modex carrier.awacsCallsign = CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsCallsign --Set the awacs callsign carrier.awacsRadio = CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsRadio --Set the awacs radio frequency carrier.awacsModulation = CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsModulation --Set the awacs radio modulation carrier.awacsAlt = CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsAltitude --Set the awacs initial altitudeS carrier.awacsSpeed = CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsSpeed --Set the awacs initial speed --Increment and add debug information awacsGroupCount = awacsGroupCount + 1 DebugLogger("UNIT: " .. unitName .. " FOUND AND REGISTERED AS PART OF CARRIER " .. carrier.carrierTypeName) end end end end end end ) --Add debug information if recoveryTankerGroupCount == 0 then DebugLogger("WARNING - THERE ARE NO AWACS WITHIN THIS MISSION!") elseif recoveryTankerGroupCount > 0 then DebugLogger(recoveryTankerGroupCount .. " AWACS FOUND!") end ------------------------------------------------------------------------------------------------------------------------------------- ----Grab all the helo groups, find which ones are based on the rescue helo type listed in the master list, and add them to the active carrier groups list ----Then find all the acceptable ships within the group and set the helo's home port to that ship. Will select randomly ------------------------------------------------------------------------------------------------------------------------------------- local rescueHeloGroupCount = 0 local rescueHeloGroups = SET_GROUP:New():FilterCategoryHelicopter():FilterOnce() --Iterate through each helicopter group to see if its within the zone of the carrier rescueHeloGroups:ForEachGroup( function(Group) local unitTable = Group:GetDCSUnits() -- This will return a table of units within the group --Iterate through each Unit for _, v in pairs(unitTable) do local mooseUnitObject = UNIT:Find(v) --Find the unit local unitType = mooseUnitObject:GetTypeName() -- Grab the units Type Name local unitName = mooseUnitObject:GetName() --Grab the unit's name --Iterate through each active carrier for _, carrier in pairs(ACTIVE_CARRIER_GROUPS) do --Iterate through each rescue helo type for _, helo in pairs(CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueHeloTypeName) do --Check to see if unit type is a rescue helo within the active carrier groups list if helo == unitType then --Check to see if unit is within zone of the carrier assigned if carrier.carrierZoneUnit:IsVec2InZone(mooseUnitObject:GetVec2()) then --Check to see if unit is intended to be a rescue helo for the tanker script if string.find(string.upper(unitName),"RESCUEHELO") then --Add the Rescue Helo object to the Active Carrier List carrier.rescueHeloObj = RESCUEHELO:New(carrier.carrierUnitObj, Group:GetName()) carrier.rescueHeloName = unitName --Increment and add debug information rescueHeloGroupCount = rescueHeloGroupCount + 1 DebugLogger("Unit: " .. unitName .. " found and registered as part of carrier " .. carrier.carrierUnitName) end end end end end end end ) --Iterate through each carrier group and define the alternate port for the helo to land apon for _, carrier in pairs(ACTIVE_CARRIER_GROUPS) do --Define variables local stopFlag = 0 --Flag to stop the while loop local unitTable = carrier.NavyGroupObj:GetDCSUnits() --Grab the unit list of the group --Loop till a random ship in the group is selected. while stopFlag == 0 do --Define variables local shipNum = math.random(1,#unitTable) --Define a random number between 1 and the maximum number of ships in the group. local mooseUnitObject = UNIT:Find(unitTable[shipNum]) --Find the unit local UnitType = mooseUnitObject:GetTypeName() -- Grab the units Type Name local UnitName = mooseUnitObject:GetName() --Grab the unit's name --Check to see if there is only the carrier in the group. if #unitTable ~= 1 then --Check to see if unit is not the carrier if carrier.carrierTypeName ~= UnitType then --loop through each acceptable ship type in the helo port types list to see if the ship is acceptable for use for i, v in ipairs(carrier.rescueHeloPortTypes) do --Check to see if unit type is within the acceptable list if v == UnitType then --Apply the home port to the ACTIVE_CARRIER_GROUPS list under home port carrier.rescueHeloHomePort = UnitName --Add debug information if carrier.rescueHeloObj then DebugLogger(carrier.rescueHeloHomePort .. " SET AS HOME PORT FOR " .. carrier.rescueHeloName) end --Set the stop flag to break the loop stopFlag = 1 end end end stopFlag = 1 --Else set the carrier as the home port and warn the user elseif #unitTable == 1 then --Apply the home port to the ACTIVE_CARRIER_GROUPS list under home port carrier.rescueHeloHomePort = UnitName --Warn the user DebugLogger("WARNING - YOUR CARRIER " .. UnitName .. " HAS NO SUPPORT SHIPS!") --Set the stop flag to break the loop stopFlag = 1 end end end --Add debug information if rescueHeloGroupCount == 0 then DebugLogger("WARNING - THERE ARE NO RESCUE HELOS WITHIN THIS MISSION!") elseif rescueHeloGroupCount > 0 then DebugLogger(rescueHeloGroupCount .. " RESCUE HELO(S) FOUND!") end ------------------------------------------------------------------------------------------------------------------------------------- ---- Setup Activate Beasons Functions ------------------------------------------------------------------------------------------------------------------------------------- local function Activate_Beacons(args) --Define variables local groupName = args --Create the ship beacons local shipID = ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:GetID() --Get the ship's ID local ship_Tacan = ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:GetBeacon() --Create the beacon for the ship --Activate the beacons ship_Tacan:ActivateTACAN(ACTIVE_CARRIER_GROUPS[groupName].carrierTacan, "X", ACTIVE_CARRIER_GROUPS[groupName].carrierTacanID, true) ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandSetFrequency(ACTIVE_CARRIER_GROUPS[groupName].carrierAIFrequency) ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandActivateICLS(ACTIVE_CARRIER_GROUPS[groupName].carrierICLS, shipID, ACTIVE_CARRIER_GROUPS[groupName].carrierTacanID):CommandActivateLink4(ACTIVE_CARRIER_GROUPS[groupName].carrierLink4) ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandActivateACLS(shipID, ACTIVE_CARRIER_GROUPS[groupName].carrierTacanID, nil) --Display message to blue coalition MESSAGE:New("99 " .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .." MARSHAL, ACTIVATING BEACONS!", 25):ToBlue() end local function Deactivate_Beacons(args) --Define variables local groupName = args --Deactivate the beacons ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateICLS() ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateBeacon() ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateLink4() ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateACLS() --Display message to blue coalition MESSAGE:New("99 " .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .." MARSHAL, DEACTIVATING BEACONS!", 25):ToBlue() end local function Cycle_Beacons(args) --Define variables local groupName = args --Create the ship beacons local shipID = ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:GetID() --Get the ship's ID local ship_Tacan = ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:GetBeacon() --Create the beacon for the ship --Deactivate the beacons ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateICLS() ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateBeacon() ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateLink4() ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandDeactivateACLS() --Activate the beacons ship_Tacan:ActivateTACAN(ACTIVE_CARRIER_GROUPS[groupName].carrierTacan, "X", ACTIVE_CARRIER_GROUPS[groupName].carrierTacanID, true) ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandSetFrequency(ACTIVE_CARRIER_GROUPS[groupName].carrierAIFrequency) ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandActivateICLS(ACTIVE_CARRIER_GROUPS[groupName].carrierICLS, shipID, ACTIVE_CARRIER_GROUPS[groupName].carrierTacanID):CommandActivateLink4(ACTIVE_CARRIER_GROUPS[groupName].carrierLink4) ACTIVE_CARRIER_GROUPS[groupName].carrierUnitObj:CommandActivateACLS(shipID, ACTIVE_CARRIER_GROUPS[groupName].carrierTacanID, nil) --Display message to blue coalition MESSAGE:New("99 " .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .." MARSHAL, CYCLING BEACONS!", 25):ToBlue() end ------------------------------------------------------------------------------------------------------------------------------------- ---- Setup Into the Wind Function ------------------------------------------------------------------------------------------------------------------------------------- local function WindTurn(args) --Define variables local groupName = args[1] local StartStop = args[2] local timeofturn = args[3] local lightingFlag = args[4] local timenow = timer.getAbsTime() local timeend = timenow+timeofturn*60 local timerecovery_start = UTILS.SecondsToClock(timenow,false) local timerecovery_end = UTILS.SecondsToClock(timeend,false) --Check if carrier ops are to start or stop if StartStop then --Set the lightingFlag ACTIVE_CARRIER_GROUPS[groupName].carrierLightingUserFlag:Set(lightingFlag) DebugLogger("LIGHTS SET TO: " .. ACTIVE_CARRIER_GROUPS[groupName].carrierLightingUserFlag:Get()) --Start Recovery Ops ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:AddTurnIntoWind(timerecovery_start,timerecovery_end,28,false,ACTIVE_CARRIER_GROUPS[groupName].carrierWindOffset) local newHeading = math.floor(ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:GetHeadingIntoWind_new(0,28)-UTILS.GetMagneticDeclination()-0.5) --Send radio transmission over SRS ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " Marshall, Turning to B R C " .. math.floor(newHeading/100) .. " " .. math.floor((newHeading - math.floor(newHeading/100)*100)/10).. " " .. math.floor(newHeading) - math.floor(newHeading/100)*100 - (math.floor((newHeading - math.floor(newHeading/100)*100)/10))*10 .. " at this time.", nil, false, ACTIVE_CARRIER_GROUPS[groupName].carrierLiveFrequency) ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " Marshall, Turning to B R C " .. math.floor(newHeading/100) .. " " .. math.floor((newHeading - math.floor(newHeading/100)*100)/10).. " " .. math.floor(newHeading) - math.floor(newHeading/100)*100 - (math.floor((newHeading - math.floor(newHeading/100)*100)/10))*10 .. " at this time.", nil, false, ACTIVE_CARRIER_GROUPS[groupName].carrierAIFrequency) --Display message to blue coalition MESSAGE:New("99 " .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " MARSHAL, TURNING TO BRC " .. tostring(newHeading) .. ", AT TIME " .. timerecovery_start .. " UNTIL " .. timerecovery_end, 25):ToBlue() else --Send radio transmission over SRS ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " Marshall, Departure Recovery Operations Complete, Returning to Original Course at this time." , nil, false, ACTIVE_CARRIER_GROUPS[groupName].carrierLiveFrequency) ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " Marshall, Departure Recovery Operations Complete, Returning to Original Course at this time." , nil, false, ACTIVE_CARRIER_GROUPS[groupName].carrierAIFrequency) --Display message to blue coalition MESSAGE:New("99 " .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " MARSHAL, DEPARTURE/RECOVERY OPERATIONS COMPLETE, RETURNING TO ORIGINAL COURSE, AT TIME " .. timerecovery_start, 25):ToBlue() --Stop Recovery Ops ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:TurnIntoWindStop() end end ------------------------------------------------------------------------------------------------------------------------------------- ---- Setup Recovery Tanker functions ------------------------------------------------------------------------------------------------------------------------------------- --Loop through each carrier group and apply settings for the recovery tanker for _, carrier in pairs(ACTIVE_CARRIER_GROUPS) do --If recovery tanker object exists if carrier.recoveryTankerObj then --Set the initial altitude carrier.recoveryTankerObj:SetAltitude(carrier.recoveryTankerInitialAlt) --Set the initial airspeed carrier.recoveryTankerObj:SetSpeed(UTILS.IasToTas(carrier.recoveryTankerInitialSpeed,carrier.recoveryTankerInitialAlt)) --Set the Radio frequency carrier.recoveryTankerObj:SetRadio(carrier.recoveryTankerRadio, carrier.recoveryTankerModulation) --Set the Modex carrier.recoveryTankerObj:SetModex(carrier.recoveryTankerModex) --Set the callsign carrier.recoveryTankerObj:SetCallsign(carrier.recoveryTankerCallsign[1],carrier.recoveryTankerCallsign[2]) --Set the TACAN carrier.recoveryTankerObj:SetTACAN(carrier.recoveryTankerTacan, carrier.recoveryTankerTacanID) --Set Unlimited Fuel if CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerFuel == "unlimited" then carrier.recoveryTankerObj:SetUnlimitedFuel(true) end --Set startup type carrier.recoveryTankerObj:SetTakeoffAir() --if CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerTakeoff == "cold" then -- carrier.recoveryTankerObj:SetTakeoffCold() --end --if CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerTakeoff == "hot" then -- carrier.recoveryTankerObj:SetTakeoffHot() --end --if CARRIER_MASTER_LIST[carrier.carrierTypeName].recoveryTankerTakeoff == "air" then -- carrier.recoveryTankerObj:SetTakeoffAir() --end end end local function Start_Tanker(args) --Define variables local groupName = args --Check to see if tanker object exists if ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj then --If true start the tanker ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:Start() end --Activate Link4 Datalink UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):CommandActivateLink4(336) --Display message to blue coalition MESSAGE:New("99 " .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " MARSHAL, DEPLOYING " .. string.upper(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign()) .. " FOR RECOVERY TANKER OPS, AT TIME " .. UTILS.SecondsToClock(timer.getAbsTime(),false) .. "!", 25):ToBlue() --Send SRS message ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " Marshall, DEPLOYING " .. string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign(),"-1","") .. " FOR RECOVERY TANKER OPS!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].carrierAIFrequency) ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " Marshall, DEPLOYING " .. string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign(),"-1","") .. " FOR RECOVERY TANKER OPS!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].carrierLiverFrequency) --Update the pattern ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:PatternUpdate() end local function RTB_Tanker(args) --Define variables local groupName = args if ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj then ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:RTB() end end local function Cancel_Tanker(args) --Define variables local groupName = args if ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj then ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:Stop() end end local function Tanker_Info(args) --Define variables local groupName = args --Set the output text local outputText = "====== TANKER " .. string.upper(string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign(),"-1","")) .. " STATUS ======" --Set the tanker type info outputText = outputText .. "\nA/C TYPE: S-3B" --Set the Frequency info outputText = outputText .. "\nFREQUENCY: " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerRadio .. " Mhz " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerModulation --Set the TACAN info outputText = outputText .. "\nTACAN: " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerTacan .. "Y (" .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerTacanID .. ")" --Set the Altitude info outputText = outputText .. "\nALTITUDE: " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt .. " ft ASL (BROKEN ATM)" --Set the Speed info outputText = outputText .. "\nSPEED: " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed .. " kn GS (BROKEN ATM)" --Display the message trigger.action.outText(outputText, 20) end local function Tanker_CycleBeacons(args) --Define variables local groupName = args --Turn the TACAN beacon off ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:SetTACANoff() --Turn the TACAN beacon on ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:SetTACAN(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerTacan, ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerTacanID) end local function Tanker_ChangeAltitude(args) --Define variables local groupName = args[1] local altitudeChange = args[2] --Check if group exists if ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj then --Set the new altitude ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt = ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt + altitudeChange --Apply the new altitude setting to the tanker ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:SetAltitude(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt) --Set the new speed ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed = TANKER_SPEED_TABLE["MPRS"][ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt/1000] --Apply the new speed setting to the tanker ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:SetSpeed(UTILS.IasToTas(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt,ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed)) --Send Message and SRS call based on whether the tanker is ascending or descending if altitudeChange > 0 then --Send Screen Message MESSAGE:New(string.upper(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign()) .. ", CLIMBING TO ANGELS " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt/1000 .. "!", 25):ToBlue() --Send SRS Message ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission(string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign(),"-1","") .. ", CLIMBING TO ANGELS " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt/1000 .. "!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerRadio) elseif altitudeChange < 0 then --Send Screen Message MESSAGE:New(string.upper(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign()) .. ", DESCENDING TO ANGELS " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt/1000 .. "!", 25):ToBlue() --Send SRS Message ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission(string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign(),"-1","") .. ", DESCENDING TO ANGELS " .. ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt/1000 .. "!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerRadio) end --Update the pattern ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:PatternUpdate() end end local function Tanker_ChangeSpeed(args) --Define variables local groupName = args[1] local speedChange = args[2] --ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed = ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed + speedChange --UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):SetSpeed(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed + speedChange) --Check if group exists if ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj then --Set the new speed ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed = ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed + speedChange --Update the new speed setting to the tanker ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:SetSpeed(UTILS.IasToTas(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentAlt,ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerCurrentSpeed)) --Send Message and SRS call based on whether the tanker is ascending or descending if speedChange > 0 then --Send Screen Message MESSAGE:New(string.upper(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign()) .. ", INCREASING " .. speedChange .. " KNOTS!", 25):ToBlue() --Send SRS Message ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission(string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign(),"-1","") .. ", INCREASING " .. speedChange .. " KNOTS!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerRadio) elseif speedChange < 0 then --Send Screen Message MESSAGE:New(string.upper(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign()) .. ", DECREASING " .. speedChange .. " KNOTS!", 25):ToBlue() --Send SRS Message ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission(string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerName):GetCallsign(),"-1","") .. ", DECREASING " .. speedChange .. " KNOTS!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerRadio) end --Update the pattern ACTIVE_CARRIER_GROUPS[groupName].recoveryTankerObj:PatternUpdate() end end ------------------------------------------------------------------------------------------------------------------------------------- ---- Setup AWACS Functions ------------------------------------------------------------------------------------------------------------------------------------- --Loop through each carrier group and apply settings for the awacs for _, carrier in pairs(ACTIVE_CARRIER_GROUPS) do --If awacs object exists if carrier.awacsObj then --Set the object as an AWACS carrier.awacsObj:SetAWACS() --Set the altitude carrier.awacsObj:SetAltitude(carrier.awacsAlt) --Set the airspeed carrier.awacsObj:SetSpeed(carrier.awacsSpeed) --Set the Radio frequency carrier.awacsObj:SetRadio(carrier.awacsRadio, carrier.awacsModulation) --Set the callsign if carrier.awacsCallsign[1] == "Wizard" then carrier.awacsObj:SetCallsign(CALLSIGN.AWACS.Wizard,carrier.awacsCallsign[2]) end --Set Unlimited Fuel if CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsFuel == "unlimited" then carrier.awacsObj:SetUnlimitedFuel(true) end --Set startup type if CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsTakeoff == "cold" then carrier.awacsObj:SetTakeoffCold() end if CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsTakeoff == "hot" then carrier.awacsObj:SetTakeoffHot() end if CARRIER_MASTER_LIST[carrier.carrierTypeName].awacsTakeoff == "air" then carrier.awacsObj:SetTakeoffAir() end end end local function Start_AWACS(args) --Define variables local groupName = args --Check to see if tanker object exists if ACTIVE_CARRIER_GROUPS[groupName].awacsObj then --If true start the tanker ACTIVE_CARRIER_GROUPS[groupName].awacsObj:Start() end --Activate Link4 Datalink UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].awacsName):CommandActivateLink4(336) --Display message to blue coalition MESSAGE:New("99 " .. ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign .. " MARSHAL, DEPLOYING " .. string.upper(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].awacsName):GetCallsign()) .. ", AT TIME " .. UTILS.SecondsToClock(timer.getAbsTime(),false) .. "!", 25):ToBlue() --Send SRS message ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. string.upper(ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign) .. " MARSHALL, DEPLOYING " .. string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].awacsName):GetCallsign(),"-1","") .. "!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].carrierAIFrequency) ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("Ninety Nine" .. string.upper(ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign) .. " MARSHALL, DEPLOYING " .. string.gsub(UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].awacsName):GetCallsign(),"-1","") .. "!",nil,false,ACTIVE_CARRIER_GROUPS[groupName].carrierLiverFrequency) end local function RTB_AWACS(args) --Define variables local groupName = args if ACTIVE_CARRIER_GROUPS[groupName].awacsObj then ACTIVE_CARRIER_GROUPS[groupName].awacsObj:RTB() end end local function Cancel_AWACS(args) --Define variables local groupName = args if ACTIVE_CARRIER_GROUPS[groupName].awacsObj then ACTIVE_CARRIER_GROUPS[groupName].awacsObj:Stop() end end ------------------------------------------------------------------------------------------------------------------------------------- ---- Setup Rescue Helo Functions and start the helo ------------------------------------------------------------------------------------------------------------------------------------- for _, carrier in pairs(ACTIVE_CARRIER_GROUPS) do if carrier.rescueHeloObj then --Set the Modex carrier.rescueHeloObj:SetModex(CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueHeloModex) --Set the altitude carrier.rescueHeloObj:SetAltitude(CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueHeloAltitude) --Set the Offsets carrier.rescueHeloObj:SetOffsetX(CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueHeloOffsetX) carrier.rescueHeloObj:SetOffsetZ(CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueHeloOffsetZ) --Set the Home Port if carrier.rescueHeloHomePort then carrier.rescueHeloObj:SetHomeBase(AIRBASE:FindByName(carrier.rescueHeloHomePort)) end --Set the Zone Radius carrier.rescueHeloObj:SetRescueZone(CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueHeloRescueZone) --Set whether to cold, hot or air start the rescue helo if CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueTakeoff == "cold" then carrier.rescueHeloObj:SetTakeoffCold() end if CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueTakeoff == "hot" then carrier.rescueHeloObj:SetTakeoffHot() end if CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueTakeoff == "air" then carrier.rescueHeloObj:SetTakeoffAir() end --Set the rescue duration carrier.rescueHeloObj:SetRescueDuration(CARRIER_MASTER_LIST[carrier.carrierTypeName].rescueHeloDuration) end end function Start_Helo(args) --Define variables local groupName = args --Stop the rescue helo ACTIVE_CARRIER_GROUPS[groupName].rescueHeloObj:Start() --Activate Link4 Datalink UNIT:FindByName(ACTIVE_CARRIER_GROUPS[groupName].rescueHeloName):CommandActivateLink4(336) --Display message to blue coalition MESSAGE:New("99 " .. string.upper(ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign) .. " MARSHAL, DEPLOYING RESCUE HELO, AT TIME " .. UTILS.SecondsToClock(timer.getAbsTime(),false), 25):ToBlue() --Send SRS message ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("NINETY NINE" .. string.upper(ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign) .. " MARSHALL, DEPLOYING RESCUE HEELO",nil,false,CARRIER_MASTER_LIST[groupName].aiFrequency) ACTIVE_CARRIER_GROUPS[groupName].NavyGroupObj:RadioTransmission("NINETY NINE" .. string.upper(ACTIVE_CARRIER_GROUPS[groupName].carrierCallsign) .. " MARSHALL, DEPLOYING RESCUE HEELO",nil,false,CARRIER_MASTER_LIST[groupName].liveFrequency) end function RTB_Helo(args) --Define variables local groupName = args --Stop the rescue helo ACTIVE_CARRIER_GROUPS[groupName].rescueHeloObj:RTB() end function Cancel_Helo(args) --Define variables local groupName = args --Stop the rescue helo ACTIVE_CARRIER_GROUPS[groupName].rescueHeloObj:Stop() end ------------------------------------------------------------------------------------------------------------------------------------- ---- Setup Menu System ------------------------------------------------------------------------------------------------------------------------------------- --Define variables local CarrierMenu = MENU_COALITION:New(coalition.side.BLUE, "CARRIER MENUS" ) --Loop through each ACTIVE_CARRIER_GROUPS for _,v in pairs(ACTIVE_CARRIER_GROUPS) do --Check if carrier object exists if v.NavyGroupObj then --Load Carrier Sub Commands CarrierSubMenu = MENU_COALITION:New(coalition.side.BLUE, v.carrierDisplayName, CarrierMenu) --Load Beacon Commands CarrierBeaconsSubMenu = MENU_COALITION:New(coalition.side.BLUE, "CARRIER BEACONS", CarrierSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE, "ACTIVATE BEACONS", CarrierBeaconsSubMenu, Activate_Beacons, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE, "DEACTIVATE BEACONS", CarrierBeaconsSubMenu, Deactivate_Beacons, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE, "CYCLE BEACONS", CarrierBeaconsSubMenu, Cycle_Beacons, v.carrierTypeName) --Load Into the Wind Commands CarrierOpsSubMenu = MENU_COALITION:New(coalition.side.BLUE, "DEPARTURE/RECOVERY OPS", CarrierSubMenu) CarrierOpsSubMenu1 = MENU_COALITION:New(coalition.side.BLUE, "START CASE I OPS" , CarrierOpsSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 15 MINUTES", CarrierOpsSubMenu1, WindTurn, {v.carrierTypeName, true, 15, 2}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 30 MINUTES", CarrierOpsSubMenu1, WindTurn, {v.carrierTypeName, true, 30, 2}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 60 MINUTES", CarrierOpsSubMenu1, WindTurn, {v.carrierTypeName, true, 60, 2}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 90 MINUTES", CarrierOpsSubMenu1, WindTurn, {v.carrierTypeName, true, 90, 2}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 2 HOURS", CarrierOpsSubMenu1, WindTurn, {v.carrierTypeName, true, 120, 2}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 4 HOURS", CarrierOpsSubMenu1, WindTurn, {v.carrierTypeName, true, 240, 2}) CarrierOpsSubMenu2 = MENU_COALITION:New(coalition.side.BLUE, "START CASE III DEPARTURE OPS" , CarrierOpsSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 15 MINUTES", CarrierOpsSubMenu2, WindTurn, {v.carrierTypeName, true, 15, 4}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 30 MINUTES", CarrierOpsSubMenu2, WindTurn, {v.carrierTypeName, true, 30, 4}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 60 MINUTES", CarrierOpsSubMenu2, WindTurn, {v.carrierTypeName, true, 60, 4}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 90 MINUTES", CarrierOpsSubMenu2, WindTurn, {v.carrierTypeName, true, 90, 4}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 2 HOURS", CarrierOpsSubMenu2, WindTurn, {v.carrierTypeName, true, 120, 4}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 4 HOURS", CarrierOpsSubMenu2, WindTurn, {v.carrierTypeName, true, 240, 4}) CarrierOpsSubMenu3 = MENU_COALITION:New(coalition.side.BLUE, "START CASE III RECOVERY OPS" , CarrierOpsSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 15 MINUTES", CarrierOpsSubMenu3, WindTurn, {v.carrierTypeName, true, 15, 5}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 30 MINUTES", CarrierOpsSubMenu3, WindTurn, {v.carrierTypeName, true, 30, 5}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 60 MINUTES", CarrierOpsSubMenu3, WindTurn, {v.carrierTypeName, true, 60, 5}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 90 MINUTES", CarrierOpsSubMenu3, WindTurn, {v.carrierTypeName, true, 90, 5}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 2 HOURS", CarrierOpsSubMenu3, WindTurn, {v.carrierTypeName, true, 120, 5}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TURN INTO WIND FOR 4 HOURS", CarrierOpsSubMenu3, WindTurn, {v.carrierTypeName, true, 240, 5}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"CANCEL CASE I/III OPS", CarrierOpsSubMenu, WindTurn, {v.carrierTypeName, false, 30, 2}) --Check if each recovery tanker exists if v.recoveryTankerObj then --Load Recovery Tanker Sub Commands CarrierTankerSubMenu = MENU_COALITION:New(coalition.side.BLUE, "RECOVERY TANKER OPS", CarrierSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"LAUNCH TANKER", CarrierTankerSubMenu, Start_Tanker, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"TANKER STATUS", CarrierTankerSubMenu, Tanker_Info, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"CYCLE BEACONS", CarrierTankerSubMenu, Tanker_CycleBeacons, v.carrierTypeName) CarrierTankerSubMenu1 = MENU_COALITION:New(coalition.side.BLUE, "CHANGE ALTITUDE" , CarrierTankerSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"CLIMB 1000 ft", CarrierTankerSubMenu1, Tanker_ChangeAltitude, {v.carrierTypeName,1000}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"CLIMB 2000 ft", CarrierTankerSubMenu1, Tanker_ChangeAltitude, {v.carrierTypeName,2000}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"CLIMB 3000 ft", CarrierTankerSubMenu1, Tanker_ChangeAltitude, {v.carrierTypeName,3000}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"DESCEND 1000 ft", CarrierTankerSubMenu1, Tanker_ChangeAltitude, {v.carrierTypeName,-1000}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"DESCEND 2000 ft", CarrierTankerSubMenu1, Tanker_ChangeAltitude, {v.carrierTypeName,-2000}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"DESCEND 3000 ft", CarrierTankerSubMenu1, Tanker_ChangeAltitude, {v.carrierTypeName,-3000}) CarrierTankerSubMenu1 = MENU_COALITION:New(coalition.side.BLUE, "CHANGE SPEED" , CarrierTankerSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"INCREASE 10 kts", CarrierTankerSubMenu1, Tanker_ChangeSpeed, {v.carrierTypeName,10}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"INCREASE 20 kts", CarrierTankerSubMenu1, Tanker_ChangeSpeed, {v.carrierTypeName,20}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"INCREASE 30 kts", CarrierTankerSubMenu1, Tanker_ChangeSpeed, {v.carrierTypeName,30}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"DECREASE 10 kts", CarrierTankerSubMenu1, Tanker_ChangeSpeed, {v.carrierTypeName,-10}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"DECREASE 20 kts", CarrierTankerSubMenu1, Tanker_ChangeSpeed, {v.carrierTypeName,-20}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"DECREASE 30 kts", CarrierTankerSubMenu1, Tanker_ChangeSpeed, {v.carrierTypeName,-30}) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"RTB TANKER", CarrierTankerSubMenu, RTB_Tanker, carrierGroupName) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"KILL TANKER", CarrierTankerSubMenu, Cancel_Tanker, carrierGroupName) end --Check if each AWACS exists if v.awacsObj then --Load AWACS Sub Commands CarrierAwacsSubMenu = MENU_COALITION:New(coalition.side.BLUE, "AWACS OPS", CarrierSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"LAUNCH AWACS", CarrierAwacsSubMenu, Start_AWACS, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"RTB AWACS", CarrierAwacsSubMenu, RTB_AWACS, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"KILL AWACS", CarrierAwacsSubMenu, Cancel_AWACS, v.carrierTypeName) end --Check if each Rescue Helo exists if v.rescueHeloObj then --Load AWACS Sub Commands CarrierRescueHeloSubMenu = MENU_COALITION:New(coalition.side.BLUE, "RESCUE HELO OPS", CarrierSubMenu) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"LAUNCH RESCUE HELO", CarrierRescueHeloSubMenu, Start_Helo, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"RTB RESCUE HELO", CarrierRescueHeloSubMenu, RTB_Helo, v.carrierTypeName) MENU_COALITION_COMMAND:New(coalition.side.BLUE,"KILL RESCUE HELO", CarrierRescueHeloSubMenu, Cancel_Helo, v.carrierTypeName) end end end ----------------------------------------------------------------------------------------------------------------------------------- -- Launch the beacons, rescue helo, and SRS path on initialization ----------------------------------------------------------------------------------------------------------------------------------- for _,v in pairs(ACTIVE_CARRIER_GROUPS) do --Setup the SRS Path v.NavyGroupObj:SetSRS(SRS_PATH, (math.random(1, 2) == 1) and "male" or "female", "en-US", nil, SRS_PORT) --Start the beacons Activate_Beacons(v.carrierTypeName) --Launch the Recovery Tanker --if v.awacsObj then -- Start_Tanker(v.carrierTypeName) --end --Launch the AWACS if v.awacsObj then Start_AWACS(v.carrierTypeName) end --Launch the Helo if v.rescueHeloObj then Start_Helo(v.carrierTypeName) end end ------------------------------------------------------------------------------------------------------------------------------------- ---- Update logs that script loaded successfully ------------------------------------------------------------------------------------------------------------------------------------- DebugLogger("SCRIPT HAS SUCCESSFULLY LOADED!") env.info("DYNAMIC CARRIER SCRIPT: SCRIPT HAS SUCCESSFULLY LOADED!")