OnWaterPurify
OnWaterPurify is called from WaterPurifier.ConvertWater before the purifier converts stored water into purified water. Returning a non-null value cancels that conversion pass.
object OnWaterPurify(WaterPurifier waterPurifier, float timeCooked)Parameters
| Parameter | Type | Description |
|---|---|---|
waterPurifier | WaterPurifier | The WaterPurifier entity that is about to convert water. Use it to read its storage containers, owner (OwnerID), position and other entity state. |
timeCooked | float | Seconds of processing accumulated for this conversion pass. The game multiplies it by waterToProcessPerMinute / 60 to decide how much water to convert. |
Return value
Returning null lets the purifier continue and convert water normally. Any non-null return value — including a plain true — causes ConvertWater to return immediately, so no water is converted during that pass; the return value itself is not used as a number.
How it works
The hook fires inside WaterPurifier.ConvertWater, which the purifier's server update loop calls periodically while it has work to do. The call happens after the output-full check, so it runs only when the purifier is actually ready to process water. waterPurifier is the entity instance, so you can inspect inventory (the input water and output purified water containers), OwnerID, net.ID and position. timeCooked is the elapsed processing time for this pass and can be used to scale output or to throttle built-in conversions. Because the hook fires frequently and repeatedly per purifier, keep the callback cheap and never log inside it. Oxide only calls your method if each argument matches the declared parameter type; keep WaterPurifier exact unless you intentionally want to skip other entity types. The output-full guard runs before the hook, so you cannot rely on the hook firing when the purified water slot is already maxed. Water purifiers are commonly placed in bases, so count them per owner if you apply limits, and remember that sleeping bases still tick.
Example plugin: Block water purifiers on unauthed bases and count usage
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Purifier Water Guard", "RustPluginGenerator", "1.0.0")]
[Description("Limits water purifiers per owner and blocks conversion when the cap is exceeded.")]
public class PurifierWaterGuard : RustPlugin
{
private class PluginConfig
{
[JsonProperty("Max purifiers per player (0 = unlimited)")]
public int MaxPerPlayer = 3;
[JsonProperty("Debug logging")]
public bool Debug = false;
}
private PluginConfig config;
private readonly Dictionary<ulong, int> counts = new Dictionary<ulong, int>();
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);
private void OnEntitySpawned(BaseNetworkable entity)
{
var purifier = entity as WaterPurifier;
if (purifier == null || purifier.OwnerID == 0) return;
counts.TryGetValue(purifier.OwnerID, out int current);
counts[purifier.OwnerID] = current + 1;
}
private void OnEntityKill(BaseNetworkable entity)
{
var purifier = entity as WaterPurifier;
if (purifier == null || purifier.OwnerID == 0) return;
if (counts.TryGetValue(purifier.OwnerID, out int current))
{
if (current <= 1) counts.Remove(purifier.OwnerID);
else counts[purifier.OwnerID] = current - 1;
}
}
private object OnWaterPurify(WaterPurifier waterPurifier, float timeCooked)
{
if (waterPurifier == null) return null;
ulong owner = waterPurifier.OwnerID;
int limit = config.MaxPerPlayer;
if (limit <= 0 || owner == 0) return null;
counts.TryGetValue(owner, out int owned);
if (owned <= limit) return null;
if (config.Debug && timeCooked > 0f)
{
Puts($"Blocked purify for owner {owner} ({owned}/{limit})");
}
return true;
}
}
}The plugin adds a per-player cap and an optional total block. In OnWaterPurify it looks up the purifier's owner via OwnerID, checks how many purifiers that owner has registered, and compares against the configured limit. It also returns a non-null value for owners who are over the cap, which halts the conversion so the input water is never consumed. Registration happens in OnEntitySpawned when a WaterPurifier spawns, with cleanup on OnEntityKill. Every conversion pass also increments a counter that a timer prints only when debug is enabled, keeping logging out of the hot path. Operators tune limits in the config without recompiling.
Common use cases
Cap purifiers per player
Count water purifiers by OwnerID and return a non-null value once a player exceeds a configured limit, so extra purifiers sit idle without consuming water.
Disable purifying on specific bases
Check whether the purifier sits inside a building privilege that lacks a required authorization and block conversion for unauthorized owners.
Log or meter production
Record output passes per owner for statistics, then let conversion continue by returning null.
Pitfalls
The hook fires very often
ConvertWater runs on the purifier's update loop, so avoid chat messages, PrintWarning or heavy LINQ inside OnWaterPurify. Do lookups once and cache results.
Output-full check runs first
When stopWhenOutputFull is set and the purified water slot is already full, the method returns before calling the hook. Handle full-output behavior elsewhere.
Return type matters
Any non-null return block conversion, not just
true. Returning a numeric value does not scale output; it simply cancels the pass.
Build a plugin with OnWaterPurify
Describe what should happen and get a compiled plugin that uses this hook.
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 OnWaterPurify
Generate