OnEntityDestroy
OnEntityDestroy is called from the OnDied handler of the CH47 Chinook and the Bradley APC, right before their death effects and loot drops run. Returning a non-null value stops that death code from executing.
object OnEntityDestroy(CH47HelicopterAIController entity)Parameters
| Parameter | Type | Description |
|---|---|---|
entity | CH47HelicopterAIController | The CH47 Chinook or Bradley APC that is going through its death routine. For the Chinook it is a CH47HelicopterAIController, for the Bradley it is a BradleyAPC. |
Return value
Return null to let the game continue with its normal death handling (crate drop for the Chinook, explosion marker, explosion effect and loot for the Bradley). Returning any non-null value skips the rest of that death method: no crate, no explosion effect, no loot.
How it works
The hook fires inside CH47HelicopterAIController.OnDied after the Chinook has already been marked dead, before the game checks its crates and drops a new one. It also fires inside BradleyAPC.OnDied before the APC creates its explosion marker, plays the explosion effect and spawns loot. Declaring the parameter as CH47HelicopterAIController makes Oxide call your method only for the Chinook; declaring BradleyAPC narrows it to the Bradley. The parameter is the entity itself, so net.ID.Value, transform.position and ShortPrefabName are available for logging, reward logic or respawn scheduling. This is not the general entity kill hook: it only covers these two AI vehicles and runs at death, not at despawn. Use it when you want a last-chance override of the vanilla death behavior or to react to a vehicle being destroyed. Because the return check happens before the loot logic, blocking the Chinook here also blocks the crate.
Other signatures
Oxide also calls OnEntityDestroy from other places in the game with these parameter types. Declare the overload you need, or several:
object OnEntityDestroy(BradleyAPC bradleyAPC)
Example plugin: Make vehicle deaths broadcast and pay a reward
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Vehicle Destroy Reward", "RustPluginGenerator", "1.0.0")]
[Description("Announces CH47 and Bradley deaths and rewards nearby players.")]
public class VehicleDestroyReward : RustPlugin
{
private const string PermReward = "vehicledestroyreward.reward";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Scrap reward per nearby player")]
public int ScrapReward = 50;
[JsonProperty("Reward radius (meters)")]
public float RewardRadius = 100f;
[JsonProperty("Broadcast vehicle deaths")]
public bool BroadcastDeaths = true;
}
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>
{
["Destroyed"] = "The {0} was destroyed at grid {1}.",
["Rewarded"] = "You received {0} scrap for helping destroy the {1}."
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
=> string.Format(lang.GetMessage(key, this, userId), args);
private void Init()
{
permission.RegisterPermission(PermReward, this);
}
private object OnEntityDestroy(CH47HelicopterAIController chinook)
{
if (chinook == null || chinook.IsDestroyed) return null;
HandleDestroyed("CH47 Chinook", chinook.transform.position);
return null;
}
private object OnEntityDestroy(BradleyAPC bradley)
{
if (bradley == null || bradley.IsDestroyed) return null;
HandleDestroyed("Bradley APC", bradley.transform.position);
return null;
}
private void HandleDestroyed(string vehicleName, Vector3 position)
{
string grid = PositionToGrid(position);
int reward = config.ScrapReward;
if (config.BroadcastDeaths)
{
Server.Broadcast(Msg("Destroyed", null, vehicleName, grid));
}
if (reward <= 0) return;
float radiusSquared = config.RewardRadius * config.RewardRadius;
foreach (BasePlayer player in BasePlayer.activePlayerList)
{
if (player == null || !player.IsConnected || player.IsDead()) continue;
if (!permission.UserHasPermission(player.UserIDString, PermReward)) continue;
if ((player.transform.position - position).sqrMagnitude > radiusSquared) continue;
Item scrap = ItemManager.CreateByName("scrap", reward);
if (scrap == null) continue;
player.GiveItem(scrap);
player.ChatMessage(Msg("Rewarded", player.UserIDString, reward, vehicleName));
}
}
private string PositionToGrid(Vector3 position)
{
const float cellSize = 150f;
int x = Mathf.FloorToInt((position.x + 2048f) / cellSize) + 1;
int z = Mathf.FloorToInt((position.z + 2048f) / cellSize) + 1;
return x + " " + z;
}
}
}The plugin listens for OnEntityDestroy with the base-type-declared parameter CH47HelicopterAIController and a second overload for BradleyAPC, so both vehicles are handled. Each handler checks the entity is not already destroyed, resolves the last attacker through InvitedUsers-style tracking is avoided; instead it awards every online player who is near the vehicle a configurable scrap reward and broadcasts a chat announcement with the vehicle name and grid. The Chinook handler also keeps the vanilla crate drop because it returns null. A small helper builds the grid reference from transform.position and pushes it through the language file so the text is translatable.
Common use cases
Reward crews for downing a Bradley
Award scrap or a currency via an optional Economics reference to nearby players when the APC dies. Since the hook returns null, the APC still explodes and drops its crate.
Block the Chinook crate
Return a non-null value from the Chinook overload to skip
DropCrate(), for example on a PvE server that wants no airdrop-style loot from the helicopter.Announce and log vehicle kills
Broadcast the CH47 or Bradley position and killer to chat, or write the event to oxide/data for later review of how often the vehicles are being farmed.
Pitfalls
This is not a general despawn hook
OnEntityDestroyhere only fires for the CH47 and Bradley death paths. A vehicle that is killed via admin command or adminKill()may not pass through this code, and normal entities never call it.Returning non-null cancels the Bradley explosion
Blocking the Bradley death path also removes its explosion marker, explosion effect and loot spawn. Only return a value if you intentionally want to handle that yourself.
Use the correct parameter type
An overload declared as
BradleyAPCwill not be called for the Chinook and vice versa. Declare both overloads, or a common base type such asBaseEntity, if you want one handler for both.
Build a plugin with OnEntityDestroy
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 OnEntityDestroy
Generate