OnBradleyApcThink
OnBradleyApcThink is called at the start of every BradleyAPC.DoSimpleAI tick, before the APC picks its target, runs patrol pathing, or executes its attack logic.
object OnBradleyApcThink(BradleyAPC bradleyAPC)Parameters
| Parameter | Type | Description |
|---|---|---|
bradleyAPC | BradleyAPC | The Bradley APC entity whose AI tick is about to run. It is a live server entity, so check it for null, IsDestroyed, and use Health(), transform.position or GetParentEntity() to build your logic. |
Return value
Returning a non-null value skips the rest of DoSimpleAI for that tick: the APC does not call SetTarget() and skips its movement and attack logic. Returning null lets the vanilla AI run normally. The original method returns void, so the returned object is only used as a signal and is never inspected by the game.
How it works
This hook fires once per AI update of a Bradley APC, inside BradleyAPC.DoSimpleAI. The call happens after the entity refreshes its night flag and before SetTarget(), so the APC has not yet chosen a target, moved along its patrol path, or fired for that tick. Because DoSimpleAI runs on a short repeating schedule for each APC, the hook is a per-APC think callback, not a one-off spawn event.
Use the bradleyAPC parameter to inspect or act on that specific APC: read Health() to check how damaged it is, read transform.position, look at its parent entity after a crate drop, or schedule a timed reaction. The APC is not guaranteed to be alive or complete, so null-check and test IsDestroyed before touching members.
The parameter type is already the concrete BradleyAPC, so you cannot narrow it further. Instead, narrow logically: if a server has several APC entities (rare, but possible with custom spawns), filter on health, position or owner inside the hook.
Because this runs many times per minute per APC, keep the body cheap: no Puts, no allocations per tick, and no expensive entity scans.
Example plugin: Make damaged Bradleys stop hunting players
using System;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Bradley Pacifist Threshold", "RustPluginGenerator", "1.0.0")]
[Description("Makes damaged Bradley APCs stop hunting players below a health threshold.")]
public class BradleyPacifistThreshold : RustPlugin
{
private class PluginConfig
{
[JsonProperty("Passive below health percent (0-100)")]
public float PassivePercent = 30f;
[JsonProperty("Chance per tick to ignore pacifism (0-1)")]
public float ResumeChance = 0.05f;
[JsonProperty("Broadcast status every X seconds (0 = off)")]
public float StatusInterval = 120f;
}
private PluginConfig config;
private Timer statusTimer;
private object blockSignal = new object();
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 void Init()
{
if (config.StatusInterval > 0f)
{
statusTimer = timer.Every(config.StatusInterval, BroadcastStatus);
}
}
private void Unload()
{
statusTimer?.Destroy();
statusTimer = null;
}
private object OnBradleyApcThink(BradleyAPC bradleyAPC)
{
if (bradleyAPC == null || bradleyAPC.IsDestroyed) return null;
float max = bradleyAPC.MaxHealth();
if (max <= 0f) return null;
float percent = bradleyAPC.Health() / max * 100f;
if (percent > config.PassivePercent) return null;
// Occasionally let a damaged APC run its normal AI so it stays a threat.
if (UnityEngine.Random.Range(0f, 1f) < config.ResumeChance) return null;
return blockSignal;
}
private void BroadcastStatus()
{
int pacified = 0;
foreach (var entity in BaseNetworkable.serverEntities)
{
var apc = entity as BradleyAPC;
if (apc == null || apc.IsDestroyed) continue;
float max = apc.MaxHealth();
if (max > 0f && apc.Health() / max * 100f <= config.PassivePercent) pacified++;
}
if (pacified > 0)
{
Server.Broadcast(string.Format("{0} Bradley APC(s) are currently sitting below {1:0}% health and holding fire.", pacified, config.PassivePercent));
}
}
}
}The plugin configures a health percentage below which a Bradley becomes passive and a chance to restore full aggression in later ticks. When OnBradleyApcThink fires, the plugin skips destroyed or null APCs, computes the APC's health ratio with Health() and MaxHealth(), and returns a non-null object so the vanilla DoSimpleAI body is skipped and the APC stays idle for that tick. UnityEngine.Random.Range decides whether the APC gets to run its normal AI again, so low-health Bradleys occasionally become dangerous, which keeps fights unpredictable instead of freezing the APC completely. A periodic timer broadcasts a status line to chat, and Unload destroys it cleanly.
Common use cases
Pause Bradley AI during server events
Return a non-null value for a configurable time window so Bradleys stop targeting and shooting while an admin-run event or wipe sequence is in progress, then let them resume.
Build a low-health passive phase
Compare
Health()against the configured threshold and suppress the think step so the APC stops chasing players, giving them a chance to finish it off or retreat.Track APC activity for analytics
Count think ticks per APC net ID to know how often each Bradley is active, then write the totals to a data file or chat summary from a slow timer rather than inside the hook.
Pitfalls
It runs very often
DoSimpleAIis called on a short repeating interval for every APC, so logging, allocations or entity scans inside the hook will cost server performance. Cache values and move heavy work into timers.Any non-null return freezes the APC
The check is
Interface.CallHook(...) != null, so returningtrue,falseor even0boxed as an object stops the AI. Always returnnullfrom paths where the APC should behave normally.The APC may be mid-disposal
During destruction or after a crate drop the entity can be flagged destroyed while still ticking. Test
bradleyAPC == nullandbradleyAPC.IsDestroyedbefore reading health or position.
Build a plugin with OnBradleyApcThink
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 OnBradleyApcThink
Generate