Skip to content
RustPluginGenerator

OnWaterPurified

OnWaterPurified is called after a WaterPurifier converts a batch of salt water into purified water during its ConvertWater pass. It fires right after the purified water output is written and before the entity sends its network update.

Signature
void OnWaterPurified(WaterPurifier waterPurifier, float timeCooked)

Parameters

Hook parameters
ParameterTypeDescription
waterPurifierWaterPurifierThe WaterPurifier entity that just finished converting one cycle of water. Use it to read the purified water storage inventory, the player owner, or its position.
timeCookedfloatThe accumulated cook time in seconds the purifier has processed for this cycle. It is the value the game uses to decide the conversion result.

Return value

The return value is ignored. The original ConvertWater method is void and the hook is injected with a continue behavior, so returning null, a value, or nothing has no effect on the game's conversion logic.

How it works

Oxide fires this hook at the end of WaterPurifier.ConvertWater, once the game has topped up the purifier's purified water storage and marked its inventory dirty. By that point the conversion has already happened, so the hook is a post-processing notification rather than a gate. waterPurifier is the entity responsible, which lets you inspect its inventory, OwnerID, transform.position or building privilege to react in context. timeCooked is the accumulated time value passed to the conversion and is useful for scaling rewards or logging how long a cycle ran.

Because the injection is continue with a void original method, the return value is ignored and you cannot cancel the conversion from here. Declaring the first parameter as a more specific type such as BaseOven will not help; leave it as WaterPurifier so the dispatch matches every call. The hook fires once per conversion cycle, so keep the body cheap: no Puts and no allocation-heavy work. Read the output container with inventory.itemList if you want to know how much water the purifier now holds.

Example plugin: Reward players with scrap for purified water

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

namespace Oxide.Plugins
{
    [Info("Purifier Reward", "RustPluginGenerator", "1.0.0")]
    [Description("Gives players scrap each time their water purifier converts water.")]
    public class PurifierReward : RustPlugin
    {
        private const string PermUse = "purifierreward.use";

        private PluginConfig config;
        private Dictionary<ulong, double> lastReward = new Dictionary<ulong, double>();

        private class PluginConfig
        {
            [JsonProperty("Scrap reward")]
            public int ScrapReward = 2;

            [JsonProperty("Cooldown in seconds")]
            public double CooldownSeconds = 300.0;

            [JsonProperty("Permission required")]
            public bool RequirePermission = true;
        }

        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>
            {
                ["Rewarded"] = "Your water purifier produced purified water. You received {0} scrap.",
                ["NoPerm"] = "You do not have permission for purifier rewards."
            }, 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);
            lastReward = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, double>>(Name) ?? new Dictionary<ulong, double>();
        }

        private void Unload()
        {
            Interface.Oxide.DataFileSystem.WriteObject(Name, lastReward);
        }

        private void OnWaterPurified(WaterPurifier waterPurifier, float timeCooked)
        {
            if (waterPurifier == null || waterPurifier.OwnerID == 0) return;

            var player = BasePlayer.FindByID(waterPurifier.OwnerID);
            if (player == null || !player.IsConnected) return;

            if (config.RequirePermission && !permission.UserHasPermission(player.UserIDString, PermUse))
            {
                player.ChatMessage(Msg("NoPerm", player.UserIDString));
                return;
            }

            double now = UnityEngine.Time.realtimeSinceStartup;
            double last;
            if (lastReward.TryGetValue(player.userID, out last) && now - last < config.CooldownSeconds) return;

            lastReward[player.userID] = now;

            var scrap = ItemManager.CreateByName("scrap", config.ScrapReward);
            if (scrap != null) player.GiveItem(scrap);

            player.ChatMessage(Msg("Rewarded", player.UserIDString, config.ScrapReward));
        }
    }
}

The plugin listens for OnWaterPurified and looks up the owner of the purifier via OwnerID. If the owner is an online player, it grants the configured scrap reward, capped by a per-player cooldown stored in data, and sends a localized chat message. Conversion is already done by the time the hook fires, so the plugin only reads the output and never touches the purifier's inventory. Config holds the scrap amount, item shortname and cooldown length. A LoadDefaultMessages block provides the reward text, and Unload writes the cooldown data back to oxide/data.

Common use cases

  • Grant resources for purifier output

    Award scrap, low grade fuel or a custom currency to the purifier owner each time a conversion completes, using OwnerID to resolve the player.

  • Log base activity

    Record the purifier position and owner to a data file so admins can see which bases are actively processing water during a wipe.

  • Track purifier efficiency

    Compare the purified water count in the storage against timeCooked to flag players using unusually fast conversions or macros.

Pitfalls

  • You cannot cancel the conversion

    The hook fires after the water has already been written to the storage, and the injection is continue, so returning a value does nothing. Use OnWaterPurify if you need to block the conversion.

  • Fires where no player is online

    OwnerID may point to a sleeping or offline player, and NPC or admin-spawned purifiers may have OwnerID zero. Always null-check BasePlayer.FindByID before rewarding.

  • Repeated calls per pass

    Each ConvertWater cycle triggers the hook. With many purifiers on the server the callback runs often, so avoid PrintWarning, disk writes or large loops inside it.

Build a plugin with OnWaterPurified

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

Prompt: Grant resources for purifier output using the OnWaterPurified 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 OnWaterPurified

Generate