OnContainerDropItems
OnContainerDropItems is called when DropUtil.DropItems is about to scatter the contents of an item container onto the ground. Returning a non-null value cancels the drop.
object OnContainerDropItems(ItemContainer container)Parameters
| Parameter | Type | Description |
|---|---|---|
container | ItemContainer | The ItemContainer whose contents are about to be dropped into the world. Inspect container.itemList to see the items, container.playerOwner for the looter, or container.entityOwner for the source entity (box, corpse, oven). |
Return value
Returning null (or any null) lets the game continue and drop every item in the container at the given position. Returning any non-null object stops the original method, so no items are dropped and the container is left as-is; the returned value itself is discarded.
How it works
The hook fires from DropUtil.DropItems(container, position), the shared helper the game uses whenever a container's contents get dumped into the world: empty loot containers, despawned boxes, corpses, ovens, recyclers and similar. Before any item becomes a DroppedItem, Oxide calls OnContainerDropItems with the container being emptied.
Use container.itemList to read the items that are about to drop, container.playerOwner to find the looting player (null for world containers), and container.entityOwner to identify the source entity. You can convert or filter the contents here, e.g. call ItemManager.CreateByName for a replacement, give it to the owner, or simply let the drop proceed.
The call is skipped entirely when Server.dropitems is disabled or the container has no itemList, so it will not fire on servers that turn off item drops. Every call passes exactly one ItemContainer, so declaring a more specific parameter type gains nothing here. The hook fires frequently on busy servers, so keep the body cheap and avoid console spam.
Example plugin: Replace dropped container loot with a scrap token
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Container Drop To Scrap", "RustPluginGenerator", "1.0.0")]
[Description("Replaces dropped container loot with scrap paid to the looting player")]
public class ContainerDropToScrap : RustPlugin
{
private const string PermBypass = "containerdroptoscrap.bypass";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Scrap Per Item")]
public int ScrapPerItem { get; set; } = 5;
[JsonProperty("Bypass Permission Keeps Normal Drops")]
public bool AllowBypass { 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 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>
{
["Received"] = "Your looted items were converted into {0} scrap.",
["Reloaded"] = "ContainerDropToScrap configuration reloaded."
}, 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(PermBypass, this);
}
private object OnContainerDropItems(ItemContainer container)
{
if (container == null || container.itemList == null || container.itemList.Count == 0)
return null;
var player = container.playerOwner;
if (config.AllowBypass && player != null && permission.UserHasPermission(player.UserIDString, PermBypass))
return null;
int itemCount = container.itemList.Count;
List<Item> items = new List<Item>(container.itemList);
foreach (Item item in items)
{
item.Remove();
}
if (player != null && player.IsConnected && config.ScrapPerItem > 0)
{
int total = itemCount * config.ScrapPerItem;
Item scrap = ItemManager.CreateByName("scrap", total, 0);
if (scrap != null && !player.inventory.GiveItem(scrap))
{
scrap.Drop(player.transform.position, Vector3.zero);
}
player.ChatMessage(Msg("Received", player.UserIDString, total));
}
return true;
}
[ChatCommand("scrapreload")]
private void CmdReload(BasePlayer player, string command, string[] args)
{
if (player != null && !player.IsAdmin) return;
LoadConfig();
if (player != null) player.ChatMessage(Msg("Reloaded", player.UserIDString));
}
}
}The plugin cancels every container drop and instead credits the looting player with a configurable amount of scrap per dropped item. In OnContainerDropItems it counts container.itemList, removes the items so nothing lingers in the container, then hands the owner a scrap item via ItemManager.CreateByName and GiveItem. Containers with no owner still get blocked so loot does not fall on the ground, and the scrap is scaled by the Scrap Per Item config value. A permission check lets staff bypass the conversion and keep normal drops, and the config is reloadable through a chat command restricted to admins.
Common use cases
Convert loot into currency
Block the physical drop and pay the looter a scrap or Economics balance per item, useful for servers that dislike item sprawl around monuments.
Prevent despawn loot spam
Return non-null for empty or low-value containers so mass looting does not scatter hundreds of dropped items and hurt server performance.
Filter which items can fall
Inspect container.itemList, remove unwanted entries, and return null so only the allowed items drop into the world.
Pitfalls
Hook does not fire when drops are disabled
If
Server.dropitemsis off, DropUtil returns before calling the hook. Do not rely on it as the only path for handling container contents.Cancelling leaves items in the container
Returning non-null stops the drop but does not remove the items. Remove them yourself or they stay in the container and may be dropped later.
Called very often
Loot bags, corpses and boxes all route through this hook on busy servers. Avoid heavy loops or logging inside the body.
Build a plugin with OnContainerDropItems
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 OnContainerDropItems
Generate