Skip to content
RustPluginGenerator

OnPlayerDrink

OnPlayerDrink is called when a player attempts to drink from a liquid container via the SVDrink RPC. Returning a non-null value cancels the drink before any liquid is consumed.

Signature
object OnPlayerDrink(BasePlayer player, LiquidContainer liquidContainer)

Parameters

Hook parameters
ParameterTypeDescription
playerBasePlayerThe BasePlayer who is trying to drink from the liquid container, supplied by the RPC message sender. Null-check it before use.
liquidContainerLiquidContainerThe LiquidContainer entity (a small water bottle, large water bottle, or another liquid-holding item) that the player is drinking from. Its inventory holds the liquid items.

Return value

Return null to let the drink proceed normally. Return any non-null value to stop the original code path, so the container's inventory is never iterated and no liquid is consumed. The method returns void, so the returned value is only used as a cancel signal.

How it works

The hook fires inside LiquidContainer.SVDrink, which runs on the server when a client sends the drink RPC for a bottle or similar item. The method first checks that the player can consume at all (metabolism.CanConsume()); if that fails, the hook is not evaluated and the action already stops. Otherwise Oxide calls OnPlayerDrink with the player and the container before the method iterates the container's inventory to consume liquid. This makes it the right place to gate drinking on your own rules.

The player argument is the drinker; use player.UserIDString for permission checks or data lookups, and null-check it since the RPC payload is client-driven. The liquidContainer argument is the entity being drunk from, so you can read liquidContainer.inventory to inspect which liquid items are present, or read its position and owner. You cannot narrow dispatch further by declaring a subtype because the injection always passes the base LiquidContainer; declaring BasePlayer for the first argument is the usual choice. Returning null leaves the drink undisturbed.

Example plugin: Block drinking while a player is in a safe zone buff

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

namespace Oxide.Plugins
{
    [Info("Drink Block Zone", "RustPluginGenerator", "1.0.0")]
    [Description("Blocks drinking from liquid containers inside a configured zone")]
    public class DrinkBlockZone : RustPlugin
    {
        private const string PermBypass = "drinkblockzone.bypass";

        private PluginConfig config;

        private class PluginConfig
        {
            [JsonProperty("Enable zone restriction")]
            public bool Enabled = true;

            [JsonProperty("Zone center X")]
            public float CenterX = 0f;

            [JsonProperty("Zone center Z")]
            public float CenterZ = 0f;

            [JsonProperty("Zone radius")]
            public float Radius = 20f;
        }

        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>
            {
                ["DrinkBlocked"] = "You cannot drink in this area."
            }, this);
        }

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

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

        private object OnPlayerDrink(BasePlayer player, LiquidContainer liquidContainer)
        {
            if (!config.Enabled || player == null || liquidContainer == null)
                return null;

            if (player.IsAdmin || permission.UserHasPermission(player.UserIDString, PermBypass))
                return null;

            Vector3 position = liquidContainer.transform.position;
            float dx = position.x - config.CenterX;
            float dz = position.z - config.CenterZ;
            if (dx * dx + dz * dz > config.Radius * config.Radius)
                return null;

            player.ChatMessage(Msg("DrinkBlocked", player.UserIDString));
            return false;
        }
    }
}

The plugin cancels drinking in areas you want to reserve for other mechanics. It reads the container's position and compares it to a configurable radius around a configured marker position, so only bottles used inside that zone are blocked. When a drink is refused, the player gets a localized chat message and the hook returns a non-null value to stop consumption. Rules are config-driven: you can toggle the feature and adjust the zone center and radius in oxide/config/DrinkBlockZone.json without recompiling. The container null-check guards against unexpected RPC payloads, and player-facing text goes through the language file.

Common use cases

  • Pause drinking during combat

    Cancel the drink when the player was hurt in the last few seconds, storing a timestamp per userID. The drink can then be retried once combat cooldown expires.

  • Restrict specific liquids

    Loop liquidContainer.inventory.itemList and block the action if the bottle contains a shortname you do not allow, such as a custom or event-only liquid.

  • Zone-based drinking rules

    Compare the container's position against raid zones or event arenas and cancel drinking there, sending a localized denial message to the player.

Pitfalls

  • Hook runs after CanConsume check only

    If metabolism.CanConsume() already returns false, OnPlayerDrink is never called. Do not rely on this hook to explain why a player cannot drink in general.

  • Any non-null return cancels

    Returning true, false, or any object all cancel the drink because the result is only tested against null. Read the returned value as a boolean cancel flag in your own code and always return null to allow.

  • Player RPC payload is client-driven

    The RPC comes from the client, so verify ownership and sanity before acting. Null-check player, liquidContainer, and its inventory on every call.

Build a plugin with OnPlayerDrink

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

Prompt: Pause drinking during combat using the OnPlayerDrink 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 OnPlayerDrink

Generate