This mod simulates the flight patterns of Southern California (more specifically, Los Angeles area) law enforcement air support helicopters. That is, they will orbit around a target entity or position instead of just hovering above. A spotlight will track the subject when night-time. You may also call for a backup heli anytime while on-duty.
A Must-Have For Realistic Gameplay!
Make sure to put HeliAssistance.dll and HeliAssistance.ini and HeliAssistance.pdb into \Plugins\LSPDFR folder.
Make sure you have the latest RageNativeUI installed. And make sure you have Spotlight installed.
API for Developers (for usage with v2.4.2)
namespace HeliAssistanceAPI { using LSPD_First_Response.Mod.API; using Rage; using Functions = HeliAssistance.API.Functions; internal static class HeliAssistanceWrapper { private const string DllPath = @"Plugins\LSPDFR\HeliAssistance.dll"; private static readonly bool DllExists = System.IO.File.Exists(DllPath); /// <summary> /// One more wrapper to prevent <see cref="CanBeUsed"/> from trying to load the HeliAssistance assembly. /// </summary> private static class IsLoadedWrapper { public static bool IsLoaded => Functions.IsLoaded; } /// <summary> /// Checks if the plugin is loaded within LSPDFR (i.e. LSPDFR is loaded and the player is on duty). /// </summary> public static bool CanBeUsed => DllExists ? IsLoadedWrapper.IsLoaded : false; /// <summary> /// Determines whether the menu can be toggled by the player. If set to false, the menu will be closed if it is visible. /// </summary> public static bool CanPlayerUseMenu { get => Functions.CanPlayerUseMenu; set => Functions.CanPlayerUseMenu = value; } /// <summary> /// Requests the air unit to be created and respond to the <see cref="Entity"/> target. If the air unit is already active and/or alive, then it will merely have the air unit respond to the target. /// </summary> public static void RequestAirUnit(Entity target) => Functions.RequestAirUnit(target); /// <summary> /// Requests the air unit to be created and respond to the <see cref="Vector3"/> target. If the air unit is already active and/or alive, then it will merely have the air unit respond to the target. /// </summary> public static void RequestAirUnit(Vector3 target) => Functions.RequestAirUnit(target); /// <summary> /// Dismisses the air unit from any active player-requested task. /// </summary> public static void DismissAirUnit() => Functions.DismissAirUnit(); /// <summary> /// Attaches the active air unit to the <see cref="LHandle"/> pursuit. /// </summary> public static void AssignAirUnitToPursuit(LHandle pursuit) => Functions.AssignAirUnitToPursuit(pursuit); /// <summary> /// Removes the air unit from the <see cref="LHandle"/> pursuit. /// </summary> public static void RemoveAirUnitFromPursuit() => Functions.RemoveAirUnitFromPursuit(); /// <summary> /// Checks if the air unit exists, regardless of its current assigned task. /// </summary> public static bool IsAirUnitAlive() => Functions.IsAirUnitAlive(); [System.Obsolete("Use IsAirUnitInService()")] public static bool IsAirUnitActive() => Functions.IsAirUnitActive(); /// <summary> /// Checks if the air unit exists and is currently assigned to a player-assigned task. /// </summary> public static bool IsAirUnitInService() => Functions.IsAirUnitInService(); /// <summary> /// Assigns a new <see cref="Entity"/> target to the air unit, if it is active in service. /// </summary> public static void UpdateTarget(Entity target) => Functions.UpdateTarget(target); /// <summary> /// Assigns a new <see cref="Vector3"/> target to the air unit, if it is active in service. /// </summary> public static void UpdateTarget(Vector3 target) => Functions.UpdateTarget(target); /// <summary> /// Updates the air unit's flight characteristics. Pass a value <= 0 to a parameter to restore the default value of the respective flight behavior. /// </summary> /// <param name="flightAltitude">The altitude the air unit will fly when responding or following a target.</param> /// <param name="flightSpeed">The speed the air unit fly when responding or following a target. Value should be in GTA's default measurement, m/s.</param> /// <param name="orbitRadius">The radius the air unit will orbit.</param> /// <param name="orbitSpeed">The speed the air unit will orbit. Value should be in GTA's default measurement, m/s.</param> public static void UpdateFlightCharacteristics(float flightAltitude = -1f, float flightSpeed = -1f, float orbitRadius = -1f, float orbitSpeed = -1f) => Functions.UpdateFlightCharacteristics(flightAltitude, flightSpeed, orbitRadius, orbitSpeed); /// <summary> /// Sets the on-scene duration to the given <paramref name="duration"/>. If the air unit is already in the on-scene task, then it will extend the duration to the given <paramref name="duration"/>. /// </summary> /// <param name="duration">In milliseconds</param> public static void UpdateOnsceneDuration(int duration) => Functions.UpdateOnsceneDuration(duration); /// <summary> /// Checks if the target of the air unit is the given <see cref="Entity"/>. <br/>Note: Make sure to call <see cref="IsAirUnitInService"/> to verify the air unit is active before calling this. /// </summary> public static bool IsCurrentTarget(Entity pedToCheck) => Functions.IsCurrentTarget(pedToCheck); /// <summary> /// Checks if the target of the air unit is the given <see cref="Vector3"/>. <br/>Note: Make sure to call <see cref="IsAirUnitInService"/> to verify the air unit is active before calling this. /// </summary> public static bool IsCurrentTarget(Vector3 posToCheck) => Functions.IsCurrentTarget(posToCheck); /// <summary> /// Retrieves the <see cref="Entity"/> the air unit is targeting. <br/>Note: Make sure to call <see cref="IsAirUnitInService"/> to verify the air unit is active before calling this. /// </summary> public static Entity GetCurrentTarget() => Functions.GetCurrentTarget(); /// <summary> /// Retrieves the <see cref="Vector3"/> the air unit is targeting. <br/>Note: Make sure to call <see cref="IsAirUnitInService"/> to verify the air unit is active before calling this. /// </summary> public static Vector3 GetCurrentTargetPosition() => Functions.GetCurrentTargetPosition(); /// <summary> /// Checks if the air unit is active, but not assigned to the player's request. In other words, is the air unit currently roaming around. /// </summary> /// <returns></returns> public static bool IsCurrentlyRoaming() => Functions.IsCurrentlyRoaming(); } }
Take a look at the INI at least once to make sure you are satisfied with the settings.
Special Thanks:
LSPDFR Developer Discord
Edited by OJdoesIt
Update
What's New in Version 2.4.2
Released
- Added feature to modify the jerk rate and distance (shakiness) of the searchlight
- Improved the accuracy of ETA
- Updated API to allow an Entity object to be targeted instead of just a Ped object
- Made minor updates to the API methods

