CanBradleyApcTarget
CanBradleyApcTarget is called from BradleyAPC.VisibilityTest whenever the APC checks whether an entity is visible and therefore worth tracking as a target.
object CanBradleyApcTarget(BradleyAPC bradleyAPC, BaseEntity ent)Parameters
| Parameter | Type | Description |
|---|---|---|
bradleyAPC | BradleyAPC | The BradleyAPC instance running its visibility check. Use it to compare distance to the player, read its position or health, or identify which APC entity is asking. |
ent | BaseEntity | The BaseEntity the APC is evaluating as a potential target. It can be a player, a vehicle, a deployable or any other entity the APC is considering; cast with `as BasePlayer` when you only care about players. |
Return value
Returning null (or any non-bool value) lets the APC use its own visibility computation. Returning a bool short-circuits the method and becomes the visibility result: true marks the entity as a valid target, false prevents the APC from targeting it.
How it works
The hook fires inside BradleyAPC.VisibilityTest, which the APC runs while evaluating candidate targets during its think loop. The method first performs its own line-of-sight and distance checks against the entity's center point, then calls the hook before returning that boolean. Two parameters matter: bradleyAPC is the vehicle doing the check, and ent is the candidate entity. A common use is to exclude certain entities from targeting — for example, keep the APC from shooting at players who are in a safe zone, at NPCs on a PvE server, or at a specific vehicle type. Returning a bool overrides the game's computed visibility result, so false denies the target and true forces the APC to treat it as visible. Because the hook fires per candidate per visibility test, it runs frequently while an APC is active; keep the body cheap and avoid logging. You can declare bradleyAPC as BradleyAPC (as given) or narrow ent to a specific type such as BasePlayer, but narrowing to BasePlayer means Oxide only routes calls where the candidate is a player, and non-player candidates fall through to default behavior.
Example plugin: Stop Bradley from targeting players inside safe zones
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("BradleySafeZoneTarget", "RustPluginGenerator", "1.0.0")]
[Description("Prevents the Bradley APC from targeting players standing inside configured safe zones")]
public class BradleySafeZoneTarget : RustPlugin
{
private class Zone
{
[JsonProperty("X")]
public float X { get; set; }
[JsonProperty("Y")]
public float Y { get; set; }
[JsonProperty("Z")]
public float Z { get; set; }
[JsonProperty("Radius")]
public float Radius { get; set; }
}
private class PluginConfig
{
[JsonProperty("Block targeting players only (ignore other entities)")]
public bool PlayersOnly { get; set; } = true;
[JsonProperty("Safe zones")]
public List<Zone> Zones { get; set; } = new List<Zone>
{
new Zone { X = 0f, Y = 0f, Z = 0f, Radius = 30f }
};
}
private PluginConfig config;
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);
private object CanBradleyApcTarget(BradleyAPC bradleyAPC, BaseEntity ent)
{
if (bradleyAPC == null || ent == null) return null;
if (config.PlayersOnly && !(ent is BasePlayer)) return null;
Vector3 position = ent.transform.position;
if (config.Zones == null) return null;
for (int i = 0; i < config.Zones.Count; i++)
{
Zone zone = config.Zones[i];
if (zone == null) continue;
Vector3 center = new Vector3(zone.X, zone.Y, zone.Z);
if (Vector3.Distance(position, center) <= zone.Radius)
{
return false;
}
}
return null;
}
}
}The plugin checks the entity being evaluated and only intervenes when it is a player. It compares the player's position against safe-zone centers and radii stored in the config. If the player is inside any configured zone, the hook returns false, which overrides the APC's visibility result and stops it from acquiring that player as a target. Everything else returns null, keeping default behavior. Admins can add zones by editing oxide/config/BradleySafeZoneTarget.json, and distance checks use Vector3.Distance so the hook body stays inexpensive even though it fires often.
Common use cases
PvE servers
Return
falsefor all player candidates so the APC never acquires players as targets, leaving it as decorative or event-only content.Safe-zone protection
Deny targeting for players standing inside designated safe areas so traders and new spawns are not shot through the APC's acquisition.
Vehicle-only targeting
Narrow the second parameter to a vehicle type so the APC keeps hunting minicopters and cars while ignoring everything else.
Pitfalls
Only bool returns take effect
The game checks whether the returned object is a
bool. Returning other types such as an int or string is ignored and the APC's own visibility result is used.Fires very often
VisibilityTest runs per candidate during think, so expensive work (LINQ, entity scans, permission lookups across many players) adds up. Cache results or keep the body to a few comparisons.
Narrowing the entity parameter
Declaring
entasBasePlayermakes Oxide skip the hook for non-player candidates, which is convenient but means you cannot intervene for vehicles or deployables in the same method.
Build a plugin with CanBradleyApcTarget
Describe what should happen and get a compiled plugin that uses this hook.
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 CanBradleyApcTarget
Generate