Skip to content
RustPluginGenerator

OnEntityDistanceCheck

OnEntityDistanceCheck is called from BaseEntity's MaxDistance RPC handler when a client asks the server whether an entity is within a given range. Returning a bool replaces the server's own distance comparison.

Signature
object OnEntityDistanceCheck(BaseEntity entity, BasePlayer player, uint id, string debugName, float maximumDistance, bool checkParent)

Parameters

Hook parameters
ParameterTypeDescription
entityBaseEntityThe entity the client asked about, usually a container or deployable being viewed through a client-side distance RPC. Can be null in theory; check it before use.
playerBasePlayerThe BasePlayer whose client sent the MaxDistance RPC. This is the player the distance is measured from.
iduintThe network id value sent with the RPC, identifying the targeted entity or message. Usually matches entity.net.ID.Value but treat it as advisory.
debugNamestringA short string label supplied by the caller, used for diagnostics. Do not rely on it having a fixed set of values.
maximumDistancefloatThe distance limit the game was about to validate against, in metres. Return your own comparison result to override it.
checkParentboolWhether the game's check also considers the entity's parent (e.g. an item inside a container). The vanilla path ignores it for the direct distance test.

Return value

Return a bool to replace the game's distance check entirely: true means the entity counts as in range, false means it does not. Return null (or any non-bool value) to let the normal entity.Distance(player.eyes.position) <= maximumDistance comparison run.

How it works

The hook fires inside the MaxDistance.Test RPC path on BaseEntity, after entity and player have been null-checked. Clients use this RPC when they need the server to confirm that an entity is close enough for an interaction, so it can be triggered by players looking at or interacting with deployables, containers and similar entities. entity is the object being tested and player is the requesting client, which is what you want for per-player rules. maximumDistance is the limit the game would have used, and debugName plus id help identify the call. The vanilla result is a simple entity.Distance(player.eyes.position) <= maximumDistance comparison; checkParent is passed through but not used by the default path. Declaring a more specific type for entity (for example StorageContainer) narrows the dispatch to only those calls, because Oxide only invokes a hook method when every argument matches the declared parameter type. The hook fires per RPC, so keep it cheap and never print from it.

Example plugin: Give VIPs extra interaction range on containers

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

namespace Oxide.Plugins
{
    [Info("ExtendedContainerRange", "RustPluginGenerator", "1.0.0")]
    [Description("Gives permitted players a longer interaction range on storage containers.")]
    public class ExtendedContainerRange : RustPlugin
    {
        private const string PermUse = "extendedcontainerrange.use";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Extended distance in metres")]
            public float ExtendedDistance = 12f;
        }

        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 System.Collections.Generic.Dictionary<string, string>
            {
                ["Range"] = "Your container interaction range is {0} metres.",
                ["NoAccess"] = "You do not have access to extended container range."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args)
        {
            return string.Format(lang.GetMessage(key, this, userId), args);
        }

        private void Init()
        {
            permission.RegisterPermission(PermUse, this);
        }

        [ChatCommand("extrange")]
        private void CmdRange(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;
            if (!permission.UserHasPermission(player.UserIDString, PermUse))
            {
                SendReply(player, Msg("NoAccess", player.UserIDString));
                return;
            }
            SendReply(player, Msg("Range", player.UserIDString, config.ExtendedDistance));
        }

        private object OnEntityDistanceCheck(StorageContainer container, BasePlayer player, uint id, string debugName, float maximumDistance, bool checkParent)
        {
            if (container == null || player == null || player.eyes == null) return null;
            if (!permission.UserHasPermission(player.UserIDString, PermUse)) return null;

            float distance = Vector3.Distance(container.transform.position, player.eyes.position);
            if (distance <= maximumDistance) return null;
            return distance <= config.ExtendedDistance;
        }
    }
}

The plugin listens for OnEntityDistanceCheck and only acts on StorageContainer entities, using Oxide's parameter typing to skip every other entity. When the player holds the configured permission, the hook returns true if the real distance is inside an extended limit (default 12 m) and falls back to the vanilla comparison otherwise, so normal range still applies past that. Players without the permission get null, which leaves the stock behaviour untouched. The permission and the extended radius live in a config file, and a /extrange chat command lets permitted players see the current value.

Common use cases

  • VIP interaction range

    Grant donators a slightly longer reach on containers and deployables without editing global server settings. Return null for everyone else so vanilla limits apply.

  • Base-wide access

    Allow building-authed players to open containers from anywhere inside their own base by comparing positions with GetBuildingPrivilege instead of plain distance.

  • Anti-cheat tightening

    Return false when the reported call comes from a player further away than physically plausible, effectively clamping the server-side confirmation.

Pitfalls

  • Fires per RPC

    This runs whenever a client sends the MaxDistance RPC, so avoid allocations, permission lookups on every call if you can cache them, and never log inside the hook.

  • Returning true is absolute

    A true return skips the vanilla comparison entirely. If you only want to extend range, still compute a distance check yourself rather than blindly returning true.

  • Not every entity uses it

    Only RPCs routed through MaxDistance.Test hit this hook. Do not assume it fires for every interaction; some systems use their own range logic.

Build a plugin with OnEntityDistanceCheck

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

Prompt: VIP interaction range using the OnEntityDistanceCheck 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 OnEntityDistanceCheck

Generate