OnRackedWeaponUnload
OnRackedWeaponUnload is called when a player tries to remove a weapon from a WeaponRack, right before the rack detaches and returns the item to the player. Returning a non-null value cancels the unload.
object OnRackedWeaponUnload(Item slot, BasePlayer player, WeaponRack weaponRack)Parameters
| Parameter | Type | Description |
|---|---|---|
slot | Item | The inventory slot item of the racked weapon being unloaded; it is the Item returned by WeaponRack inventory.GetSlot for the weapon's InventoryIndex. Null-check it and use it to inspect the weapon before the rack releases it. |
player | BasePlayer | The BasePlayer who triggered the unload by interacting with the weapon rack. Can be null in unusual cases, so guard before using it. |
weaponRack | WeaponRack | The WeaponRack entity the weapon is mounted on. Use it to check ownership, position, attached privilege or to send effects. |
Return value
Returning null (or any value that is not a valid type for the check) lets the unload proceed normally. Returning a non-null value makes UnloadWeapon bail out early and returns before the held entity is detached, so the weapon stays on the rack and the player gets no item.
How it works
This hook fires inside WeaponRack.UnloadWeapon, after the game has resolved the weapon slot and confirmed the item can be reloaded at a rack, but before the held entity is detached and handed back to the player. Because the injection sits in the unload path only, it does not run when a weapon is first mounted (OnRackedWeaponLoad covers that side).
slot is the Item from the rack inventory, so you can read info.shortname, skin, amount, condition and GetOwnerPlayer(). player is whatever BasePlayer invoked the interaction. weaponRack gives you OwnerID, transform.position, GetBuildingPrivilege() and other entity data without re-resolving anything.
There is only one call site and it passes the concrete Item, BasePlayer and WeaponRack types, so declaring narrower parameter types is not useful here. The hook is not called on server startup or when the rack is destroyed by other means, only on the player-driven unload path, so it is cheap to use for policy checks. Reach for it when you want to keep a weapon on the rack, log rack activity, or attach a restriction to specific weapons.
Example plugin: Block unloading of restricted weapons from racks
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Rack Unload Guard", "RustPluginGenerator", "1.0.0")]
[Description("Blocks unloading of restricted weapons from weapon racks unless the player has permission.")]
public class RackUnloadGuard : RustPlugin
{
private const string PermBypass = "rackunloadguard.bypass";
private PluginConfig config;
private readonly HashSet<string> restricted = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private class PluginConfig
{
[JsonProperty("Restricted weapon shortnames")]
public List<string> RestrictedWeapons = new List<string> { "rifle.ak", "rifle.l96", "lmg.m249" };
}
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>
{
["Restricted"] = "This weapon cannot be removed from the rack."
}, 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);
restricted.Clear();
if (config?.RestrictedWeapons != null)
{
foreach (var shortname in config.RestrictedWeapons)
{
if (!string.IsNullOrEmpty(shortname))
restricted.Add(shortname);
}
}
}
private object OnRackedWeaponUnload(Item slot, BasePlayer player, WeaponRack weaponRack)
{
if (slot?.info == null || player == null || weaponRack == null) return null;
if (!restricted.Contains(slot.info.shortname)) return null;
if (permission.UserHasPermission(player.UserIDString, PermBypass)) return null;
player.ChatMessage(Msg("Restricted", player.UserIDString));
return true;
}
}
}The plugin reads a list of weapon shortnames from config and a permission that bypasses the restriction. When OnRackedWeaponUnload fires, it looks up the item's shortname in the config list; if the weapon is restricted and the player lacks the bypass permission, it sends a localized chat message and returns a non-null value so the rack refuses to release the item. Players with rackunloadguard.bypass unload as usual, and any weapon not on the list is unaffected. All checks are simple lookups so the hook adds negligible overhead.
Common use cases
Lock high-value weapons to racks
Prevent players from removing sniper rifles or other high-tier weapons from display racks unless they hold a permission, effectively turning the rack into a secure showcase.
Audit rack activity
Record which player pulled which weapon from which rack position for a staff log or admin command without touching the game's normal unload flow.
Quest or event gating
Block unloading while an event flag is active so weapons stay mounted on arena racks until the round ends, then clear the flag to allow normal removal.
Pitfalls
Returning a value blocks silently
The player sees the interaction do nothing. Always send a chat reply before returning non-null so the player understands why the weapon stayed on the rack.
Do not confuse with destroy or take hooks
OnRackedWeaponUnloadonly covers the unload path. If the rack is destroyed, the weapon may go different routes; useOnRackedWeaponTakeor entity kill handlers for those scenarios.Null-safety on all three parameters
Guard
slot,playerandweaponRackbefore reading members. A nullslotfrom the item container will otherwise throw when you callslot.info.shortname.
Build a plugin with OnRackedWeaponUnload
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 OnRackedWeaponUnload
Generate