Skip to content
RustPluginGenerator

OnRackedWeaponLoad

OnRackedWeaponLoad is called inside WeaponRack.LoadWeaponAmmo before the game instantiates a rack'd weapon and selects its ammo, letting a plugin cancel that single load pass.

Signature
object OnRackedWeaponLoad(Item slot, ItemDefinition itemDefinition, BasePlayer player, WeaponRack weaponRack)

Parameters

Hook parameters
ParameterTypeDescription
slotItemThe Item occupying the weapon rack slot that the game is about to fill. Its info.shortname is the weapon prefab shortname and its amount is used for the ammo count.
itemDefinitionItemDefinitionThe ItemDefinition resolved from the slot's item for this load pass. Special handling of the snowball gun and ammo type selection happens after the hook.
playerBasePlayerThe BasePlayer interacting with the rack, usually whoever opened or refreshed it. Can be null in some internal calls, so always check it.
weaponRackWeaponRackThe WeaponRack entity performing the load. Use it to read mounted items, position, owner or display flags before the weapon is instantiated.

Return value

Returning null lets LoadWeaponAmmo continue and the weapon is mounted with ammo as usual. Returning any non-null object makes the hook call register as a value and the method returns immediately, so that slot's weapon never gets instantiated for this pass.

How it works

The hook fires from WeaponRack.LoadWeaponAmmo, the internal routine that turns a stored rack slot item into a live mounted weapon with ammo. It runs after the game resolved the item definition and before the snowball-gun special case and the ammo selection logic. Because it fires per load pass, it can run multiple times when a rack refreshes several slots.

slot is the item being loaded, itemDefinition is the resolved definition (null checks matter because the game bails before the hook only when the definition is missing), player is the interacting player and may be null, and weaponRack is the entity itself. Declaring BasePlayer instead of a broader type is the natural fit here; passing a more specific type would simply narrow dispatch, and there is no benefit unless you want to skip NPC-driven calls.

Cancelling is the only meaningful use: the original method returns void, so returning anything non-null makes it return early. Returning null lets the rack finish loading the weapon normally.

Example plugin: Block loading of weapons with no permission

RackedWeaponLoadGate.cs
using System.Linq;
using UnityEngine;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins
{
    [Info("RackedWeaponLoadGate", "RustPluginGenerator", "1.0.0")]
    [Description("Restricts which weapons can be loaded into weapon racks based on permission and a whitelist.")]
    public class RackedWeaponLoadGate : RustPlugin
    {
        private const string PermUse = "rackedweaponloadgate.use";

        private PluginConfig config;
        private readonly Dictionary<ulong, float> lastNotice = new Dictionary<ulong, float>();

        private class PluginConfig
        {
            [JsonProperty("Require permission for every weapon")]
            public bool RequirePermission = true;

            [JsonProperty("Allowed shortnames (empty = allow all)")]
            public List<string> AllowedShortnames = new List<string>();
        }

        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>
            {
                ["NoPermission"] = "You are not allowed to load weapons into racks.",
                ["NotAllowed"] = "That weapon cannot be loaded into a 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(PermUse, this);
        }

        private object OnRackedWeaponLoad(Item slot, ItemDefinition itemDefinition, BasePlayer player, WeaponRack weaponRack)
        {
            if (slot?.info == null || itemDefinition == null || weaponRack == null) return null;

            if (config.RequirePermission && player != null && !permission.UserHasPermission(player.UserIDString, PermUse))
            {
                Notice(player, Msg("NoPermission", player.UserIDString));
                return false;
            }

            if (config.AllowedShortnames.Count > 0 && !config.AllowedShortnames.Contains(itemDefinition.shortname))
            {
                if (player != null) Notice(player, Msg("NotAllowed", player.UserIDString));
                return false;
            }

            return null;
        }

        private void Notice(BasePlayer player, string message)
        {
            float now = UnityEngine.Time.realtimeSinceStartup;
            float last;
            if (lastNotice.TryGetValue(player.userID, out last) && now - last < 3f) return;
            lastNotice[player.userID] = now;
            player.ChatMessage(message);
        }

        private void Unload()
        {
            lastNotice.Clear();
        }
    }
}

The plugin registers a rackedweaponloadgate.use permission and, optionally, an allowed-shortname whitelist in the config. When OnRackedWeaponLoad fires, it checks the player, verifies permission and inspects the item shortname against the whitelist when one is configured. Every rejection sends a throttled chat message through the language file and returns a non-null placeholder, which stops LoadWeaponAmmo before the weapon is created. Allowed loads return null so the rack behaves normally. The same result applies to any further slots the rack tries to load, so a denied player cannot sidestep it by reloading the UI.

Common use cases

  • Permission-gated weapon racks

    Restrict which weapons a base can rack behind a permission or group check, useful on servers that sell specialized racks.

  • Per-rack weapon policy

    Inspect weaponRack to apply rules by position, owner or a stored marker, for example blocking explosives on decorative racks.

  • Anti-exploit filtering

    Refuse loads of shortnames that map to removed or bugged items so a malicious client cannot spawn an invalid mounted weapon.

Pitfalls

  • The player can be null

    Some internal load passes do not carry a player. Check player == null and fall back to server-side rules rather than throwing.

  • Fires repeatedly

    A rack can load several slots in quick succession. Keep the handler cheap and throttle any chat feedback so players are not spammed.

  • Return value has no payload

    The method returns void, so the object you return is only a signal. Returning a string or other object always cancels the load.

Build a plugin with OnRackedWeaponLoad

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Permission-gated weapon racks using the OnRackedWeaponLoad hook, with a config file and a permission
Generate this plugin

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 OnRackedWeaponLoad

Generate