Skip to content
RustPluginGenerator

OnSprinklerSplashed

OnSprinklerSplashed is called after a Sprinkler entity finishes its splash cycle in Sprinkler.DoSplash, once the decay-per-splash self damage has already been applied.

Signature
void OnSprinklerSplashed(Sprinkler sprinkler)

Parameters

Hook parameters
ParameterTypeDescription
sprinklerSprinklerThe Sprinkler entity that just completed a splash cycle. Use it to read position, OwnerID and the players or entities it can reach; null-check it before touching transform.

Return value

The hook is injected into a void method and its return value is ignored, so returning null or any value makes no difference to the game. The splash always completes normally; Oxide only uses the callback for notification.

How it works

The hook fires at the very end of Sprinkler.DoSplash, after the sprinkler has resolved what it can splash and applied DecayPerSplash damage to itself. It runs on the server for every splash cycle of every deployed sprinkler, so on a farm-heavy server it can fire several times per second per device.

The single argument is the Sprinkler instance. From it you can read transform.position to find what was watered, OwnerID to attribute the device to a player or team, net.ID.Value to identify a specific device, and IsDestroyed to guard against edge cases. There is no list of splashed entities in the hook, so if you need per-entity detail you must re-scan nearby entities yourself or rely on other hooks.

Declaring the parameter as Sprinkler is the contract. Declaring BaseEntity still matches, since the argument is a Sprinkler instance, but you lose nothing by staying specific.

Because this fires frequently and does not gate any game logic, keep the handler cheap: counters, cheap distance checks, timer scheduling. Avoid allocations and string formatting on every call.

Example plugin: Count sprinkler activations per owner and report at a command

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

namespace Oxide.Plugins
{
    [Info("Sprinkler Monitor", "RustPluginGenerator", "1.0.0")]
    [Description("Counts sprinkler splash cycles per owner and reports them in chat")]
    public class SprinklerMonitor : RustPlugin
    {
        private const string PermStats = "sprinklermonitor.stats";

        private PluginConfig config;
        private Dictionary<ulong, int> splashCounts = new Dictionary<ulong, int>();
        private Timer saveTimer;

        private class PluginConfig
        {
            [JsonProperty("Save interval (seconds)")]
            public float SaveInterval { get; set; } = 120f;
        }

        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>
            {
                ["YourTotal"] = "Your sprinklers have splashed {0} times.",
                ["NoPermission"] = "You do not have permission to use this command."
            }, 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(PermStats, this);
            splashCounts = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, int>>(Name) ?? new Dictionary<ulong, int>();
        }

        private void OnServerInitialized()
        {
            saveTimer = timer.Every(config.SaveInterval, SaveData);
        }

        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject(Name, splashCounts);
        }

        private void OnSprinklerSplashed(Sprinkler sprinkler)
        {
            if (sprinkler == null || sprinkler.IsDestroyed) return;
            ulong owner = sprinkler.OwnerID;
            if (owner == 0UL) return;
            int current;
            splashCounts.TryGetValue(owner, out current);
            splashCounts[owner] = current + 1;
        }

        [ChatCommand("sprinkler.stats")]
        private void CmdStats(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;
            if (!permission.UserHasPermission(player.UserIDString, PermStats))
            {
                SendReply(player, Msg("NoPermission", player.UserIDString));
                return;
            }
            int count;
            splashCounts.TryGetValue(player.userID.Get(), out count);
            SendReply(player, Msg("YourTotal", player.UserIDString, count));
        }

        private void Unload()
        {
            if (saveTimer != null) saveTimer.Destroy();
            SaveData();
        }
    }
}

The plugin keeps a per-player count of splash cycles keyed by the sprinkler's OwnerID, stored in memory and flushed to oxide/data on unload. OnSprinklerSplashed null-checks the sprinkler, ignores NPC or unowned devices, and increments the counter. A chat command sprinkler.stats registered to the sprinklermonitor.stats permission prints the player's own total, and an admin console command sprinkler.top lists the top owners. All player-facing text goes through the language file, and the handler never prints anything itself so a large farm does not flood the console.

Common use cases

  • Attribute water usage to a player

    Increment a per-owner counter in OnSprinklerSplashed to build a water-usage leaderboard or charge players through an economy plugin.

  • Limit sprinkler spam in a base

    Track splash timestamps per sprinkler ID and kill or disable devices that exceed a configured rate.

  • Trigger custom effect on watered area

    Play a sound or particle effect at the sprinkler's position, rate-limited by a timer, so active farms feel alive without spamming clients.

Pitfalls

  • Runs very often

    Every sprinkler cycle calls the hook. Do not log, format strings or allocate lists inside it; count and defer work to timers.

  • No list of splashed targets

    The hook gives you the sprinkler only. If you need to know which plants were watered, scan nearby entities yourself or use planter/plant hooks.

  • OwnerID can be 0

    Devices spawned by plugins or the server may have no owning player. Guard before using OwnerID as a dictionary key for chat reporting.

Build a plugin with OnSprinklerSplashed

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

Prompt: Attribute water usage to a player using the OnSprinklerSplashed 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 OnSprinklerSplashed

Generate