Skip to content
RustPluginGenerator

OnHelicopterStrafeEnter

OnHelicopterStrafeEnter is called at the start of PatrolHelicopterAI.StartStrafe, right before the helicopter commits to a strafing run against a player. Returning a non-null value cancels the strafe.

Signature
object OnHelicopterStrafeEnter(PatrolHelicopterAI patrolHelicopterAI, UnityEngine.Vector3 position, BasePlayer strafeTarget)

Parameters

Hook parameters
ParameterTypeDescription
patrolHelicopterAIPatrolHelicopterAIThe PatrolHelicopterAI component of the helicopter that is starting a strafing run. Use it to read the AI's state, distance to target, or to Killed/redirect the helicopter itself.
positionUnityEngine.Vector3The world position of the strafe target at the moment the strafe begins (taken from strafeTarget.transform.position). Use it as the aim point for effects, markers or CUI compass hints.
strafeTargetBasePlayerThe BasePlayer the helicopter is about to lock onto for the strafing run. It is the player passed into PatrolHelicopterAI.StartStrafe, not a computed nearest target.

Return value

Returning null (or nothing) lets the strafe proceed exactly as vanilla. Returning any non-null object cancels the original StartStrafe body, so strafe_target is never set and the helicopter skips this strafing run.

How it works

The hook fires inside PatrolHelicopterAI.StartStrafe(BasePlayer, bool), which the AI calls when it has decided to strafe a player (the vanilla logic picks a target when the helicopter is in range and not already strafing). It runs before the AI assigns strafe_target, rolls the get_out_of_strafe_distance value, and before any napalm decision. Three arguments arrive: the helicopter's PatrolHelicopterAI component, the target's world position, and the target BasePlayer.

This is an entry gate, not a per-tick call — it fires once per strafe attempt. Because the target parameter is typed BasePlayer in the injection, you cannot narrow it to a more specific type meaningfully; instead inspect strafeTarget.IsNpc, team membership, permissions or building authorization to decide whether the run is allowed. patrolHelicopterAI gives you the helicopter's transform and health if you want to check its distance to a safe zone or to the player.

Blocking here is cheaper than blocking later damage hooks: the AI never enters the strafe state and does not consume napalm.

Example plugin: Skip strafes against players inside a safe zone

HelicopterSafeZoneStrafe.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Helicopter Safe Zone Strafe", "RustPluginGenerator", "1.0.0")]
    [Description("Cancels patrol helicopter strafing runs against players inside protected zones")]
    public class HelicopterSafeZoneStrafe : RustPlugin
    {
        private const string PermImmune = "helicoptersafezonestrafe.immune";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Immune permission bypasses zones")]
            public bool PermissionBypassesZones = true;

            [JsonProperty("Protected zones (x, y, z, radius)")]
            public List<Zone> Zones = new List<Zone>
            {
                new Zone { X = 0f, Y = 0f, Z = 0f, Radius = 50f }
            };
        }

        private class Zone
        {
            [JsonProperty("X")] public float X;
            [JsonProperty("Y")] public float Y;
            [JsonProperty("Z")] public float Z;
            [JsonProperty("Radius")] public float Radius;
        }

        protected override void LoadDefaultConfig() => config = new PluginConfig();

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new Exception();
            }
            catch
            {
                PrintWarning("Configuration file is invalid, using defaults");
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void SaveConfig() => Config.WriteObject(config);

        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["Protected"] = "The patrol helicopter cannot strafe you here."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args)
        {
            return string.Format(lang.GetMessage(key, this, userId), args);
        }

        private void Init()
        {
            permission.RegisterPermission(PermImmune, this);
        }

        private object OnHelicopterStrafeEnter(PatrolHelicopterAI patrolHelicopterAI, Vector3 position, BasePlayer strafeTarget)
        {
            if (strafeTarget == null || strafeTarget.IsNpc) return null;

            if (config.PermissionBypassesZones && permission.UserHasPermission(strafeTarget.UserIDString, PermImmune))
            {
                SendReply(strafeTarget, Msg("Protected", strafeTarget.UserIDString));
                return true;
            }

            if (!IsInsideProtectedZone(position)) return null;

            SendReply(strafeTarget, Msg("Protected", strafeTarget.UserIDString));
            return true;
        }

        private bool IsInsideProtectedZone(Vector3 position)
        {
            foreach (Zone zone in config.Zones)
            {
                if (Vector3.Distance(position, new Vector3(zone.X, zone.Y, zone.Z)) <= zone.Radius)
                    return true;
            }
            return false;
        }
    }
}

The plugin keeps a configurable list of safe-zone world positions and radii. When OnHelicopterStrafeEnter fires, it checks the target player's current position against every zone using Vector3.Distance. If the player is inside a protected zone, the hook returns a non-null object, which cancels the strafe. It also respects a helicopters.safestrafe permission so players with the permission are always left alone, and it messages the protected player once through the language file. No timers or UI are used, so Unload only needs to be present for completeness.

Common use cases

  • Protect safe zones and monuments

    Cancel strafes when the target is inside a no-PvE zone so players trading or doing monuments are not gunned down by the helicopter.

  • Permission-based immunity

    Give VIP or staff a permission that makes the helicopter never choose them as a strafe target, using the same hook return to block the run.

  • Alert and log incoming strafes

    Return null but use the position and target to send a warning message or log strafe events for anti-cheat review of suspicious helicopter behavior.

Pitfalls

  • It fires per strafe attempt, not per player

    The AI calls StartStrafe repeatedly during an attack, so a blocked player may generate many hook calls. Keep the logic short and avoid chat spam inside it.

  • Blocking does not force a new target

    Cancelling the strafe leaves the AI in its prior state; it may retry the same target shortly after. Combine with targeting hooks if you need it to pick someone else.

  • Narrowing the parameter type has no effect

    The injection passes the actual BasePlayer reference; declaring a subclass parameter like ScientistNPC will simply cause Oxide to skip your method for normal players, silently disabling the guard.

Build a plugin with OnHelicopterStrafeEnter

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Protect safe zones and monuments using the OnHelicopterStrafeEnter hook, with a config file and a permission
Generate this plugin

Edit the prompt on the next screen. 2 free plugins a month, no card.

Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.

Build a plugin with OnHelicopterStrafeEnter

Generate