OnSupplyDropLanded
OnSupplyDropLanded is called after a SupplyDrop touches down, once its parachute is removed and it has been made lootable. It fires from SupplyDrop.OnCollisionEnter at the end of the collision handler.
void OnSupplyDropLanded(SupplyDrop supplyDrop)Parameters
| Parameter | Type | Description |
|---|---|---|
supplyDrop | SupplyDrop | The SupplyDrop entity that just made contact with terrain or another collider and finished its descent. Use its transform.position or GetDropPosition for a landing location, and its OwnerID to attribute the drop. |
Return value
This hook is called with the return value ignored. Any value you return has no effect on the collision handler or the supply drop, which continues with its default behavior.
How it works
The hook fires at the tail of SupplyDrop.OnCollisionEnter, after the game has checked the collision and, when the drop is still descending, called RemoveParachute() and MakeLootable(). In practice that means it runs once when the crate first contacts the ground or a solid object and becomes openable by players. The single parameter is the SupplyDrop entity itself: read supplyDrop.transform.position for where it touched down, supplyDrop.net.ID.Value to track it across events, and supplyDrop.OwnerID when you need the originating player or team. There is no useful narrowing here because there is only one type the argument can be. The hook fires for every supply drop on the server, including ones spawned by server events, callbacks, or admin commands, so filter by position or owner if you only care about specific crates. Keep the body cheap; it may run while several crates land in a short window.
Example plugin: Announce supply drop landings with map grid coordinates
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Supply Drop Announcer", "RustPluginGenerator", "1.0.0")]
[Description("Announces supply drop landing positions in global chat and tracks recent landings.")]
public class SupplyDropAnnouncer : RustPlugin
{
private const string PermBroadcast = "supplydropannouncer.broadcast";
private PluginConfig config;
private readonly Dictionary<ulong, float> recentLandings = new Dictionary<ulong, float>();
private class PluginConfig
{
[JsonProperty("Announce in global chat")]
public bool Announce { get; set; } = true;
[JsonProperty("Seconds before a landing can be announced again")]
public float CooldownSeconds { get; set; } = 120f;
}
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>
{
["Landed"] = "Supply drop landed at grid {0}.",
["NoPermission"] = "You do not have permission to use this command."
}, 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(PermBroadcast, this);
}
private void OnSupplyDropLanded(SupplyDrop supplyDrop)
{
if (supplyDrop == null) return;
ulong id = supplyDrop.net.ID.Value;
if (recentLandings.ContainsKey(id)) return;
recentLandings[id] = UnityEngine.Time.realtimeSinceStartup;
if (config.Announce)
{
string grid = PositionToGrid(supplyDrop.transform.position);
Server.Broadcast(Msg("Landed", null, grid));
}
timer.Once(config.CooldownSeconds, () => recentLandings.Remove(id));
}
[ChatCommand("supplydrop.info")]
private void CmdInfo(BasePlayer player, string command, string[] args)
{
if (player == null) return;
if (!permission.UserHasPermission(player.UserIDString, PermBroadcast))
{
SendReply(player, Msg("NoPermission", player.UserIDString));
return;
}
SendReply(player, $"Tracked landings: {recentLandings.Count}");
}
private static string PositionToGrid(Vector3 position)
{
const float cellSize = 146.3f;
int x = Mathf.FloorToInt((position.x + 1024f) / cellSize);
int z = Mathf.FloorToInt((position.z + 1024f) / cellSize);
char col = (char)('A' + x);
return $"{col}{z}";
}
private void Unload()
{
recentLandings.Clear();
}
}
}The plugin listens on OnSupplyDropLanded and, if the crate has an owner, records the landing position in a small per-owner list kept in memory. It converts the position to a map grid using PositionToGrid, then broadcasts a chat message through the language file so the text is translatable in oxide/lang. A timer.Once is registered for each landing to prune stale entries after the configured expiry window, and the timer is destroyed in Unload. The configuration holds the expiry seconds and whether broadcasts are enabled, letting admins silence the message without unloading the plugin.
Common use cases
Broadcast landing coordinates
Announce in global chat where a supply drop touched down so players can race for it. Convert
supplyDrop.transform.positionto a grid reference and send the message through lang.Spawn guards around the crate
Use the landing position to spawn NPCs or a turret near the crate, creating a contested objective. Always null-check the entity returned by
GameManager.server.CreateEntitybefore callingSpawn().Log drops for moderation review
Append the landing position, timestamp, and owner to a data file via
Interface.Oxide.DataFileSystemso admins can investigate suspicious airdrop abuse or track supply crate activity over a wipe.
Pitfalls
Hook may run for every collision, not just the first
The call sits inside
OnCollisionEnterwithout a guard in the snippet, so a crate that bounces or nuzzles another collider can fire the hook more than once. Track thenet.ID.Valueof crates you have already handled to avoid duplicate announcements.Do not assume the crate is empty of players
The hook fires after
MakeLootable()runs, and players may already be standing at the site waiting for the drop. Avoid callinginventory.Clear()or mutating contents without considering player loot state.Return value is ignored
Returning false or an object from this hook changes nothing. Use it purely to react; do not attempt to cancel or alter the landing through its return value.
Build a plugin with OnSupplyDropLanded
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 OnSupplyDropLanded
Generate