Skip to content
RustPluginGenerator

CanBeTargeted

CanBeTargeted is called when an AutoTurret, HelicopterTurret, FlameTurret or GunTrap decides whether an entity is a valid target. Returning a bool overrides the game's own visibility or arc check for that entity.

Signature
object CanBeTargeted(BaseCombatEntity entity, AutoTurret turret)

Parameters

Hook parameters
ParameterTypeDescription
entityBaseCombatEntityThe entity a turret is evaluating as a target. For AutoTurret it is a BaseCombatEntity, for FlameTurret and GunTrap it is always a BasePlayer, and for HelicopterTurret it is a BaseCombatEntity. Cast or null-check it before reading owner or player data.
turretAutoTurretThe turret or trap asking the question. Declare it as AutoTurret, HelicopterTurret, FlameTurret or GunTrap to only receive calls from that source; the declared type must match the argument or Oxide skips the call.

Return value

Return true to mark the candidate as targetable and false to reject it; both are used verbatim by the caller instead of the game's own check. Return null (or anything that is not a bool) to let vanilla behavior run: the auto turret falls through to its visibility raycast, the heli to the angle test, and the flame turret and gun trap to their normal trigger logic.

How it works

This hook fires inside the target selection code of four turret types. On AutoTurret.ObjectVisible it runs while the turret scans for a visible target, before the line-of-sight raycast is done. On HelicopterTurret.InFiringArc it runs while the heli evaluates an entity, before the 80 degree angle test. On FlameTurret.CheckTrigger and GunTrap.CheckTrigger it runs per player in the trigger volume, after sleeping, dead and height checks have already passed.

entity is the candidate being evaluated and turret is the device asking. Use turret to filter by type: declare the parameter as BaseCombatEntity and you receive calls from auto turrets and heli turrets; declare BasePlayer and you only receive calls where the candidate is a player. Declaring a more specific turret type narrows the hook to that device, and Oxide skips the call when the argument is not an instance of the declared type.

Returning a bool for AutoTurret and HelicopterTurret replaces the result of ObjectVisible / InFiringArc, so the turret treats the answer as final. For the flame turret and gun trap the bool also short-circuits the trigger check. This runs frequently while turrets are active, so keep the body cheap and cache decisions.

Other signatures

Oxide also calls CanBeTargeted from other places in the game with these parameter types. Declare the overload you need, or several:

  • object CanBeTargeted(BaseCombatEntity potentialtarget, HelicopterTurret helicopterTurret)
  • object CanBeTargeted(BasePlayer player, FlameTurret flameTurret)
  • object CanBeTargeted(BasePlayer player, GunTrap gunTrap)

Example plugin: Make turrets ignore players protected by a plugin permission

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

namespace Oxide.Plugins
{
    [Info("TurretSafeZone", "RustPluginGenerator", "1.0.0")]
    [Description("Prevents turrets and traps from targeting players who hold the immunity permission")]
    public class TurretSafeZone : RustPlugin
    {
        private const string PermUse = "turretsafezone.immune";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Announce immunity on toggle")]
            public bool AnnounceOnToggle { get; set; } = true;
        }

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

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                config = Config.ReadObject<PluginConfig>();
                if (config == null) throw new System.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>
            {
                ["NoPermission"] = "You do not have permission to use this command.",
                ["Enabled"] = "Turret immunity enabled.",
                ["Disabled"] = "Turret immunity disabled."
            }, this);
        }

        private string Msg(string key, string userId = null) => lang.GetMessage(key, this, userId);

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

        private object CanBeTargeted(BaseCombatEntity entity, BaseCombatEntity turret)
        {
            if (entity == null || turret == null) return null;

            var player = entity as BasePlayer;
            if (player == null || player.IsNpc) return null;

            if (permission.UserHasPermission(player.UserIDString, PermUse)) return false;

            return null;
        }

        [ChatCommand("turretimmune")]
        private void CmdTurretImmune(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, PermUse))
            {
                player.ChatMessage(Msg("NoPermission", player.UserIDString));
                return;
            }

            if (permission.UserHasPermission(player.UserIDString, PermUse))
            {
                permission.RevokeUserPermission(player.UserIDString, PermUse);
                if (config.AnnounceOnToggle) player.ChatMessage(Msg("Disabled", player.UserIDString));
            }
            else
            {
                permission.GrantUserPermission(player.UserIDString, PermUse, this);
                if (config.AnnounceOnToggle) player.ChatMessage(Msg("Enabled", player.UserIDString));
            }
        }
    }
}

The plugin registers a turretsafezone.immune permission and checks it inside CanBeTargeted. When the candidate is a player who holds the permission, the hook returns false, which the auto turret, heli turret, flame turret and gun trap take as a rejection, so that player is never acquired as a target. Everyone else gets null, so the normal visibility and trigger logic runs unchanged. An admin chat command toggles the permission so testers can turn protection on and off without touching config files. Because the hook fires often, it only does a permission lookup and a type check before returning.

Common use cases

  • Protect new players at spawn

    Reject any candidate that is a BasePlayer inside the spawn area by comparing positions against a configured radius, so base turrets near spawn cannot farm fresh players.

  • Let owners bypass their own turrets

    Return false when the player's userID matches the turret's OwnerID, so an authorized owner can walk through their own auto turret line of fire without being shot.

  • Team-aware auto turrets

    Compare currentTeam of the candidate with the team of turret.OwnerID and reject teammates, useful on servers where turrets are meant to be squad-friendly.

Pitfalls

  • Not every turret passes a BasePlayer

    AutoTurret and HelicopterTurret pass BaseCombatEntity, which can be an animal, a scientist or a vehicle. Cast with as BasePlayer and handle null before reading player members.

  • Verify the turret argument type

    If you declare the second parameter as AutoTurret you will never see FlameTurret or GunTrap calls. Declare a shared base like BaseCombatEntity if you want to affect all four devices.

  • This hook is hot

    ObjectVisible runs repeatedly while a turret scans, often many times per second per turret. Avoid LINQ, string formatting or entity scans inside the body; cache permissions or lists when possible.

Build a plugin with CanBeTargeted

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

Prompt: Protect new players at spawn using the CanBeTargeted 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 CanBeTargeted

Generate