Skip to content
RustPluginGenerator

OnLootPlayer

OnLootPlayer is called when a player opens another player's corpse loot panel, after the containers have been attached to the looter's loot state but before the loot panel is sent to the client.

Signature
void OnLootPlayer(BasePlayer player, BasePlayer player2)

Parameters

Hook parameters
ParameterTypeDescription
playerBasePlayerThe BasePlayer whose corpse inventory is being opened, i.e. the owner of the dying player entity that is being looted.
player2BasePlayerThe BasePlayer who is doing the looting; this is the player whose client receives the loot panel.

Return value

The return value is ignored at this injection site; the original code continues and the loot panel is always sent. To block or alter looting use the CanLootPlayer hook instead, which is checked before any container work.

How it works

Fires inside BasePlayer.RPC_LootPlayer on the corpse entity (the this in the injection), which is why the first argument is the dead player and the second is the looter. The game reaches this point only after CanInteract, CanBeLooted and StartLootingEntity have all succeeded and the main, wear and belt containers have been added to the looter's inventory.loot state. Use player2 to identify the looter (permissions, team checks, combat-blocked rules) and player for the corpse owner, which is useful for death/raid bookkeeping. Declaring the first parameter as BasePlayer is required by the existing signature; declaring a narrower type than BasePlayer would make Oxide skip the call for any other argument, so leave both as BasePlayer. Because the hook fires before SendImmediate and the player_corpse RPC, state changes made here (strip, flags, CUI) are visible to the client on the first frame the panel opens. It does not fire for boxes, dropped item containers or NPC corpses.

Example plugin: Block looting enemy corpses while combat-blocked

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

namespace Oxide.Plugins
{
    [Info("Combat Loot Block", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks looting of player corpses while the looter is in combat.")]
    public class CombatLootBlock : RustPlugin
    {
        private const string PermBypass = "combatlootblock.bypass";

        private class PluginConfig
        {
            [JsonProperty("Combat window (seconds)")]
            public float CombatWindow { get; set; } = 10f;

            [JsonProperty("Allow looting teammates")]
            public bool AllowTeammates { get; set; } = true;
        }

        private PluginConfig config;
        private readonly Dictionary<string, float> lastCombat = new Dictionary<string, float>();

        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>
            {
                ["Blocked"] = "You cannot loot a player corpse while in combat."
            }, 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 void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if (info == null || entity == null) return;
            var attacker = info.InitiatorPlayer;
            var victim = entity as BasePlayer;
            if (attacker == null || victim == null || attacker == victim) return;
            if (attacker.IsNpc || victim.IsNpc) return;
            lastCombat[attacker.UserIDString] = UnityEngine.Time.realtimeSinceStartup;
        }

        private void OnLootPlayer(BasePlayer player, BasePlayer looter)
        {
            if (player == null || looter == null || looter.IsNpc) return;
            if (permission.UserHasPermission(looter.UserIDString, PermBypass)) return;

            float last;
            if (!lastCombat.TryGetValue(looter.UserIDString, out last)) return;
            if (UnityEngine.Time.realtimeSinceStartup - last > config.CombatWindow) return;

            if (config.AllowTeammates && player.currentTeam != 0 && player.currentTeam == looter.currentTeam) return;

            looter.inventory.loot.Clear();
            looter.inventory.loot.SendImmediate();
            looter.ChatMessage(Msg("Blocked", looter.UserIDString));
        }

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

The plugin records when each player last damaged another player in OnEntityTakeDamage and stores it in a dictionary keyed by the looter's UserIDString. When OnLootPlayer fires it looks up the looter's last damage timestamp and, if it is within the configured window and the corpse is not a teammate, it closes the loot panel and sends a language message. Because the containers are attached before the hook runs, the plugin empties the player's loot state so nothing can be taken, then destroys any open UI and returns. Permission combatlootblock.bypass exempts admins and staff, and the config controls the combat window length.

Common use cases

  • Anti-raid looting cooldowns

    Prevent players who just took damage from looting player corpses for a few seconds, cutting down on combat logging and body-sniping.

  • Corpse access permissions

    Restrict corpse looting to teammates or permission holders while leaving regular boxes and NPC corpses untouched.

  • Loot logging and telemetry

    Record who looted which corpse and when, using the two BasePlayer arguments to build a persistent log for admin review.

Pitfalls

  • Wrong argument order

    The first parameter is the corpse's owner, not the looter. Swapping them leads to permission checks running against a dead player.

  • Does not stop the panel

    The return value at this injection is ignored, so the loot UI still opens. Clear player2.inventory.loot containers and call SendImmediate yourself if you need to close it.

  • Narrow parameter types

    Changing player or player2 to a subclass makes Oxide skip the hook call, so the plugin silently stops working. Keep both as BasePlayer.

Build a plugin with OnLootPlayer

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

Prompt: Anti-raid looting cooldowns using the OnLootPlayer 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 OnLootPlayer

Generate